diff --git a/Cargo.lock b/Cargo.lock index 5479dd2..28df776 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,15 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anstream" version = "0.6.18" @@ -143,6 +152,15 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hexy" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06fe36e4a24d8f2efdf7c336b7e13cec34ce338d9e191a2bc712f1d67ab21cbb" +dependencies = [ + "ansi_term", +] + [[package]] name = "indexmap" version = "2.7.1" @@ -253,6 +271,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +[[package]] +name = "pretty-hex" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc83ee4a840062f368f9096d80077a9841ec117e17e7f700df81958f1451254" + [[package]] name = "proc-macro2" version = "1.0.93" @@ -379,7 +403,9 @@ name = "vestal" version = "0.1.0" dependencies = [ "clap", + "hexy", "object", + "pretty-hex", "syscalls", ] @@ -390,6 +416,28 @@ dependencies = [ "tek_jack", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.59.0" diff --git a/crates/vestal/Cargo.toml b/crates/vestal/Cargo.toml index 0dd85a5..9129d0f 100644 --- a/crates/vestal/Cargo.toml +++ b/crates/vestal/Cargo.toml @@ -7,6 +7,8 @@ edition = "2021" clap = { version = "4.5.4", features = [ "cargo" ] } syscalls = "0.6.18" object = { version = "0.36.7", features = [ "read_core", "write_core", "elf", "pe" ] } +hexy = "0.1.4" +pretty-hex = "0.4.1" #exe = "0.5.6" #elf = "0.7.4" #goblin = "0.9.3" diff --git a/crates/vestal/src/main.rs b/crates/vestal/src/main.rs index 8e53d48..d4aeff0 100644 --- a/crates/vestal/src/main.rs +++ b/crates/vestal/src/main.rs @@ -3,20 +3,7 @@ mod util; pub(crate) use self::util::*; //mod dll; //mod exec; -pub(crate) use std::pin::Pin; -pub(crate) use std::sync::Arc; -pub(crate) use std::error::Error; -pub(crate) use std::path::{Path, PathBuf}; -pub(crate) use std::collections::{HashMap, HashSet}; -pub(crate) use std::fs::{read, canonicalize}; -//pub(crate) use ::lancelot::loader::pe::{PE, reloc::apply_relocations}; -//pub(crate) use ::goblin::{error, Object, pe::{import::Import, export::Export}}; -pub(crate) use ::object::endian::LittleEndian; -pub(crate) use ::object::pe::ImageNtHeaders64; -pub(crate) use ::object::read::pe::PeFile; -pub(crate) use ::object::write::elf::Writer as ElfWriter; use clap::{arg, command, value_parser, ArgAction, Command}; -type Usually = Result>; fn main () -> Usually<()> { let matches = command!() .arg(arg!([path] "Path to VST DLL").value_parser(value_parser!(PathBuf))) @@ -30,6 +17,7 @@ fn main () -> Usually<()> { if let Some(path) = vestal.resolve(path.to_str().expect("path must be unicode"))? { vestal.load(&path)?; vestal.inspect(); + vestal.run_main(&path)?; } else { panic!("Could not find: {path:?}") } @@ -48,7 +36,28 @@ struct Vestal { path_to_imports: HashMap, Vec>, } #[derive(Debug)] -struct Export {} +struct Export { + id: u32, + name: Option>, + target: Target, +} +impl Export { + fn name_string (&self) -> Option { + String::from_utf8(self.name.as_ref()?.to_vec()).ok() + } + fn addr (&self) -> u32 { + if let Target::Addr(addr) = self.target { + addr + } else { + panic!("no addr") + } + } +} +#[derive(Debug)] +enum Target { + Addr(u32), + Name(Arc<[u8]>, Arc<[u8]>), +} #[derive(Debug)] struct Import {} impl Vestal { @@ -73,14 +82,19 @@ impl Vestal { let dll: PeFile<'_, ImageNtHeaders64, &[u8]> = PeFile::parse(data.as_slice())?; if let Some(exports) = dll.export_table()? { let mut collected = vec![]; - for export in exports.exports()?.iter() { - collected.push(Export {}); - if let Some(name) = export.name { - let name = String::from_utf8(name.to_vec())?; - //println!(" (export {} {:?} {:?})", &export.ordinal, &name, &export.target); - } else { - //println!(" (export {} {:?})", &export.ordinal, &export.target) - } + for export_ref in exports.exports()?.iter() { + collected.push(Export { + id: export_ref.ordinal, + name: export_ref.name.map(|name|name.into()), + target: match export_ref.target { + ExportTarget::Address(addr) => + Target::Addr(addr), + ExportTarget::ForwardByName(dll, name) => + Target::Name(dll.into(), name.into()), + _ => + todo!("unsupported export target {:?}", &export_ref.target) + } + }); } self.path_to_exports.insert(path.clone(), collected); } @@ -130,4 +144,25 @@ impl Vestal { //println!(")"); } } + fn run_main (&self, path: &PathBuf) -> Usually<()> { + let data = self.path_to_data.get(path); + let len = data.as_ref().unwrap().len(); + let data = data.as_ref().unwrap(); + println!(); + println!("{:?}", data[0..512].hex_dump()); + println!(); + let exports = self.path_to_exports.get(path).expect("no exports"); + for export in exports.iter() { + if export.name_string() == Some("VSTPluginMain".to_string()) { + println!("{export:?}"); + println!("{}", export.name_string().unwrap()); + let addr = (export.addr() as usize); + println!(); + println!("{:?}", data[addr..addr+512].hex_dump()); + println!(); + return Ok(()) + } + } + panic!("no main"); + } } diff --git a/crates/vestal/src/util.rs b/crates/vestal/src/util.rs index 71ae476..0d08c41 100644 --- a/crates/vestal/src/util.rs +++ b/crates/vestal/src/util.rs @@ -1,3 +1,17 @@ +pub(crate) use std::pin::Pin; +pub(crate) use std::sync::Arc; +pub(crate) use std::error::Error; +pub(crate) use std::path::{Path, PathBuf}; +pub(crate) use std::collections::{HashMap, HashSet}; +pub(crate) use std::fs::{read, canonicalize}; +//pub(crate) use ::lancelot::loader::pe::{PE, reloc::apply_relocations}; +//pub(crate) use ::goblin::{error, Object, pe::{import::Import, export::Export}}; +pub(crate) use ::object::endian::LittleEndian; +pub(crate) use ::object::pe::ImageNtHeaders64; +pub(crate) use ::object::read::pe::{PeFile, ExportTarget}; +pub(crate) use ::object::write::elf::Writer as ElfWriter; +pub(crate) use ::pretty_hex::*; +pub(crate) type Usually = Result>; /// You can manually patch DLLs by prepending /// a `#!/usr/bin/env vestal` line to them. pub fn slice_shebang (buffer: &[u8]) -> (Vec, Vec) {