Question

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.

Was it helpful?

Solution

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.

typedef BOOL (* wp)(_In_   HANDLE ....);

equals:

typedef BOOL (__cdecl* wp)(_In_   HANDLE ...);

but the winapi functions use __stdcall calling convention which expects the callee to clean the stack. you will have to typedef a __stdcall function:

typedef BOOL (__stdcall* wp)(_In_   HANDLE ....);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top