I've been writing a little hooking library, which uses MS Detours and can attach to any MS API in any process and log what it's doing. One of things I've tried to do in my library is to remove all the boiler plate from hooking so that each hook can be written very simply.
I've got it down to this being all that's required to hook the CreateFile function and print its first parameter to the debugger:
Hooker hooker;
Hook(hooker, dllnames::Kernel32, apis::T_CreateFileW, CreateFileW, [](auto lpFilename, auto ...rest) -> auto
{
APILOG(L"%s", lpFilename);
return TruePtr(lpFilename, rest...);
});
The only boiler plate required for this, is the function pointer definition apis::T_CreateFileW
. However, it strikes me for many cases, I could go further even than this. I'm wondering if I could us a macro to write the above as:
APILOG(hooker, dllnames::Kernel32, CreateFileW, L"%s", lpFilename);
This would mean that could almost write a printf that would allow me to log what any API was doing provided its parameters could be reasonably captured with a format string.
But is this possible as a macro? I guess some problems are:
- I have to expand the ... of the macro into both
auto param1, auto param2
as well asparam1, param2
. - I'd have to specify and print at least the first N parameters of the real API in my format string whether I want them or not, since only at that point can I pass
rest...
- If I want to print all the parameters, I wouldn't be able to pass
rest...
It's possible I've already simplified this as far as I can, I'm just curious to see if anything approaching it is possible.