use pelite;
use pelite::pattern as pat;
use pelite::{util::CStr, Pod};
use pelite::pe32::*;
pub fn print(file: PeFile, dll_name: &str) {
let ifaces = interfaces(file);
tprint! {
"### Interfaces\n\n"
"```\n"
for iface in (&ifaces) {
{dll_name}"!"{iface.address;#010x}" "{iface.name}"\n"
}
"```\n\n"
}
}
#[allow(dead_code)]
#[derive(Pod, Debug)]
#[repr(C)]
pub struct InterfaceReg {
create_fn: Va,
name: Ptr<CStr>,
next: Ptr<InterfaceReg>,
}
#[derive(Copy, Clone, Debug)]
pub struct Interface<'a> {
pub name: &'a str,
pub address: u32,
}
pub fn interfaces<'a>(file: PeFile<'a>) -> Vec<Interface<'a>> {
let mut save = [0; 8];
let exports = file.exports().unwrap().by().unwrap();
let create_interface_fn = exports.name("CreateInterface").unwrap().symbol().unwrap();
#[allow(non_snake_case)]
let s_pInterfaceRegs = {
file.scanner().exec(create_interface_fn, pat!("55 8BEC 5D E9$ 55 8BEC 56 8B35*{'}"), &mut save);
save[1]
};
let mut list = Vec::new();
let mut matches = file.scanner().matches_code(pat!("A1*{'} A3???? C705*{'}*{*{B8*'} *'} C3"));
while matches.next(&mut save) {
if save[1] != s_pInterfaceRegs || save[2] != s_pInterfaceRegs {
continue;
}
let name = file.derva_c_str(save[4]).unwrap().to_str().unwrap();
let address = save[3];
list.push(Interface { name, address });
}
list.sort_unstable_by_key(|iface| iface.name);
return list;
}