Source Code D3D9 EndScene Hook Template Using Dummy Device

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,061
78,998
2,370
How long you been coding/hacking?
5 years
This is a simple D3D9 EndScene Hook Template, you can hit compile and inject it into any Direct3D9 game and it will show a red box on the screen.

Credits to @Broihon @0xDEC0DE @Solaire their code was instrumental in creating this little template.

This template gets the D3D9 Device Pointer and EndScene address using:
https://guidedhacking.com/threads/get-direct3d9-and-direct3d11-devices-dummy-device-method.11867/

Then we do a Trampoline Hook after getting the address of EndScene from the vTable. This is not VMT hooking.

Here is what main.cpp looks like:
C++:
bool bInit = false;
tEndScene oEndScene = nullptr;
LPDIRECT3DDEVICE9 pD3DDevice = nullptr;
void* d3d9Device[119];

HRESULT APIENTRY hkEndScene(LPDIRECT3DDEVICE9 pDevice)
{
    if (bInit == false)
    {
        pD3DDevice = pDevice;
        bInit = true;
    }

    //draw stuff here like so:
    DrawFilledRect(200, 200, 200, 200, D3DCOLOR_ARGB(255, 255, 0, 0), pDevice);

    return oEndScene(pDevice);
}

DWORD WINAPI Init(HMODULE hModule)
{
    if (GetD3D9Device(d3d9Device, sizeof(d3d9Device)))
    {
        oEndScene = (tEndScene)TrampHook((char*)d3d9Device[42], (char*)hkEndScene, 7);
    }
    return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)Init, hModule, 0, nullptr));
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
If you know nothing about Direct3D, do this guide:
https://guidedhacking.com/threads/how-to-get-started-with-directx-9-make-your-menu-hacks.10402

Stay tuned for a more thorough release and a bone ESP using this source code also.
 

Attachments

StraightArrow

Dank Tier Donator
Aug 28, 2020
3
202
0
Hi,
Thanks for this code. It's been useful. I was trying to test some other functions with this. Namely, I need Present to be hooked. It does not seem to work. I "printed out" the address that present points to (the vtable for present is this btw d3d9Device[17]). And I got a relative jmp to another jmp to the overlayrenderer. I've tried breakpointing in multiple spots in that chain and have had no hits. By comparison, I tried this with begin scene and it worked just fine and looked similar to end scene. I looked at the pix data for my game and I see Present is a part of IDirect3dswapchain9 instead of idirect3ddevice9. Could this be the culprit? I also read something about d3d9 using the COM-Model so functions are not as cut and dry. I was thinking of pattern scanning if this dummydevice/vtable method doesn't work. Is that a better route?
 

StraightArrow

Dank Tier Donator
Aug 28, 2020
3
202
0
Hi @Rake, thanks for the reply. I wanted to try to figure it out before replying again, and I got really close, but now I'm stuck. I think D3D9 works differently and we don't have IDXGISwapChain->Present. It's more like IDirect3DSwapChain9:: Present. So what I did was, I kept the d3d Dummy device active and executed this
C++:
IDirect3DSwapChain9* pDummySwapchain;
    HRESULT dummySwapCreated = d3ddevice->CreateAdditionalSwapChain(d3dpresentparam, &pDummySwapchain);
    //swapchain[3] is probably what present we need;
    memcpy(pSwapchainTable, *reinterpret_cast<void***>(pDummySwapchain), Size_Swapchain);
So basically creating an additional swapchain object and copying its vtable. Encouragingly, breakpoints were hitting when I breakpointed calls with this vtable, so I'm like 80% sure I'm hitting the real-time present call.
BUT.
For some reason copying instructions to the gateway has created issues. Basically, the first few bytes of Present are a jmp instruction, then another jmp instruction (instead of easy stuff with begin scene/end scene like mov push etc). When I copy that jmp instruction +address to my gateway I get undefined behavior. It's weird because the bytes are EXACTLY the same as Present's first bytes (e9 xyz), but when I check with cheat engine the final, actual jmp location will be random every time. I was thinking, does this have something to do with jmping between such different address spaces e.g. my dll vs d3d9? Is the memcpy having undefined behavior? Thanks for all your help thus far.
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods