mirror of
https://codeberg.org/unspeaker/vestal.git
synced 2025-12-07 10:36:42 +01:00
explore entrypoint hexdump
This commit is contained in:
parent
10c922e0c5
commit
8946a571ae
4 changed files with 121 additions and 22 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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<T> = Result<T, Box<dyn std::error::Error>>;
|
||||
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<Arc<PathBuf>, Vec<Import>>,
|
||||
}
|
||||
#[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)]
|
||||
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 {} <nameless> {:?})", &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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
/// a `#!/usr/bin/env vestal` line to them.
|
||||
pub fn slice_shebang (buffer: &[u8]) -> (Vec<u8>, Vec<u8>) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue