【发布时间】:2016-08-16 20:57:24
【问题描述】:
我正在尝试挂钩 StartDocW 以通过 mhook 拦截打印。我使用 AppInit_DLLs 加载我的库。
DLL 代码很简单:
#include <windows.h>
#include "mhook/mhook-lib/mhook.h"
using StartDocPtr = int(*)(HDC, const DOCINFO*);
StartDocPtr orig;
int HookedStartDocW(HDC hdc, const DOCINFO* lpdi) {
return orig(hdc, lpdi);
}
BOOL WINAPI DllMain(__in HINSTANCE, __in DWORD Reason, __in LPVOID) {
orig = (StartDocPtr)GetProcAddress(GetModuleHandle("gdi32"), "StartDocW");
switch (Reason)
{
case DLL_PROCESS_ATTACH:
Mhook_SetHook((PVOID*)&orig, &HookedStartDocW);
break;
case DLL_PROCESS_DETACH:
Mhook_Unhook((PVOID*)&orig);
break;
}
}
挂钩正常工作,打印完成。但是如果我将 HookStartDocW 更改为以下:
int HookedStartDocW(HDC hdc, const DOCINFO* lpdi) {
char buf[40];
GetModuleFileName(NULL, buf, 40);
return orig(hdc, lpdi);
}
打印程序会立即崩溃。即使我只是离开char buf[40] 并评论GetModuleHandle - 程序也会挂起。为什么会这样?
此外,如果程序崩溃\打印时挂起(如果我添加了除 return orig(hdc, lpdi) 之外的任何内容)- PC 开始表现得很奇怪,拒绝运行程序等。如果我重新启动它 - Windows 只是在启动屏幕上无休止地旋转,让它恢复运行的唯一方法是通过 liveCD 启动并重命名\删除我的钩子 DLL。
打印程序:Excel 2016、记事本。
编译器 - MSVC 2015,x64 版本的 DLL 编译,使用 MBCS 而不是 unicode。
【问题讨论】:
-
你已经从
StartDocW签名中遗漏了WINAPI调用约定(在它的替换和指向旧函数的 typedef 中),所以堆栈正在被修改。