[英]Winapi hook via mhook causes program crash or hang
我試圖鈎住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)
之外添加任何東西) return orig(hdc, lpdi)
開始表現異常怪異,拒絕運行程序,等等。如果我重新啟動它-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
。 因此,您對調用堆棧的管理不當。 這就是為什么您的代碼崩潰的原因。
您還使用DOCINFO
時,你應該使用DOCINFOW
代替。 在代碼中很明顯,您正在針對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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.