【问题标题】:Easyhook: unmanaged hooking, how to call original function / change return status?Easyhook:非托管挂钩,如何调用原始函数/更改返回状态?
【发布时间】:2013-09-06 13:17:14
【问题描述】:

所以我在winspool.drv!WritePrinter有一个钩子函数,它被远程注入到spoolsv.exe的非托管C++成功钩子。

目前,钩子似乎要么替换原始函数,要么以无法检测的方式破坏堆栈:钩子后,WritePrinter 调用导致钩子外没有打印机活动。

我发现至少有一种方法可以调用原始函数,即所谓的LhGetOldProc。但是,使用它会导致崩溃,不确定这是与 easyhook 相关的错误还是只是错误的转换。

那么,如何在 Easyhook 非托管版本中正确调用原始函数?

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
}

挂钩代码:

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:在 2013 年,CodePlex(EasyHook 讨论列表所在的位置)在使用 Microsoft 帐户注册时不接受电子邮件的三级域。不会使用 Firebug 绕过表单。

【问题讨论】:

  • 不得不将讨论迁移到 codeplex,easyhook.codeplex.com/discussions/456212
  • 这是什么版本的 Windows?您可以发布更多代码吗?根据我所看到的一切,你在这里提出的建议不应该奏效。

标签: c++ unmanaged easyhook


【解决方案1】:

堆栈被破坏,因为你的函数指针有错误的调用约定。

默认调用约定是 __cdecl,它要求调用者清理堆栈。

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

等于:

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

但是 winapi 函数使用 __stdcall 调用约定,它期望被调用者清理堆栈。 你将不得不 typedef 一个 __stdcall 函数:

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

【讨论】:

  • spoolsv.exe 中 0xF... 处未处理的异常:执行位置 0xF.. 的访问冲突(可能 DEP 触发?)
  • casting to void* 似乎解决了问题,谢谢@user1283078
猜你喜欢
  • 1970-01-01
  • 2011-08-29
  • 2021-11-07
  • 2021-01-29
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多