看了挺多资料的 感谢各个网友回答我之前 “十万个为什么”的问题才悟懂了一些皮毛
准备HOOK之前需要知道HOOK什么,比如 HOOK D3D9.dll 下的DrawIndexedPrimitive
第一步
我的环境vs2017  创建DLL 在源文件dllmain.cpp下面写代码
获取模块地址
//获取模块地址 原函数地址
ULONG_PTR onHookInit()
{
     
    HMODULE hModule = LoadLibraryA("D3D9.dll");  //加载模块 获得模块指针
    ULONG_PTR addr = (ULONG_PTR)hModule;
        //addr = (ULONG_PTR) GetProcAddress(hModule, "Direct3DCreate9");
    return addr+0x2B6B1;
     
}
用到API LoadLibraryA   //获取D3D.dll模块句柄   (在下文代码中)我注释哪行其实就已经得到了D3D的地址了不知道为什么不生效 所以换了一个方法,需要自己找到地址
怎么找地址? 自己创建一个D3D环境 因为我不会D3D编程 我就在Directx给的实例上面下载的
打开工程之后我在这里添加了一句 g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, 4, 0, 4) 并下了个断点
右键 查看返汇编
地址出来了 是   6647b6b1
在OD里面就很清楚了
现在找D3D9D的真实地址 找一个使用了D3D的程序  我用了PCHunter64工具查看到了d3d9.dll 的基地址 66450000
66450000 - 6647B6B1=2B6B1   (这里是十六进制计算的)
下面的代码的0x2B6B1 就是这样子得来的
我注释哪行其实就已经得到了D3D的地址了不知道为什么不生效
(windows7 地址都一样)
第二步
//开始HOOK
bool hookDrawIndexedPrimitive()
{
    ULONG_PTR addr = onHookInit();//把找到的地址传进来
    jmp = addr + 5;//其实我自己也不是很清楚网上的友仔都这样子说
    if (addr == 0)
    {
        MessageBoxA(NULL, "error", NULL, 0);
    }
    if (VirtualProtect((LPVOID)addr, 5, PAGE_EXECUTE_READWRITE, &oldProtect))
    {      
        DWORD value = (DWORD)My_DrawIndexedPrimitive - addr - 5;
        _asm {

            mov eax, addr//addr 模块地址
            mov byte ptr[eax], 0xE9
            add  eax, 1
            mov ebx,value
            mov dword ptr[eax], ebx
                }
        VirtualProtect((LPVOID)addr, 5, oldProtect, &oldProtect);
    }
}

jmp=addr+5  我到od里面看了一下应该是HOOK之后跳转到后面的push ecx吧

VirtualProtect((LPVOID)addr, 5, PAGE_EXECUTE_READWRITE, &oldProtect)
一个API VirtualProtect  让代码段可读可写 不懂的话网上找找资料吧 因为我也不懂!!!

内联汇编 直接做 “粘贴工程师” 吧  都一样的

第三步

//定制函数原型  这个内联汇编我也是抄的(虽然说是抄但内联汇编OD跟进去就知道怎么回事了)

__declspec(naked)HRESULT WINAPI or_DrawIndexedPrimitive(
    LPDIRECT3DDEVICE9 m_Device,
    D3DPRIMITIVETYPE type ,
    INT BaseVertexIndex,
    UINT MinIndex,
    UINT NumVertices,
    UINT StartIndex,
    UINT PrimitiveCount
) {
    _asm {
                mov edi,edi
                push ebp
                mov ebp,esp
                mov eax,jmp
                jmp eax

            }
};
第四步

//定制自己的函数

要hook DrawIndexeDprimitve   就要弄一个假的  DrawIndexeDprimitve  函数原型网上很多的 大括号{}里面的内容就是我们要实现的功能 这里面的知识点需要会一些D3D 因为我不会所以还是做 “粘贴工程师”

HRESULT WINAPI My_DrawIndexedPrimitive(
    LPDIRECT3DDEVICE9 m_Device,
    D3DPRIMITIVETYPE type,
    INT BaseVertexIndex,
    UINT MinIndex,
    UINT NumVertices,
    UINT StartIndex,
    UINT PrimitiveCount
)
{
    HRESULT result = S_OK;
    IDirect3DVertexBuffer9*PStremData = NULL;
    UINT iOffsetInBytes, Istride;
    m_Device->SetRenderState(D3DRS_ZENABLE, FALSE);
    result = or_DrawIndexedPrimitive(m_Device, type, BaseVertexIndex, MinIndex, NumVertices, StartIndex, PrimitiveCount);

    return result;
}

效果

Last modification:May 5, 2022
如果觉得我的文章对你有用,请随意赞赏