簡體   English   中英

通過mhook的Winapi鈎子導致程序崩潰或掛起

[英]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.hStartDocW()的實際聲明:

__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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM