我为函数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())。
答案 0 :(得分:1)
使用__declspec(naked)
告诉编译器不要为该函数发出序言或结尾。在序言中,编译器通常会发出必要的指令,以便以后能够访问在堆栈上传递的函数的参数。由于您的代码引用了参数device
,因此编译器为访问此参数而发出的代码不起作用,最终会访问内存中不可预测的值。最可能的一种可能性是最终访问调用它的函数的第一个参数,这就是为什么它似乎不时起作用的原因。但是,你不能依赖于此。
你应该在程序集中完全编写这样的函数。如果你想要它,你仍然需要连接64位代码。
答案 1 :(得分:0)
从NULL对象调用它是未定义的行为。未定义的行为包括“我写的钩子有时会收到NULL”。无论你在做什么计划,显然只是有些烦恼。或者你的钩子被窃听。