use std::collections::BTreeMap;
use anyhow::Result;
use lazy_static::lazy_static;
use super::WindowsEmulator;
pub enum CallingConvention {
Stdcall,
Cdecl,
}
pub struct ArgumentDescriptor {
pub ty: String,
pub name: String,
}
pub struct FunctionDescriptor {
pub calling_convention: CallingConvention,
pub return_type: String,
pub arguments: Vec<ArgumentDescriptor>,
}
type Hook = Box<dyn Fn(&mut dyn WindowsEmulator, &FunctionDescriptor) -> Result<()> + Send + Sync>;
lazy_static! {
pub static ref API: BTreeMap<String, FunctionDescriptor> = {
let mut m = BTreeMap::new();
m.insert(
String::from("kernel32.dll!GetVersionExA"),
FunctionDescriptor {
calling_convention: CallingConvention::Stdcall,
return_type: String::from("bool"),
arguments: vec![
ArgumentDescriptor {
ty: String::from("LPOSVERSIONINFOA"),
name: String::from("lpVersionInformation"),
}
]
}
);
m
};
pub static ref HOOKS: BTreeMap<String, Hook> = {
let mut m = BTreeMap::new();
m.insert(
String::from("kernel32.dll!GetVersionExA"),
Box::new(
move |emu: &mut dyn WindowsEmulator, desc: &FunctionDescriptor| -> Result<()> {
let ra = emu.pop()?;
emu.set_pc(ra);
if let CallingConvention::Stdcall = desc.calling_convention {
for _ in 0..desc.arguments.len() {
let _ = emu.pop()?;
}
}
Ok(())
}
) as Hook
);
m
};
}