Hook DirectX 9

kick

Предвестник
Administrator
За веру и верность форуму
Отец-основатель
Сообщения
7 048
Розыгрыши
21
Решения
1
Репутация
5 874
Реакции
6 597
Баллы
2 688
Код:
#ifndef _Hook_H_
#define _Hook_H_

#pragma once
#ifdef _WIN64
typedef unsigned __int64 UPARAM;
#else
typedef unsigned long UPARAM;
#endif
class CreateHook
{
    BYTE data[14];
    FARPROC func;
    FARPROC hookFunc;
    bool bHooked;
    bool b64bitJump;
    DWORD oldProtect;
public:
    inline CreateHook() : bHooked(false), func(NULL), hookFunc(NULL), b64bitJump(false), oldProtect(0)
    {
    }

    inline ~CreateHook()
    {
        if (bHooked)
            Unhook();

        if (func && oldProtect)
            VirtualProtect((LPVOID)func, 14, oldProtect, &oldProtect);
    }

    inline bool Hook(FARPROC funcIn, FARPROC hookFuncIn)
    {
        if (bHooked)
        {
            if (funcIn == func)
            {
                if (hookFunc != hookFuncIn)
                {
                    hookFunc = hookFuncIn;
                    Rehook();
                    return true;
                }
            }

            Unhook();
        }

        func = funcIn;
        hookFunc = hookFuncIn;

        if (!VirtualProtect((LPVOID)func, 14, PAGE_EXECUTE_READWRITE, &oldProtect))
            return false;

        memcpy(data, (const void*)func, 14);

        return true;
    }

    inline void Rehook(bool bForce = false)
    {
        if ((!bForce && bHooked) || !func)
            return;

        UPARAM startAddr = UPARAM(func);
        UPARAM targetAddr = UPARAM(hookFunc);
        UPARAM offset = targetAddr - (startAddr + 5);

#ifdef _WIN64
        b64bitJump = (offset > 0x7fff0000);

        if (b64bitJump)
        {
            LPBYTE addrData = (LPBYTE)func;
            *(addrData++) = 0xFF;
            *(addrData++) = 0x25;
            *((LPDWORD)(addrData)) = 0;
            *((unsigned __int64*)(addrData + 4)) = targetAddr;
        }
        else
#endif
        {
            LPBYTE addrData = (LPBYTE)func;
            *addrData = 0xE9;
            *(DWORD*)(addrData + 1) = DWORD(offset);
        }

        bHooked = true;
    }

    inline void Unhook()
    {
        if (!bHooked || !func)
            return;

        UINT count = b64bitJump ? 14 : 5;

        memcpy((void*)func, data, count);

        bHooked = false;
    }
};

#endif
Код:
CreateHook chPresent;
typedef HRESULT(WINAPI*D3D9CREATEEXPROC)(UINT, IDirect3D9Ex**);
HRESULT WINAPI SMPresent(LPDIRECT3DDEVICE9 SMGamepDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion)
{
    chPresent.Unhook();
    if (!Create)
    {
        D3DXCreateLine(SMGamepDevice, &pLine);
        D3DXCreateFontW(SMGamepDevice, 13, 0, FW_BOLD, 1, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN, L"Tahoma", &pFont);
        Create = true;
    }
    if (!pFont || !pLine)
    {
        pLine->OnLostDevice();
        pFont->OnLostDevice();
    }
    else
    {

        pLine->OnLostDevice();
        pLine->OnResetDevice();
        pFont->OnLostDevice();
        pFont->OnLostDevice();
    }

    HRESULT r_Present = SMGamepDevice->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
    chPresent.Rehook();
    return r_Present;
}

bool Interace()
{
    HMODULE hD3D9 = NULL;
    bool bResult = false;
    char szPath[256];
    SHGetFolderPathA(NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT, szPath);
    strcat_s(szPath, "\\d3d9.dll");

    if (hD3D9 = GetModuleHandleA(szPath))
    {
        D3D9CREATEEXPROC CreateEx = (D3D9CREATEEXPROC)GetProcAddress(hD3D9, "Direct3DCreate9Ex");
        if (CreateEx)
        {
            HRESULT hr = D3D_OK;
            LPDIRECT3D9EX d3d9ex = nullptr;
            if (SUCCEEDED(hr = CreateEx(D3D_SDK_VERSION, &d3d9ex)))
            {
                D3DPRESENT_PARAMETERS dp;
                ZeroMemory(&dp, sizeof(dp));
                dp.Windowed = 1;
                dp.SwapEffect = D3DSWAPEFFECT_FLIP;
                dp.BackBufferFormat = D3DFMT_A8R8G8B8;
                dp.BackBufferCount = 1;
                dp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

                IDirect3DDevice9Ex *mDevice = nullptr;
                if (SUCCEEDED(hr = d3d9ex->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, &dp, NULL, &mDevice)))
                {
                    bResult = true;
                    UPARAM * vtbl = *(UPARAM**)mDevice;
                    chPresent.Hook((FARPROC)*(vtbl + 17), (FARPROC)SMPresent);
                    mDevice->Release();
                    chPresent.Rehook();
                }
                d3d9ex->Release();
            }
        }
    }
    return bResult;
}
 

Назад
Сверху Снизу