explore entrypoint hexdump

This commit is contained in:
🪞👃🪞 2025-02-19 23:16:29 +02:00
parent 10c922e0c5
commit 8946a571ae
4 changed files with 121 additions and 22 deletions

48
Cargo.lock generated
View file

@ -8,6 +8,15 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 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]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.18" version = "0.6.18"
@ -143,6 +152,15 @@ dependencies = [
"foldhash", "foldhash",
] ]
[[package]]
name = "hexy"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06fe36e4a24d8f2efdf7c336b7e13cec34ce338d9e191a2bc712f1d67ab21cbb"
dependencies = [
"ansi_term",
]
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.7.1" version = "2.7.1"
@ -253,6 +271,12 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "pretty-hex"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbc83ee4a840062f368f9096d80077a9841ec117e17e7f700df81958f1451254"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.93" version = "1.0.93"
@ -379,7 +403,9 @@ name = "vestal"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"clap", "clap",
"hexy",
"object", "object",
"pretty-hex",
"syscalls", "syscalls",
] ]
@ -390,6 +416,28 @@ dependencies = [
"tek_jack", "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]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.59.0" version = "0.59.0"

View file

@ -7,6 +7,8 @@ edition = "2021"
clap = { version = "4.5.4", features = [ "cargo" ] } clap = { version = "4.5.4", features = [ "cargo" ] }
syscalls = "0.6.18" syscalls = "0.6.18"
object = { version = "0.36.7", features = [ "read_core", "write_core", "elf", "pe" ] } 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" #exe = "0.5.6"
#elf = "0.7.4" #elf = "0.7.4"
#goblin = "0.9.3" #goblin = "0.9.3"

View file

@ -3,20 +3,7 @@ mod util;
pub(crate) use self::util::*; pub(crate) use self::util::*;
//mod dll; //mod dll;
//mod exec; //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}; use clap::{arg, command, value_parser, ArgAction, Command};
type Usually<T> = Result<T, Box<dyn std::error::Error>>;
fn main () -> Usually<()> { fn main () -> Usually<()> {
let matches = command!() let matches = command!()
.arg(arg!([path] "Path to VST DLL").value_parser(value_parser!(PathBuf))) .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"))? { if let Some(path) = vestal.resolve(path.to_str().expect("path must be unicode"))? {
vestal.load(&path)?; vestal.load(&path)?;
vestal.inspect(); vestal.inspect();
vestal.run_main(&path)?;
} else { } else {
panic!("Could not find: {path:?}") panic!("Could not find: {path:?}")
} }
@ -48,7 +36,28 @@ struct Vestal {
path_to_imports: HashMap<Arc<PathBuf>, Vec<Import>>, path_to_imports: HashMap<Arc<PathBuf>, Vec<Import>>,
} }
#[derive(Debug)] #[derive(Debug)]
struct Export {} struct Export {
id: u32,
name: Option<Arc<[u8]>>,
target: Target,
}
impl Export {
fn name_string (&self) -> Option<String> {
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)] #[derive(Debug)]
struct Import {} struct Import {}
impl Vestal { impl Vestal {
@ -73,14 +82,19 @@ impl Vestal {
let dll: PeFile<'_, ImageNtHeaders64, &[u8]> = PeFile::parse(data.as_slice())?; let dll: PeFile<'_, ImageNtHeaders64, &[u8]> = PeFile::parse(data.as_slice())?;
if let Some(exports) = dll.export_table()? { if let Some(exports) = dll.export_table()? {
let mut collected = vec![]; let mut collected = vec![];
for export in exports.exports()?.iter() { for export_ref in exports.exports()?.iter() {
collected.push(Export {}); collected.push(Export {
if let Some(name) = export.name { id: export_ref.ordinal,
let name = String::from_utf8(name.to_vec())?; name: export_ref.name.map(|name|name.into()),
//println!(" (export {} {:?} {:?})", &export.ordinal, &name, &export.target); target: match export_ref.target {
} else { ExportTarget::Address(addr) =>
//println!(" (export {} <nameless> {:?})", &export.ordinal, &export.target) 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); self.path_to_exports.insert(path.clone(), collected);
} }
@ -130,4 +144,25 @@ impl Vestal {
//println!(")"); //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");
}
} }

View file

@ -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<T> = Result<T, Box<dyn std::error::Error>>;
/// You can manually patch DLLs by prepending /// You can manually patch DLLs by prepending
/// a `#!/usr/bin/env vestal` line to them. /// a `#!/usr/bin/env vestal` line to them.
pub fn slice_shebang (buffer: &[u8]) -> (Vec<u8>, Vec<u8>) { pub fn slice_shebang (buffer: &[u8]) -> (Vec<u8>, Vec<u8>) {