mirror of
https://codeberg.org/unspeaker/vestal.git
synced 2025-12-06 10:46:42 +01:00
separate load/show/main
This commit is contained in:
parent
09bdc91701
commit
5490fef835
3 changed files with 131 additions and 111 deletions
|
|
@ -33,7 +33,7 @@ impl Vestal {
|
||||||
let ilt = descriptor.get_original_first_thunk(dll)?;
|
let ilt = descriptor.get_original_first_thunk(dll)?;
|
||||||
let lookups = descriptor.get_lookup_thunks(dll)?;
|
let lookups = descriptor.get_lookup_thunks(dll)?;
|
||||||
let resolved = Arc::new(self.resolve(&dep)?.expect("no path for {name}"));
|
let resolved = Arc::new(self.resolve(&dep)?.expect("no path for {name}"));
|
||||||
print!("\n (module {BOLD}{dep:?}{RESET} N=0x{:>08x} IAT=0x{:>08x} ILT=0x{:>08x}\n {resolved:?}",
|
print!(" (module {BOLD}{dep:?}{RESET} N=0x{:>08x} IAT=0x{:>08x} ILT=0x{:>08x}\n {resolved:?}",
|
||||||
&descriptor.name.0,
|
&descriptor.name.0,
|
||||||
&descriptor.first_thunk.0,
|
&descriptor.first_thunk.0,
|
||||||
&descriptor.original_first_thunk.0);
|
&descriptor.original_first_thunk.0);
|
||||||
|
|
@ -56,13 +56,13 @@ impl Vestal {
|
||||||
let call_via = descriptor.first_thunk.0 + index as u32 * 8;
|
let call_via = descriptor.first_thunk.0 + index as u32 * 8;
|
||||||
let name = match import {
|
let name = match import {
|
||||||
ImportData::Ordinal(x) => {
|
ImportData::Ordinal(x) => {
|
||||||
print!("\n (import-ordinal {BOLD}0x{:>08x}{RESET} IAT={} ILT={} LU={} 0x{:>04x})",
|
//print!("\n (import-ordinal {BOLD}0x{:>08x}{RESET} IAT={} ILT={} LU={} 0x{:>04x})",
|
||||||
call_via, thunk, orig, lookup, x);
|
//call_via, thunk, orig, lookup, x);
|
||||||
format!("___VESTAL___ORD___{x}___")
|
format!("___VESTAL___ORD___{x}___")
|
||||||
},
|
},
|
||||||
ImportData::ImportByName(name) => {
|
ImportData::ImportByName(name) => {
|
||||||
print!("\n (import-by-name {BOLD}0x{:>08x}{RESET} IAT={} ILT={} LU={} {:?})",
|
//print!("\n (import-by-name {BOLD}0x{:>08x}{RESET} IAT={} ILT={} LU={} {:?})",
|
||||||
call_via, thunk, orig, lookup, name);
|
//call_via, thunk, orig, lookup, name);
|
||||||
format!("{name}")
|
format!("{name}")
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#![feature(slice_split_once)]
|
#![feature(slice_split_once)]
|
||||||
mod util;
|
mod util;
|
||||||
mod load;
|
mod load;
|
||||||
|
mod show;
|
||||||
pub(crate) use self::util::*;
|
pub(crate) use self::util::*;
|
||||||
use clap::{arg, command, value_parser, ArgAction, Command};
|
use clap::{arg, command, value_parser, ArgAction, Command};
|
||||||
fn main () -> Usually<()> {
|
fn main () -> Usually<()> {
|
||||||
|
|
@ -42,114 +43,17 @@ impl Vestal {
|
||||||
fn enter (&mut self, path: &PathBuf) -> Usually<()> {
|
fn enter (&mut self, path: &PathBuf) -> Usually<()> {
|
||||||
let mut total = 0usize;
|
let mut total = 0usize;
|
||||||
self.load(&path)?;
|
self.load(&path)?;
|
||||||
let data = self.path_to_data.get(path);
|
|
||||||
let len = data.as_ref().unwrap().len();
|
|
||||||
let data = data.as_ref().unwrap();
|
|
||||||
//println!();
|
|
||||||
//println!();
|
|
||||||
for (dll_path, dll) in self.path_to_pe.iter() {
|
for (dll_path, dll) in self.path_to_pe.iter() {
|
||||||
let ep_rva = dll.get_entrypoint()?;
|
self.show_dll(dll_path)?;
|
||||||
let ep_off = dll.rva_to_offset(ep_rva)?;
|
|
||||||
println!("\n\n{:p} 0x{:x?} {:x?} {:x?}\n{dll_path:?}\n",
|
|
||||||
dll.as_ptr(),
|
|
||||||
dll.get_image_base()?,
|
|
||||||
ep_rva,
|
|
||||||
ep_off);
|
|
||||||
if true || dll_path.as_ref() == path {
|
|
||||||
let dll_data = self.path_to_data.get(dll_path).unwrap();
|
let dll_data = self.path_to_data.get(dll_path).unwrap();
|
||||||
total += dll_data.len();
|
let len = dll_data.len();
|
||||||
println!("{:?}", dll_data.hex_dump());
|
println!(" (bytes {len} 0x{len:x})");
|
||||||
let buf = dll.get_buffer();
|
self.show_calls(dll_path, dll_path.as_ref() == path)?;
|
||||||
let section = dll.get_section_by_name(".text")?;
|
total += len;
|
||||||
let section_ptr = section.pointer_to_raw_data.0 as usize;
|
//println!("{:?}", dll_data.hex_dump());
|
||||||
let section_len = section.size_of_raw_data as usize;
|
|
||||||
let section_data = &buf[section_ptr..section_ptr+section_len];
|
|
||||||
let mut decoder = iced_x86::Decoder::with_ip(64, section_data, 0x1000, 0);
|
|
||||||
while decoder.can_decode() {
|
|
||||||
let position = decoder.position();
|
|
||||||
let instruction = decoder.decode();
|
|
||||||
let opcodes = §ion_data[position..position+instruction.len()];
|
|
||||||
//println!("0x{position:08x} {opcodes:32} {instruction}");
|
|
||||||
if (instruction.flow_control() == iced_x86::FlowControl::IndirectBranch
|
|
||||||
|| instruction.flow_control() == iced_x86::FlowControl::IndirectCall)
|
|
||||||
&& instruction.op0_kind() == iced_x86::OpKind::Memory {
|
|
||||||
match opcodes[0] {
|
|
||||||
0xff => match opcodes[1] {
|
|
||||||
0x10 | 0x12 | 0x13 |
|
|
||||||
0x50 | 0x51 | 0x52 | 0x53 | 0x54 | 0x55 | 0x56 | 0x57 |
|
|
||||||
0x60 | 0x90 | 0x92 | 0x93 | 0x94 | 0x97 => continue,
|
|
||||||
_ => {},
|
|
||||||
},
|
|
||||||
0x41 | 0x42 | 0x43 | 0x49 => match opcodes[1] {
|
|
||||||
0xff => continue,
|
|
||||||
_ => {},
|
|
||||||
},
|
|
||||||
0x48 => match opcodes[2] {
|
|
||||||
0x20 | 0x60 | 0x62 | 0xa0 | 0xa2 => continue,
|
|
||||||
_ => {},
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
let offset = (position + section_ptr) as u32;
|
//self.show_addr_to_import();
|
||||||
let offset_rva = dll.offset_to_rva(Offset(offset))?.0;
|
println!("(bytes-total {total} (0x{total:x})");
|
||||||
let call_target = match opcodes[0] {
|
|
||||||
0xff => match opcodes[1] {
|
|
||||||
0x15 | 0x25 =>
|
|
||||||
offset_rva + opcodes.len() as u32 + u32::from_le_bytes([
|
|
||||||
opcodes[2],
|
|
||||||
opcodes[3],
|
|
||||||
opcodes[4],
|
|
||||||
opcodes[5]
|
|
||||||
]),
|
|
||||||
_ => 0x0
|
|
||||||
},
|
|
||||||
0x48 => match opcodes[1] {
|
|
||||||
0xff => match opcodes[2] {
|
|
||||||
0x15 | 0x25 =>
|
|
||||||
offset_rva + opcodes.len() as u32 + u32::from_le_bytes([
|
|
||||||
opcodes[3],
|
|
||||||
opcodes[4],
|
|
||||||
opcodes[5],
|
|
||||||
opcodes[6]
|
|
||||||
]),
|
|
||||||
_ => 0x0
|
|
||||||
},
|
|
||||||
_ => 0x0
|
|
||||||
}
|
|
||||||
_ => 0x0
|
|
||||||
};
|
|
||||||
println!("{BOLD}{:20?}{RESET} O=0x{:08x} {BOLD}R=0x{:08x}{RESET} {:25} {:40} 0x{:08x} {:?}",
|
|
||||||
dll_path.file_name().unwrap(),
|
|
||||||
offset,
|
|
||||||
offset_rva,
|
|
||||||
opcodes.iter().map(|x|format!("{x:>02x}")).collect::<Vec<_>>().join(" "),
|
|
||||||
instruction,
|
|
||||||
call_target,
|
|
||||||
self.addr_to_import.get(&call_target));
|
|
||||||
//println!("0x{:08x} {}", decoder.position(), instruction);
|
|
||||||
//return Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//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!();
|
|
||||||
//return Ok(())
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
//panic!("no main");
|
|
||||||
for addr in self.addr_to_import.keys() {
|
|
||||||
let (dll, export) = self.addr_to_import.get(addr).unwrap();
|
|
||||||
println!("{BOLD}0x{addr:>08x}{RESET} {dll:>20} {export:<40}");
|
|
||||||
}
|
|
||||||
//println!("{:#?}", &self.addr_to_import);
|
|
||||||
println!("Total code bytes: {total} (0x{total:x})");
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
116
crates/vestal/src/show.rs
Normal file
116
crates/vestal/src/show.rs
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
use crate::*;
|
||||||
|
impl Vestal {
|
||||||
|
pub fn show_addr_to_import (&self) {
|
||||||
|
for (addr, (dll, export)) in self.addr_to_import.iter() {
|
||||||
|
println!("{BOLD}0x{addr:>08x}{RESET} {dll:>20} {export:<40}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn show_vst_entrypoint (&self, path: &PathBuf) {
|
||||||
|
//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!();
|
||||||
|
//return Ok(())
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
//panic!("no main");
|
||||||
|
//println!("{:#?}", &self.addr_to_import);
|
||||||
|
}
|
||||||
|
pub fn show_dll (&self, path: &PathBuf) -> Usually<()> {
|
||||||
|
let dll = self.path_to_pe.get(path).expect("no such library");
|
||||||
|
let ep_rva = dll.get_entrypoint()?;
|
||||||
|
let ep_off = dll.rva_to_offset(ep_rva)?;
|
||||||
|
println!("\n({:p} 0x{:x?} {:x?} {:x?}\n {path:?})",
|
||||||
|
dll.as_ptr(),
|
||||||
|
dll.get_image_base()?,
|
||||||
|
ep_rva,
|
||||||
|
ep_off);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
pub fn show_calls (&self, path: &PathBuf, verbose: bool) -> Usually<()> {
|
||||||
|
let mut calls = 0;
|
||||||
|
let dll = self.path_to_pe.get(path).expect("no such library");
|
||||||
|
let buf = dll.get_buffer();
|
||||||
|
let section = dll.get_section_by_name(".text")?;
|
||||||
|
let section_ptr = section.pointer_to_raw_data.0 as usize;
|
||||||
|
let section_len = section.size_of_raw_data as usize;
|
||||||
|
let section_data = &buf[section_ptr..section_ptr+section_len];
|
||||||
|
let mut decoder = iced_x86::Decoder::with_ip(64, section_data, 0x1000, 0);
|
||||||
|
while decoder.can_decode() {
|
||||||
|
let position = decoder.position();
|
||||||
|
let instruction = decoder.decode();
|
||||||
|
let opcodes = §ion_data[position..position+instruction.len()];
|
||||||
|
//println!("0x{position:08x} {opcodes:32} {instruction}");
|
||||||
|
if (instruction.flow_control() == iced_x86::FlowControl::IndirectBranch
|
||||||
|
|| instruction.flow_control() == iced_x86::FlowControl::IndirectCall)
|
||||||
|
&& instruction.op0_kind() == iced_x86::OpKind::Memory {
|
||||||
|
match opcodes[0] {
|
||||||
|
0xff => match opcodes[1] {
|
||||||
|
0x10 | 0x12 | 0x13 |
|
||||||
|
0x50 | 0x51 | 0x52 | 0x53 | 0x54 | 0x55 | 0x56 | 0x57 |
|
||||||
|
0x60 | 0x90 | 0x92 | 0x93 | 0x94 | 0x97 => continue,
|
||||||
|
_ => {},
|
||||||
|
},
|
||||||
|
0x41 | 0x42 | 0x43 | 0x49 => match opcodes[1] {
|
||||||
|
0xff => continue,
|
||||||
|
_ => {},
|
||||||
|
},
|
||||||
|
0x48 => match opcodes[2] {
|
||||||
|
0x20 | 0x60 | 0x62 | 0xa0 | 0xa2 => continue,
|
||||||
|
_ => {},
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
let offset = (position + section_ptr) as u32;
|
||||||
|
let offset_rva = dll.offset_to_rva(Offset(offset))?.0;
|
||||||
|
let call_target = match opcodes[0] {
|
||||||
|
0xff => match opcodes[1] {
|
||||||
|
0x15 | 0x25 =>
|
||||||
|
offset_rva + opcodes.len() as u32 + u32::from_le_bytes([
|
||||||
|
opcodes[2],
|
||||||
|
opcodes[3],
|
||||||
|
opcodes[4],
|
||||||
|
opcodes[5]
|
||||||
|
]),
|
||||||
|
_ => 0x0
|
||||||
|
},
|
||||||
|
0x48 => match opcodes[1] {
|
||||||
|
0xff => match opcodes[2] {
|
||||||
|
0x15 | 0x25 =>
|
||||||
|
offset_rva + opcodes.len() as u32 + u32::from_le_bytes([
|
||||||
|
opcodes[3],
|
||||||
|
opcodes[4],
|
||||||
|
opcodes[5],
|
||||||
|
opcodes[6]
|
||||||
|
]),
|
||||||
|
_ => 0x0
|
||||||
|
},
|
||||||
|
_ => 0x0
|
||||||
|
}
|
||||||
|
_ => 0x0
|
||||||
|
};
|
||||||
|
let unknown = (String::from("unknown"), String::from("unknown"));
|
||||||
|
let external = format!("{}::{}",
|
||||||
|
self.addr_to_import.get(&call_target).unwrap_or(&unknown).0,
|
||||||
|
self.addr_to_import.get(&call_target).unwrap_or(&unknown).1);
|
||||||
|
let dependent = path.file_name().unwrap();
|
||||||
|
if verbose {
|
||||||
|
println!(" ({BOLD}{external:30}{RESET} O=0x{:08x} {BOLD}R=0x{:08x}{RESET} {:25} {:40} 0x{:08x}",
|
||||||
|
offset,
|
||||||
|
offset_rva,
|
||||||
|
opcodes.iter().map(|x|format!("{x:>02x}")).collect::<Vec<_>>().join(" "),
|
||||||
|
instruction,
|
||||||
|
call_target,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
calls += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!(" (calls {calls})");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue