Winapi钩子通过mhook导致程序崩溃或挂起
Winapi hook via mhook causes program crash or hang
我试图通过mhook钩StartDocW拦截打印。我使用appinit_dll来加载我的库。
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。
你的钩子声明错误。
查看Wingdi.h
中StartDocW()
的实际声明:
__gdi_entry WINGDIAPI int WINAPI StartDocW(__in HDC hdc, __in CONST DOCINFOW *lpdi);
可以忽略__gdi_entry
。WINGDIAPI
简单地解析为__declspec(dllimport)
。在此声明中重要的是WINAPI
.
像几乎所有的 Win32 API函数一样,StartDocW()
使用__stdcall
调用约定。WINAPI
宏解析为__stdcall
。
你的代码根本没有指定任何调用约定,所以它使用编译器的默认值,通常是__cdecl
。因此,您对调用堆栈管理不当。这就是你的代码崩溃的原因。
当你应该使用DOCINFOW
时,你也在使用DOCINFO
。在您的代码中很明显,您正在为MBCS而不是UNICODE编译,因此DOCINFO
映射到DOCINFOA
。你不能将DOCINFOA
传递给StartDocW()
,它期望的是DOCINFOW
。
你需要修改你的声明,例如:
#include <windows.h>
#include "mhook/mhook-lib/mhook.h"
using StartDocPtr = int (WINAPI *)(HDC, const DOCINFOW*);
StartDocPtr orig = nullptr;
int WINAPI HookedStartDocW(HDC hdc, const DOCINFOW* lpdi) {
//...
return orig(hdc, lpdi);
}
BOOL WINAPI DllMain(__in HINSTANCE, __in DWORD Reason, __in LPVOID) {
orig = (StartDocPtr) GetProcAddress(GetModuleHandle(TEXT("gdi32")), "StartDocW");
switch (Reason)
{
case DLL_PROCESS_ATTACH:
Mhook_SetHook((PVOID*)&orig, &HookedStartDocW);
break;
case DLL_PROCESS_DETACH:
Mhook_Unhook((PVOID*)&orig);
break;
}
}
- 程序崩溃并显示"std::out_of_range"错误
- 试图创建流或fopen时程序崩溃
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- 如何找出应用程序崩溃的原因 - Win 10 LTSB
- 操纵安卓相机的深度图导致应用程序崩溃
- 为什么当我尝试搜索双链表中第一个数据条目之外的数据时,程序崩溃了?
- DLL Made with CMake 使程序崩溃
- 程序崩溃使用boost::asio
- 调用 free() 有时会导致程序崩溃
- 邮件加密程序崩溃
- 调用 java 的回调() 时应用程序崩溃.由于 detatchThread 而获得运行时错误
- 比较迭代器会使程序崩溃,而不会在自定义气泡排序实现中出现错误
- For 循环在尝试读取数组 c++ 时程序崩溃
- 即使有 0 个错误,Getter 似乎也会使程序崩溃
- Windows桌面程序保存您的计算机会话 - 基于程序崩溃时的恢复会话
- 无法访问的代码如何导致我的程序崩溃?
- 矢量迭代器在尝试调用函数时使我的程序崩溃
- QCompleter set模型使应用程序崩溃
- 使用唯一指针调用函数会使我的程序崩溃
- 删除SDL_PollEvent时程序崩溃