From 27dec3a72c3436997253358c56fa46b1a08ff066 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 22 Feb 2025 00:35:37 +0200 Subject: [PATCH] cleanup; big hexdump --- crates/vestal/src/bang.rs | 24 +++---- crates/vestal/src/load.rs | 51 ++++++++++++++ crates/vestal/src/main.rs | 141 +++++++++++++++----------------------- 3 files changed, 118 insertions(+), 98 deletions(-) diff --git a/crates/vestal/src/bang.rs b/crates/vestal/src/bang.rs index 4888cbb..cd16861 100644 --- a/crates/vestal/src/bang.rs +++ b/crates/vestal/src/bang.rs @@ -14,15 +14,15 @@ pub fn slice_shebang (buffer: &[u8]) -> (Arc<[u8]>, Arc<[u8]>) { } } -impl Vestal { - pub fn load_bang_data (&mut self, path: &Arc) -> Usually> { - let (bang, data) = crate::bang::slice_shebang(read(path.as_path())?.as_slice()); - self.path_to_bang.insert(path.clone(), bang.clone()); - if bang.len() > 0 { - println!(" (bang {path:?} {:x})", bang.len()) - } - self.path_to_data.insert(path.clone(), data.clone()); - println!(" (buffer {:p} 0x{:08x} {path:?})", data.as_ptr(), data.len()); - Ok(data) - } -} +//impl Vestal { + //pub fn load_bang_data (&mut self, path: &Arc) -> Usually> { + //let (bang, data) = crate::bang::slice_shebang(read(path.as_path())?.as_slice()); + //self.path_to_bang.insert(path.clone(), bang.clone()); + //if bang.len() > 0 { + //println!(" (bang {path:?} {:x})", bang.len()) + //} + //self.path_to_data.insert(path.clone(), data.clone()); + //println!(" (buffer {:p} 0x{:08x} {path:?})", data.as_ptr(), data.len()); + //Ok(data) + //} +//} diff --git a/crates/vestal/src/load.rs b/crates/vestal/src/load.rs index a133c93..64e23f9 100644 --- a/crates/vestal/src/load.rs +++ b/crates/vestal/src/load.rs @@ -1,5 +1,56 @@ use crate::*; +/////////////////////////////////////////////////////////////////////////////////////////////////// + +#[derive(Default, Debug)] +struct Vestal { + search_paths: Vec, + paths_visited: BTreeSet>, + path_to_bang: BTreeMap, Arc<[u8]>>, + path_to_data: BTreeMap, Arc<[u8]>>, + path_to_pe: BTreeMap, Arc>, + path_to_rpe: BTreeMap, Arc>, + addr_to_import: BTreeMap, + //path_to_exports: BTreeMap, Vec>, + //path_to_imports: BTreeMap, Vec>, +} +impl Vestal { + fn enter (&mut self, path: &PathBuf) -> Usually<()> { + let mut total = 0usize; + self.load(&path)?; + for (dll_path, dll) in self.path_to_pe.iter() { + self.show_dll(dll_path)?; + let dll_data = self.path_to_data.get(dll_path).unwrap(); + let len = dll_data.len(); + println!(" (bytes {len} 0x{len:x})"); + self.show_calls(dll_path, dll_path.as_ref() == path)?; + if dll_path.as_ref() == path { + println!("{:?}", dll_data.hex_dump()); + let text = dll.get_section_by_name(".text")?; + println!("\n{:#?}", text); + let start = text.pointer_to_raw_data.0 as usize; + let size = text.size_of_raw_data as usize; + let vsize = text.virtual_size as usize; + println!("\n{:?}", &dll_data[start..start+size].hex_dump()); + println!("\n{:?}", &dll_data[start..start+vsize].hex_dump()); + let elf = crate::link::create_elf(&dll_data[start..start+vsize]); + println!("\n{:?}", &elf.hex_dump()); + println!("\n{:?}", &elf.len()); + let mut options = std::fs::OpenOptions::new(); + options.write(true).create(true).mode(0o755); + let mut file = options.open("output")?; + file.write_all(&elf)?; + println!("\nDone."); + } + total += len; + //println!("{:?}", dll_data.hex_dump()); + } + //self.show_addr_to_import(); + println!("(bytes-total {total} (0x{total:x})"); + Ok(()) + } +} + impl Vestal { pub fn resolve (&self, name: &str) -> Usually> { for base in self.search_paths.iter() { diff --git a/crates/vestal/src/main.rs b/crates/vestal/src/main.rs index 23e83cf..d51567d 100644 --- a/crates/vestal/src/main.rs +++ b/crates/vestal/src/main.rs @@ -1,11 +1,54 @@ #![feature(slice_split_once)] mod util; -mod load; -mod show; +//mod load; +//mod show; mod link; mod bang; pub(crate) use self::util::*; +fn main () -> Usually<()> { + use clap::{arg, command, value_parser, ArgAction, Command}; + let matches = command!() + .arg(arg!([path] "Path to VST DLL").value_parser(value_parser!(PathBuf))) + .arg(arg!(-i --inspect "Show info, don't run").required(false)) + //.arg(arg!(-s --stub "Provide a stub import").required(false)) + .get_matches(); + let path = matches.get_one::("path") + .unwrap_or_else(||panic!("Pass a path to a VST DLL.")); + let mut rebuilder = Rebuilder::new(&[ + std::env::current_dir()?, + canonicalize(path.clone().parent().expect("invalid parent path"))?, + "/home/user/Lab/Cosmo/wineprefix/drive_c/windows/system32".into(), + ]); + println!(); + for path in rebuilder.paths.iter() { + println!("(search {path:?})") + } + let path = rebuilder.find(path.to_str().expect("path must be unicode"), false)? + .unwrap_or_else(||panic!("Could not find: {path:?}")); + let main = rebuilder.load(&path, true)?; + //let main = rebuilder.dlls.get(&name).unwrap(); + for (name, dll) in rebuilder.dlls.iter() { + println!("\n{name}"); + println!("{:?}", dll.code.hex_conf(HexConfig { + title: false, + width: 32, + group: 4, + chunk: 4, + display_offset: dll.code_start as usize, + ..HexConfig::default() + })); + } + //let mut decoder = iced_x86::Decoder::with_ip(64, &main.code, 0x1000, 0); + //while decoder.can_decode() { + //let instruction = decoder.decode(); + //if Dll::matches(&instruction) { + //println!("{instruction}"); + //} + //} + Ok(()) +} + #[derive(Debug, Default)] struct Rebuilder { /// Search paths @@ -28,6 +71,8 @@ struct Dll { pe: Arc, /// Bytes of `.text` section code: Arc<[u8]>, + /// Start of `.text` section + code_start: u32, /// Addresses of imported methods by library deps_by_library: BTreeMap, BTreeMap, u32>>, /// Imported methods by address @@ -61,10 +106,12 @@ impl Rebuilder { ..Default::default() } } - fn load (&mut self, path: &impl AsRef, recurse: bool) -> Usually<()> { + fn load (&mut self, path: &impl AsRef, recurse: bool) -> Usually> { let path: Arc = Arc::from(PathBuf::from(path.as_ref())); if self.visited.contains(&path) { - return Ok(()) + let name = path.file_name().expect("no file name"); + let name: Arc = name.to_str().map(Arc::from).expect("non-unicode filename"); + return Ok(name) } self.visited.insert(path.clone()); let dll = Arc::new(Dll::new(&Arc::new(PathBuf::from(path.as_ref())), false)?); @@ -78,7 +125,7 @@ impl Rebuilder { } } } - Ok(()) + Ok(dll.name.clone()) } fn find (&self, name: &str, verbose: bool) -> Usually> { for base in self.paths.iter() { @@ -130,7 +177,7 @@ impl Dll { Some(&deps_by_address), &mut calls_by_source, &mut calls_by_target, - false + true )?; Ok(Self { name: name.clone(), @@ -138,6 +185,7 @@ impl Dll { bang, pe, code: Arc::from(text), + code_start: start as u32, deps_by_library: deps_by_library.clone(), deps_by_address: deps_by_address.clone(), calls_by_source, @@ -221,7 +269,7 @@ impl Dll { let mut decoder = iced_x86::Decoder::with_ip(64, data, 0x1000, 0); let mut calls = 0; while decoder.can_decode() { - if let Some(call) = Self::call(name, pe, start, data, deps, &mut decoder, verbose)? { + if let Some(call) = Self::call(name, pe, start, data, deps, &mut decoder, false)? { calls += 1; calls_by_source.insert(call.source, call.clone()); if !calls_by_target.contains_key(&call.target) { @@ -344,82 +392,3 @@ impl Dll { None } } - -fn main () -> Usually<()> { - use clap::{arg, command, value_parser, ArgAction, Command}; - let matches = command!() - .arg(arg!([path] "Path to VST DLL").value_parser(value_parser!(PathBuf))) - .arg(arg!(-i --inspect "Show info, don't run").required(false)) - //.arg(arg!(-s --stub "Provide a stub import").required(false)) - .get_matches(); - if let Some(path) = matches.get_one::("path") { - let mut rebuilder = Rebuilder::new(&[ - std::env::current_dir()?, - canonicalize(path.clone().parent().expect("invalid parent path"))?, - "/home/user/Lab/Cosmo/wineprefix/drive_c/windows/system32".into(), - ]); - println!(); - for path in rebuilder.paths.iter() { - println!("(search {path:?})") - } - if let Some(path) = rebuilder.find(path.to_str().expect("path must be unicode"), false)? { - rebuilder.load(&path, true)?; - } else { - panic!("Could not find: {path:?}") - } - } else { - panic!("Pass a path to a VST DLL.") - } - Ok(()) -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#[derive(Default, Debug)] -struct Vestal { - search_paths: Vec, - paths_visited: BTreeSet>, - path_to_bang: BTreeMap, Arc<[u8]>>, - path_to_data: BTreeMap, Arc<[u8]>>, - path_to_pe: BTreeMap, Arc>, - path_to_rpe: BTreeMap, Arc>, - addr_to_import: BTreeMap, - //path_to_exports: BTreeMap, Vec>, - //path_to_imports: BTreeMap, Vec>, -} -impl Vestal { - fn enter (&mut self, path: &PathBuf) -> Usually<()> { - let mut total = 0usize; - self.load(&path)?; - for (dll_path, dll) in self.path_to_pe.iter() { - self.show_dll(dll_path)?; - let dll_data = self.path_to_data.get(dll_path).unwrap(); - let len = dll_data.len(); - println!(" (bytes {len} 0x{len:x})"); - self.show_calls(dll_path, dll_path.as_ref() == path)?; - if dll_path.as_ref() == path { - println!("{:?}", dll_data.hex_dump()); - let text = dll.get_section_by_name(".text")?; - println!("\n{:#?}", text); - let start = text.pointer_to_raw_data.0 as usize; - let size = text.size_of_raw_data as usize; - let vsize = text.virtual_size as usize; - println!("\n{:?}", &dll_data[start..start+size].hex_dump()); - println!("\n{:?}", &dll_data[start..start+vsize].hex_dump()); - let elf = crate::link::create_elf(&dll_data[start..start+vsize]); - println!("\n{:?}", &elf.hex_dump()); - println!("\n{:?}", &elf.len()); - let mut options = std::fs::OpenOptions::new(); - options.write(true).create(true).mode(0o755); - let mut file = options.open("output")?; - file.write_all(&elf)?; - println!("\nDone."); - } - total += len; - //println!("{:?}", dll_data.hex_dump()); - } - //self.show_addr_to_import(); - println!("(bytes-total {total} (0x{total:x})"); - Ok(()) - } -}