IDirect3DDevice9::EndScene hook sometimes get NULL

2019-09-17 07:00发布

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()).

2条回答
女痞
2楼-- · 2019-09-17 07:05

Calling it from a NULL object is undefined behaviour. Undefined behaviour includes "The hook I wrote sometimes recieves NULL". Whatever progam you're hooking is clearly just somewhat bugged. Or your hook is bugged.

查看更多
Bombasti
3楼-- · 2019-09-17 07:17

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.

查看更多
登录 后发表回答