D3D9挂钩(EndScene + DrawIndexedPrimitive) [英] D3D9 Hooking (EndScene + DrawIndexedPrimitive)

查看:71
本文介绍了D3D9挂钩(EndScene + DrawIndexedPrimitive)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

众所周知,我对DirectX感到非常厌倦.我已经尝试了很多次,无论做什么,我似乎都无法工作.我搜寻了网并研究了钩子;我将一些代码组合在一起,将自己的钩子拼凑在一起.我弄平了窃的钩子,以查明它们是如何工作的.我什至从头开始写了一些.但是,我似乎无法工作.我正在尝试为CrossFire创建一个简单的D3D mod菜单.我尝试过的:

As none of you already know, I am quite fed up with DirectX at the moment. I have tried and tried, and no matter what I do, I cannot seem to get any hooks to work. I have scoured the web and studied hooks; I have combined bits of code together to scrap together my own hook; I have flat out plagiarized hooks to find out how they worked; I have even written a few from scratch. However, I cannot seem to get one to work. I'm trying to make a simple D3D mod-menu for CrossFire. What I have tried:

  1. 通过VT​​able进行挂接[获取设备指针时遇到问题]
  2. 通过图案+遮罩扫描等进行钩挂,并绕道而行[不确定如何获得图案,并且找不到能在win10上可靠工作的图案]
  3. 创建虚拟设备以获取地址等,[导致立即关闭游戏(检测到)]

无论我做什么,一旦编程到绕行的EndScene中,要么关闭,崩溃,要么什么都没发生,菜单要么平坦,要么拒绝显示.

No matter what I do, the menu either flat out refuses to appear once programmed into the detoured EndScene, I get shut-down, I crash, or nothing happens.

是否有可以从中学习并带有示例代码的入门材料?

Are there any good starter materials with sample code that I can learn from, as well as get this off the ground?

我已经对hack菜单进行了编程,对变量进行了设置,对功能进行了编程,DllMain,相关性,您都将其命名.我需要做的只是使钩子正常工作-我唯一要工作的钩子有一个奇怪的错误,即在EndScene&中绘制文本.DrawIndexedPrimitive中的墙壁破解无法正常工作.

I already have the hack menu programmed, the variables set, the features programmed, the DllMain, the dependencies, you name it. All I need is to get a proper hook working - the only one I got to work had a weird bug where text drawing in EndScene & wall-hack in DrawIndexedPrimitive didn't work.

推荐答案

这是一个SO答案的大量代码,但是我们开始吧.

This is a large amount of code for a SO answer but here we go.

  • 获取正确的窗口
  • 创建虚拟设备
  • 从vtable获取endcene的地址
  • 做一个标准的x86蹦床挂钩
  • 内部挂钩可以执行您需要做的初始化工作
  • 获取正确的设备指针的副本
  • 画东西
  • 使用正确的设备指针调用原始功能
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>

bool Hook(char* src, char* dst, int len)
{
    if (len < 5) return false;

    DWORD curProtection;

    VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &curProtection);

    memset(src, 0x90, len);

    uintptr_t relativeAddress = (uintptr_t)(dst - src - 5);

    *src = (char)0xE9;
    *(uintptr_t*)(src + 1) = (uintptr_t)relativeAddress;

    DWORD temp;
    VirtualProtect(src, len, curProtection, &temp);

    return true;
}

char* TrampHook(char* src, char* dst, unsigned int len)
{
    if (len < 5) return 0;

    // Create the gateway (len + 5 for the overwritten bytes + the jmp)
    char* gateway = (char*)VirtualAlloc(0, len + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

    // Put the bytes that will be overwritten in the gateway
    memcpy(gateway, src, len);

    // Get the gateway to destination addy
    uintptr_t gateJmpAddy = (uintptr_t)(src - gateway - 5);

    // Add the jmp opcode to the end of the gateway
    *(gateway + len) = (char)0xE9;

    // Add the address to the jmp
    *(uintptr_t*)(gateway + len + 1) = gateJmpAddy;

    // Place the hook at the destination
    if (Hook(src, dst, len))
    {
        return gateway;
    }
    else return nullptr;
}


typedef HRESULT(APIENTRY* tEndScene)(LPDIRECT3DDEVICE9 pDevice);

static HWND window;


BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam)
{
    DWORD wndProcId;
    GetWindowThreadProcessId(handle, &wndProcId);

    if (GetCurrentProcessId() != wndProcId)
        return TRUE; // skip to next window

    window = handle;
    return FALSE; // window found abort search
}

HWND GetProcessWindow()
{
    window = NULL;
    EnumWindows(EnumWindowsCallback, NULL);
    return window;
}

bool GetD3D9Device(void** pTable, size_t Size)
{
    if (!pTable)
        return false;

    IDirect3D9* pD3D = Direct3DCreate9(D3D_SDK_VERSION);

    if (!pD3D)
        return false;

    IDirect3DDevice9* pDummyDevice = NULL;

    // options to create dummy device
    D3DPRESENT_PARAMETERS d3dpp = {};
    d3dpp.Windowed = false;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = GetProcessWindow();

    HRESULT dummyDeviceCreated = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDummyDevice);

    if (dummyDeviceCreated != S_OK)
    {
        // may fail in windowed fullscreen mode, trying again with windowed mode
        d3dpp.Windowed = !d3dpp.Windowed;

        dummyDeviceCreated = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDummyDevice);

        if (dummyDeviceCreated != S_OK)
        {
            pD3D->Release();
            return false;
        }
    }

    memcpy(pTable, *reinterpret_cast<void***>(pDummyDevice), Size);

    pDummyDevice->Release();
    pD3D->Release();
    return true;
}

void DrawFilledRect(int x, int y, int w, int h, D3DCOLOR color, IDirect3DDevice9* dev)
{
    D3DRECT BarRect = { x, y, x + w, y + h };
    dev->Clear(1, &BarRect, D3DCLEAR_TARGET | D3DCLEAR_TARGET, color, 0, 0);
}


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;
}

对我来说是Broihon,Solaire&此准系统d3d9结束场景钩的0xDEC0DE

Credits to me, Broihon, Solaire & 0xDEC0DE for this barebones d3d9 endscene hook

这篇关于D3D9挂钩(EndScene + DrawIndexedPrimitive)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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