IDirect3DDevice9 :: EndScene钩子有时在参数IDirect3DDevice9中获取NULL [英] IDirect3DDevice9::EndScene hook sometimes get NULL in the paramter IDirect3DDevice9

查看:491
本文介绍了IDirect3DDevice9 :: EndScene钩子有时在参数IDirect3DDevice9中获取NULL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为函数IDirect3DDevice9 :: EndScene创建了一个蹦床钩。如果EndScene函数跳转到这个编解码器,我修改了开始:

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

__asm
{
PUSH 0x14
MOV EAX,0x718E6478
JMP地址
}
}
<问题是有时候 device 是NULL,为什么呢?如果我添加一个小条件像这样:

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

一切正常,无错误。



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

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



你应该在程序集中完全编写一个这样的函数。你将需要,如果你想要你想挂钩64位代码。


I made a trampoline hook for the function IDirect3DDevice9::EndScene. The codecave I modified the start if the EndScene function to jump to is this:

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

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

The problem is that sometimes device is NULL, why is that? if I add a small condition like this:

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

Everything works as intended with no errors.

What possibly can be the reason for this function to receive device as NULL? This is a member function of the object IDirect3DDevice9, it shouldn't be possible to call it like this EndScene(NULL) because it always called from it's object (e.g pDevice->EndScene()).

解决方案

Using __declspec(naked) tells the compiler not to emit a prologue or an epilogue for the function. In the prologue the compiler would normally emit the instructions necessary for it to be able later access arguments to the function that are passed on the stack. Since your code references the argument device the code the compiler emits to access this argument doesn't work and ends up accessing an unpredictable value in memory. One of the more likely possibilities is that ends up accessing the the first argument of the function that called it, and this is why it may appear to work from time to time. However you can't depend on this.

You should really write a function like this entirely in assembly. You're going to need to if you want it you want to hook 64-bit code anyways.

这篇关于IDirect3DDevice9 :: EndScene钩子有时在参数IDirect3DDevice9中获取NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆