简体   繁体   English

Easyhook:非托管挂钩,如何调用原始功能/更改返回状态?

[英]Easyhook: unmanaged hooking, how to call original function / change return status?

So I have a hook function at winspool.drv!WritePrinter , which is successfully hooked with unmanaged C++ remotely injected to spoolsv.exe. 所以我在winspool.drv!WritePrinter有一个钩子函数,它与远程注入spoolsv.exe的非托管C ++成功挂钩。

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. 目前,钩子似乎要么取代原始函数,要么以不可检测的方式破坏堆栈:挂钩后,WritePrinter调用导致钩子外没有打印机活动。

I've figured out there's at least one way to call original function, so-called LhGetOldProc . 我已经发现至少有一种方法可以调用原始函数,即所谓的LhGetOldProc However, using it leads to crashes, don't sure if this is easyhook-related error or it's just bad casting. 但是,使用它会导致崩溃,不确定这是否与easyhook相关的错误或者只是糟糕的投射。

So, how do I properly call original function in Easyhook unmanaged version? 那么,如何在Easyhook非托管版本中正确调用原始函数?

Hook callback with LhGetOldProc : 使用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. TIL:2013年,CodePlex(EasyHook讨论列表所在的位置)在使用Microsoft帐户注册时不接受电子邮件的第三级域名。 Not going to use Firebug to bypass the form. 不会使用Firebug绕过表单。

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. 默认调用约定是__cdecl,它希望调用者清理堆栈。

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. 但是winapi函数使用__stdcall调用约定,它希望被调用者清理堆栈。 you will have to typedef a __stdcall function: 你必须输入一个__stdcall函数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM