use pelite;
use pelite::pe32::{Va, Ptr, Pe, PeFile};
use pelite::{util::CStr, Pod};
use pelite::pattern as pat;
pub fn print(client: PeFile) {
for class in &classes(client).unwrap() {
println!("{:?}", class);
}
}
#[allow(non_snake_case)]
#[derive(Pod, Debug)]
#[repr(C)]
struct ClientClass {
pCreateFn: Ptr,
pCreateEventFn: Ptr,
pNetworkName: Ptr<CStr>,
pRecvTable: Va,
pNext: Ptr<ClientClass>,
ClassID: i32,
}
#[derive(Debug)]
pub struct Class<'a> {
pub network_name: &'a str,
pub class_id: i32,
pub size_of: u32,
}
pub fn classes<'a>(client: PeFile<'a>) -> pelite::Result<Vec<Class<'a>>> {
let mut save = [0; 8];
let mut list = Vec::new();
let pat = pat!("A1*{'} A3*{'} C705*{'}*{'???? ???? *{'}} C3");
let mut matches = client.scanner().matches_code(pat);
while matches.next(&mut save) {
if save[1] != save[3] || save[2] != save[4] + 0x10 {
continue;
}
let client_class: &ClientClass = client.derva(save[4]).unwrap();
let network_name = client.deref_c_str(client_class.pNetworkName).unwrap().to_str().unwrap();
let size_of = match client.deref_copy(client_class.pCreateFn.offset(4)) {
Ok(0x68_u8) => client.deref_copy::<u32>(client_class.pCreateFn.offset(5)).unwrap_or(0),
Ok(0x6A_u8) => client.deref_copy::<u8>(client_class.pCreateFn.offset(5)).unwrap_or(0) as u32,
_ => 0,
};
let class_id = 0;
list.push(Class { network_name, class_id, size_of })
}
Ok(list)
}