IDirect3DDevice9 :: EndScene钩子有时在参数IDirect3DDevice9中得到NULL

时间:2014-07-26 09:18:17

标签: c++ directx hook directx-9

我为函数IDirect3DDevice9 :: EndScene创建了一个trampoline钩子。如果要跳转到的EndScene函数,我修改了开始的编码器:

__declspec(naked) HRESULT EndScene_Hook(IDirect3DDevice9* device)
{
    ScreenCapture::Capture(device);

    __asm
    {
        PUSH 0x14
        MOV EAX, 0x718E6478
        JMP address
    }
}

问题是有时device为NULL,为什么会这样?如果我添加这样一个小条件:

if(device != NULL)
    ScreenCapture::Capture(device);

一切都按预期运行,没有错误。

这个函数接收device为NULL的原因可能是什么?这是对象IDirect3DDevice9的成员函数,不应该像EndScene(NULL)那样调用它,因为它总是从它的对象调用(例如pDevice-> EndScene())。

2 个答案:

答案 0 :(得分:1)

使用__declspec(naked)告诉编译器不要为该函数发出序言或结尾。在序言中,编译器通常会发出必要的指令,以便以后能够访问在堆栈上传递的函数的参数。由于您的代码引用了参数device,因此编译器为访问此参数而发出的代码不起作用,最终会访问内存中不可预测的值。最可能的一种可能性是最终访问调用它的函数的第一个参数,这就是为什么它似乎不时起作用的原因。但是,你不能依赖于此。

你应该在程序集中完全编写这样的函数。如果你想要它,你仍然需要连接64位代码。

答案 1 :(得分:0)

从NULL对象调用它是未定义的行为。未定义的行为包括“我写的钩子有时会收到NULL”。无论你在做什么计划,显然只是有些烦恼。或者你的钩子被窃听。