mirror of
https://codeberg.org/unspeaker/vestal.git
synced 2025-12-06 12:56:41 +01:00
explore entrypoint hexdump
This commit is contained in:
parent
10c922e0c5
commit
8946a571ae
4 changed files with 121 additions and 22 deletions
48
Cargo.lock
generated
48
Cargo.lock
generated
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue