So I have a hook function at winspool.drv!WritePrinter
, which is successfully hooked with unmanaged C++ remotely injected to spoolsv.exe.
Currently, the hook seems to either replace original function, or corrupt the stack in an undetectable way: after hooking, WritePrinter calls result in no printer activity outside the hook.
I've figured out there's at least one way to call original function, so-called LhGetOldProc
. However, using it leads to crashes, don't sure if this is easyhook-related error or it's just bad casting.
So, how do I properly call original function in Easyhook unmanaged version?
Hook callback with LhGetOldProc
:
UCHAR *uc = NULL;
LhGetOldProc(hhW, &uc);
typedef BOOL (*wp)(_In_ HANDLE, _In_ LPVOID, _In_ DWORD cbBuf, _Out_ LPDWORD);
wp my_wp = reinterpret_cast<wp>(reinterpret_cast<long>(uc)); // http://stackoverflow.com/questions/1096341/function-pointers-casting-in-c
BOOL res ;
if (my_wp == 0x0) {
return -1;
} else {
res = my_wp(hPrinter, pBuf, cbBuf, pcWritten); // crash
}
Hook code:
HMODULE hSpoolsv = LoadLibraryA("winspool.drv");
TRACED_HOOK_HANDLE hHook = new HOOK_TRACE_INFO();
NTSTATUS NtStatus;
UNICODE_STRING* NameBuffer = NULL;
HANDLE hRemoteThread;
FORCE(LhInstallHook(GetProcAddress(hSpoolsv, "WritePrinter"), WritePrinterHookA, 0x0, hHook));
ULONG ACLEntries[1] = { (ULONG) - 1 };
FORCE(LhSetExclusiveACL(ACLEntries, 1, hHook));
hhW = hHook;
TIL: in 2013, CodePlex (where EasyHook discussion list is) doesn't accept third level domains for e-mail when registering with Microsoft account. Not going to use Firebug to bypass the form.
The stack gets corrupted because your function pointer has the wrong calling convention.
The default calling convention is __cdecl which expects the caller to clean the stack.
equals:
but the winapi functions use __stdcall calling convention which expects the callee to clean the stack. you will have to typedef a __stdcall function: