cleanup; big hexdump

This commit is contained in:
🪞👃🪞 2025-02-22 00:35:37 +02:00
parent a6511a5ed2
commit 27dec3a72c
3 changed files with 118 additions and 98 deletions

View file

@ -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<PathBuf>) -> Usually<Arc<[u8]>> {
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<PathBuf>) -> Usually<Arc<[u8]>> {
//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)
//}
//}

View file

@ -1,5 +1,56 @@
use crate::*;
///////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Default, Debug)]
struct Vestal {
search_paths: Vec<PathBuf>,
paths_visited: BTreeSet<Arc<PathBuf>>,
path_to_bang: BTreeMap<Arc<PathBuf>, Arc<[u8]>>,
path_to_data: BTreeMap<Arc<PathBuf>, Arc<[u8]>>,
path_to_pe: BTreeMap<Arc<PathBuf>, Arc<VecPE>>,
path_to_rpe: BTreeMap<Arc<PathBuf>, Arc<VecPE>>,
addr_to_import: BTreeMap<u32, (String, String)>,
//path_to_exports: BTreeMap<Arc<PathBuf>, Vec<ImageExportDescriptor>>,
//path_to_imports: BTreeMap<Arc<PathBuf>, Vec<ImageImportDescriptor>>,
}
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<Option<PathBuf>> {
for base in self.search_paths.iter() {

View file

@ -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 <VALUE> "Provide a stub import").required(false))
.get_matches();
let path = matches.get_one::<PathBuf>("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<VecPE>,
/// Bytes of `.text` section
code: Arc<[u8]>,
/// Start of `.text` section
code_start: u32,
/// Addresses of imported methods by library
deps_by_library: BTreeMap<Arc<str>, BTreeMap<Arc<str>, u32>>,
/// Imported methods by address
@ -61,10 +106,12 @@ impl Rebuilder {
..Default::default()
}
}
fn load (&mut self, path: &impl AsRef<Path>, recurse: bool) -> Usually<()> {
fn load (&mut self, path: &impl AsRef<Path>, recurse: bool) -> Usually<Arc<str>> {
let path: Arc<PathBuf> = 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<str> = 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<Option<PathBuf>> {
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 <VALUE> "Provide a stub import").required(false))
.get_matches();
if let Some(path) = matches.get_one::<PathBuf>("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<PathBuf>,
paths_visited: BTreeSet<Arc<PathBuf>>,
path_to_bang: BTreeMap<Arc<PathBuf>, Arc<[u8]>>,
path_to_data: BTreeMap<Arc<PathBuf>, Arc<[u8]>>,
path_to_pe: BTreeMap<Arc<PathBuf>, Arc<VecPE>>,
path_to_rpe: BTreeMap<Arc<PathBuf>, Arc<VecPE>>,
addr_to_import: BTreeMap<u32, (String, String)>,
//path_to_exports: BTreeMap<Arc<PathBuf>, Vec<ImageExportDescriptor>>,
//path_to_imports: BTreeMap<Arc<PathBuf>, Vec<ImageImportDescriptor>>,
}
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(())
}
}