顾锦歌——发现生活的美!

文章 分类 标签
23 11 0

公告

此处是站点公告

D3D函数hook

顾锦歌 2022-02-04 324 0条评论 C/C++

首页 / 正文

这个方法不需要在主线程运行前注入,CE和直播软件OBS也是用了这个方法,所以推荐使用

理论上同一个类的虚函数地址是一样的,所以我们可以自己创建一个IDirect3DDevice9,然后就能获取虚函数地址了
经测试不同IDirect3DDevice9的虚函数表指针不一样,所以只能用inline hook,不能用虚函数表hook

 void* endSceneAddr = NULL;
BYTE endSceneOldCode[sizeof(JmpCode)];
 
 
HRESULT STDMETHODCALLTYPE MyEndScene(IDirect3DDevice9* thiz)
{
    // 这里放我们的绘制代码
 
    unhook(endSceneAddr, endSceneOldCode);
    HRESULT hr = thiz->EndScene();
    hook(endSceneAddr, MyEndScene, endSceneOldCode);
    return hr;
}
 
DWORD WINAPI initHookThread(LPVOID dllMainThread)
{
    // 等待DllMain(LoadLibrary线程)结束
    WaitForSingleObject(dllMainThread, INFINITE);
    CloseHandle(dllMainThread);
 
    // 创建一个窗口用于初始化D3D
 
    WNDCLASSEX wc = {};
    wc.cbSize = sizeof(wc);
    wc.style = CS_OWNDC;
    wc.hInstance = GetModuleHandle(NULL);
    wc.lpfnWndProc = DefWindowProc;
    wc.lpszClassName = _T("DummyWindow");
    if (RegisterClassEx(&wc) == 0)
    {
        MessageBox(NULL, _T("注册窗口类失败"), _T(""), MB_OK);
        return 0;
    }
 
    HWND hwnd = CreateWindowEx(0, wc.lpszClassName, _T(""), WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, NULL, NULL, wc.hInstance, NULL);
    if (hwnd == NULL)
    {
        MessageBox(NULL, _T("创建窗口失败"), _T(""), MB_OK);
        return 0;
    }
 
    // 初始化D3D
 
    IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
    if (d3d9 == NULL)
    {
        MessageBox(NULL, _T("创建D3D失败"), _T(""), MB_OK);
        DestroyWindow(hwnd);
        return 0;
    }
 
    D3DPRESENT_PARAMETERS pp = {};
    pp.Windowed = TRUE;
    pp.SwapEffect = D3DSWAPEFFECT_COPY;
 
    IDirect3DDevice9* device;
    if (FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, 
        D3DCREATE_SOFTWARE_VERTEXPROCESSING, &pp, &device)))
    {
        MessageBox(NULL, _T("创建设备失败"), _T(""), MB_OK);
        d3d9->Release();
        DestroyWindow(hwnd);
        return 0;
    }
 
    // hook EndScene
    endSceneAddr = (*(void***)device)[42]; // EndScene是IDirect3DDevice9第43个函数
    hook(endSceneAddr, MyEndScene, endSceneOldCode);
 
    // 释放
    d3d9->Release();
    device->Release();
    DestroyWindow(hwnd);
    return 0;
}
 
 
BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
    )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        // 取当前线程句柄
        HANDLE curThread;
        if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &curThread, SYNCHRONIZE, FALSE, 0))
            return FALSE;
        // DllMain中不能使用COM组件,所以要在另一个线程初始化
        CloseHandle(CreateThread(NULL, 0, initHookThread, curThread, 0, NULL));
        break;
 
    case DLL_PROCESS_DETACH:
        if (endSceneAddr != NULL)
            unhook(endSceneAddr, endSceneOldCode);
        break;
 
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

绘制文字
这部分就直接用D3D的API了,不懂的去看看D3D教程...

HRESULT STDMETHODCALLTYPE MyEndScene(IDirect3DDevice9* thiz)
{
    static RECT rect = { 0, 0, 200, 200 };
    g_font->DrawText(NULL, _T("Hello World"), -1, &rect, DT_TOP | DT_LEFT, D3DCOLOR_XRGB(255, 0, 0));
 
    return RealEndScene(thiz);
}
 
HRESULT STDMETHODCALLTYPE MyCreateDevice(IDirect3D9* thiz, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface)
{
    unhookVTable(g_d3d9, 16, RealCreateDevice);
    HRESULT res = RealCreateDevice(thiz, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
    g_device = *ppReturnedDeviceInterface;
 
    D3DXFONT_DESC d3dFont = {};
    d3dFont.Height = 25;
    d3dFont.Width = 12;
    d3dFont.Weight = 500;
    d3dFont.Italic = FALSE;
    d3dFont.CharSet = DEFAULT_CHARSET;
    wcscpy_s(d3dFont.FaceName, L"Times New Roman");
    D3DXCreateFontIndirect(g_device, &d3dFont, &g_font);
 
    // 测试中不知道为什么第一次调用DrawText后device的虚函数表会恢复,没办法只好在hook前调用一次
    static RECT rect = { 0, 0, 200, 200 };
    g_font->DrawText(NULL, _T("Hello World"), -1, &rect, DT_TOP | DT_LEFT, D3DCOLOR_XRGB(255, 0, 0));
 
    hookVTable(g_device, 42, MyEndScene, &RealEndScene); // EndScene是IDirect3DDevice9第43个函数
 
    return res;
}

评论(0)

当前没有评论,还不快来留下第一个脚印吧

热门文章

最新评论

  • Jacob Hankinson

    Your go-to source for leads. We can provide business to business and business to consumer leads, custom-tailored to your needs. CustomDatabases.org

  • Otilia Drechsler

    Hi, It is with sad regret to inform you TopDataList.com is shutting down. We are ceasing operations on TopDataList.com and have made our leads available at a $149 once off fee. Visit us on TopDataList.com Regards, Otilia

  • Ervin Quinn

    Hello, from CustomData.click we are a provider of unique databases that could help your business. Please visit us at CustomData.click to see if we can help you. Regards, Ervin

  • Keri Cardus

    Hello. It is with sad regret to inform you TopDataList.com is shutting down. We have made all our databases available for you for a once off fee. Visit us on TopDataList.com

  • Beth Steele

    ZippyLeads.org is running an easter special till the 18th of April. Get all the leads you need for your company with our easter special.

  • Johan Fourie

    Hello. My name is Johan Fourie and I am looking to sell DataList.biz. We are a data company that has been in the industry for 12 years. We do around $170k/year in revenue. 1) I am looking to sell 50% of the business for $5k. 2) It would be helpful if you are knowledgeable about the Data Business. 3) I am looking for someone that is willing to take over administration, support, client relations. 4) I will continue to do the marketing for new products. 5) You will accept all future income and pay me from it. Please contact me on WhatsApp +27 72 280 1952 or my personal email: johanfourieinc@gmail.com if you are interested in this and we can have a call. Regards, Johan Fourie

  • Pam Using

    Hi, I am interested in some of your products. Please give me a call on +1 304-873-4360

  • Typecho

    欢迎加入 Typecho 大家族

日历

2025年01月

   1234
567891011
12131415161718
19202122232425
262728293031 

标签云

文章目录

推荐关键字:

上一张 下一张