Hook DirectX 在War3 魔兽争霸界面写屏

时间:2021-08-09 19:58:29

	
       由于经常玩Dota,11平台出来以后,发现War3界面上有一行字,“游戏正在进入....”。就想到了它的实现方式,HOOKAPI。《Windows核心编程》中有关于hookapi的描述, 以前都是——先改写原函数的前5个字节,跳转到自己的函数,还原原函数,调用,结束。前段时间看到微软的这个Detours库,实现更方便,多线程时更安全。

Hook DirectX 在War3 魔兽争霸界面写屏

   Detours库,可以在微软官方下载,完全免费。

   现在来实现war3写屏。

   War3使用了directx 8的库。Hook的第一个函数是Direct3DCreate8(UINT SDKVersion); 我们先下载DirectX 8的SDK。

   步骤,先新建一个Win32 DLL动态链接库工程。包含头文件

#include "detours.h" //微软的hook库#include <d3d8.h> //directx 必须包含的头文件#include <d3dx8.h>//directx 必须包含的头文件#pragma comment(lib,"detoured.lib") //微软的hook链接库#pragma comment(lib,"detours.lib") //微软的hook链接库#pragma comment(lib,"d3d8.lib")//directx链接库#pragma comment(lib,"d3dx8.lib")//directx链接库


先获取Direct3DCreate8函数的真实地址。有多种方法,下面方法是最简单的。

</pre><pre name="code" class="cpp">static IDirect3D8 * (WINAPI * TrueDirect3DCreate8)(UINT SDKVersion) = Direct3DCreate8;
使用Detours来Hook函数异常简单

		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourAttach(&(PVOID&)TrueDirect3DCreate8,myDirect3DCreate8);
		DetourTransactionCommit();
代码不过多解释,Detours例子上直接改的。重要的是
DetourAttach(&(PVOID&)TrueDirect3DCreate8,myDirect3DCreate8);
其它语句是它帮你处理事务,这个函数把 Direct3DCreate8替换成我们的,myDirect3DCreate8 但是 TrueDirect3DCreate8的值并未改变,依然保留

了 Direct3DCreate8的函数的真实地址。在我们的myDirect3DCreate8函数中,不应调用原函数,而是p3d = TrueDirect3DCreate8(SDKVersion);。

因为原函数地址已经被我们改变。

我们在新函数中继续hook这个CreateDevice函数如获取画图指针。方法同上

		pCreateDevice=(void*)*(DWORD*)(*(DWORD*)p3d + 0x3C);//获得IDirect3D8::CreateDevice的地址指针 

		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourAttach(&(PVOID&)pCreateDevice,MyCreateDevice);
		DetourTransactionCommit();

请注意这个函数地址的获取方式,我是在调试CreateDevice这个函数是获得的 0x3C这个偏移。

Hook DirectX 在War3 魔兽争霸界面写屏

hook后在我们的函数中继续hook EndSense函数,并在函数中画出我们自己的文字。

pEndSense=(void*)*(DWORD*)(*(DWORD*)lpp3d + 0x8C);

DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pEndSense,MyEndSense);
DetourTransactionCommit();

写屏

d3df->DrawText(
FPSString, 
-1, // size of string or -1 indicates null terminating string
&rect, // rectangle text is to be formatted to in windows coords
        DT_LEFT, // draw in the top left corner of the viewport
0xff00ff00);      // black text

结束。