You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用EasyHook挂钩CreateWindowExW时调用原函数的相关疑问

问题分析
  • 你当前的写法会触发无限递归,最终导致栈溢出程序崩溃:你挂钩的目标就是user32.dll导出的CreateWindowExW函数,当你在挂钩回调CreateWindowExW_Hook中直接调用CreateWindowExW时,调用的还是被Hook修改过入口的函数,会再次跳转到你的CreateWindowExW_Hook函数,永远不会执行原函数的逻辑。
正确实现方案

EasyHook提供了规范的原函数调用方式,你需要提前定义原函数的签名指针,存储未被Hook的原函数地址后调用即可,修改后的完整代码如下:

// 首先定义CreateWindowExW的函数指针签名
typedef HWND (__stdcall *PFN_CreateWindowExW)(
    DWORD     dwExStyle,
    LPCWSTR   lpClassName,
    LPCWSTR   lpWindowName,
    DWORD     dwStyle,
    int       X,
    int       Y,
    int       nWidth,
    int       nHeight,
    HWND      hWndParent,
    HMENU     hMenu,
    HINSTANCE hInstance,
    LPVOID    lpParam
);

// 全局变量存储原函数的可调用地址
PFN_CreateWindowExW g_pOriginalCreateWindowExW = nullptr;

HWND __stdcall CreateWindowExW_Hook(
    DWORD     dwExStyle,
    LPCWSTR   lpClassName,
    LPCWSTR   lpWindowName,
    DWORD     dwStyle,
    int       X,
    int       Y,
    int       nWidth,
    int       nHeight,
    HWND      hWndParent,
    HMENU     hMenu,
    HINSTANCE hInstance,
    LPVOID    lpParam
)
{
    // 修改参数
    X = 50; Y = 50; nWidth = 400; nHeight = 300;
    // 调用存储的原函数地址,不会触发Hook
    return g_pOriginalCreateWindowExW(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}

extern "C" void __declspec(dllexport) __stdcall NativeInjectionEntryPoint(REMOTE_ENTRY_INFO* inRemoteInfo);

void __stdcall NativeInjectionEntryPoint(REMOTE_ENTRY_INFO* inRemoteInfo)
{
    HOOK_TRACE_INFO hHook = { NULL };
    // 先获取原函数地址
    PVOID pCreateWindowExWAddr = GetProcAddress(GetModuleHandle(TEXT("User32")), "CreateWindowExW");
    
    NTSTATUS result = LhInstallHook(
        pCreateWindowExWAddr,
        CreateWindowExW_Hook,
        NULL,
        &hHook);
    
    if (SUCCEEDED(result))
    {
        // 获取可直接调用的原函数地址,存入全局变量
        LhGetOriginalFunction(&hHook, (PVOID*)&g_pOriginalCreateWindowExW);
        
        ULONG ACLEntries[1] = { 0 };
        LhSetExclusiveACL(ACLEntries, 1, &hHook);
    }
}
补充说明
  • 不需要额外定义同名的CreateWindowExW函数,你只需要通过EasyHook提供的LhGetOriginalFunction接口获取绕过Hook的原函数地址调用即可,不会触发二次Hook。
  • 如果你提前在安装Hook之前就备份原函数的入口机器码手动跳转也可以实现,但直接用EasyHook提供的接口兼容性更好,不需要处理不同系统下函数入口的差异。

内容的提问来源于stack exchange,提问作者user16872085

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:48:04