I'm trying to write a small program that hooks IAT entries. Inside the hook, for now I want to just print the arguments and invoke orginal function (whose address I stored beforehand in a static context).
As I want to hook multiple entries, I was thinking about writing a macro
gen_hook_func!(MessageBoxA);
That given a function name, would generate a function hook:
fn hook_MessageBoxA(hWnd: HWND, lpText: LPCSTR, lpCaption: LPCSTR, uType: UINT) -> c_int {
// 1) Print arguments
println!("hWnd: {:?}", hWnd);
...
// 2) Call orginal function.
unsafe {
let orginal_func_addr = // retrieve from static
let orginal_func = std::mem::transmute<_,(HWND, LPCSTR, LPCSTR, UINT) -> c_int>(orginal_func_addr);
orginal_func(hWnd, lpText, lpCaption, uType);
}
}
However I'm having some technical issues (not really experienced in rust). The closest that I've managed to get to for now is:
macro_rules! gen_hook_func {
( $hook_name:ident, ($( $arg_name:ident : $arg_type:ty ),*) -> $ret_type:ty ) => {
fn $hook_name(
$(
$arg_name : $arg_type,
)*
) -> $ret_type {
$(
println!("{:?}", $arg_name);
)*
let orginal_func_addr: usize = ...
unsafe {
type OrginalFuncT = fn (
$(
$arg_type,
)*
) -> $ret_type;
let orginal_func = std::mem::transmute::<_, OrginalFuncT>(orginal_func_addr);
orginal_func(
$(
$arg_name,
)*
)
}
}
};
}
gen_hook_func!(hook_MessageBoxA, (hWnd: HWND, lpText: LPCSTR, lpCaption: LPCSTR, uType: UINT) -> c_int);
which is far from ideal, as I have to pass function signature to gen_hook_func!
macro. I'm sure there must be a cleaner way!