文章转载来源:http://www.moguizuofang.com/bbs/thread-31432-1-1.html
原创公布了 hook方法,但没使用方法, 主流射击游戏通用,此代码仅供学习研究,游戏公司尽早修复漏洞
#include "stdafx.h"
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
bool bCompare(CONST BYTE *pData, CONST BYTE *bMask, CONST CHAR *szMask)
{
for (; *szMask; ++szMask, ++pData, ++bMask)
if (*szMask == 'x' && *pData != *bMask)
return false;
return (*szMask) == NULL;
}
DWORD FindPattern(DWORD dwAddress, DWORD dwLen, BYTE* bMask, char* szMask)
{
for (DWORD i = 0; i < dwLen; i++)
if (bCompare((BYTE *)(dwAddress + i), bMask, szMask))
return (DWORD)(dwAddress + i);
return 0;
}
void __cdecl nReset(void)
{
_asm pushad
_asm popad
}
static DWORD PresentRetAddr;
__declspec(naked) DWORD __stdcall Present_Return(LPDIRECT3DDEVICE9 pDevice, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion)
{
__asm
{
MOV EDI, EDI
PUSH EBP
MOV EBP, ESP
jmp PresentRetAddr
}
}
static LPDIRECT3DDEVICE9 pDevice;
LPD3DXFONT pFont = 0;
#define TextRed D3DCOLOR_ARGB(255,255,0,0)
void WriteText(LPD3DXFONT g_pFont, INT x, INT y, D3DCOLOR Color, WCHAR *String)
{
RECT Rect;
SetRect(&Rect, x, y, x, y);
g_pFont->DrawText(0, String, -1, &Rect, DT_LEFT | DT_NOCLIP, Color);
}
//这个函数用于取当前的指针,或许有更好的办法......
HRESULT WINAPI Present_Detour(LPDIRECT3DDEVICE9 Device, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion)
{
pDevice = Device; //这行代码执行后就可以恢复这个函数的钩子, 避免被检测//恢复的代码就自己写吧
return Present_Return(Device, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
}
D3DVIEWPORT9 VPort;
DWORD SCenterX, SCenterY;
WCHAR Msg[256];
void __cdecl nEndScene(void)
{
static LPDIRECT3DDEVICE9 dwpDevice;
static DWORD dwEBP=0,offset=0;
__asm pushad
__asm MOV dwEBP, EBP
if (pDevice&&!offset)
{//遍历堆栈,取设备当前设备指针
for (int i = 0; i < 1024; i++)
{
if (*(DWORD*)(dwEBP + i) == (DWORD)pDevice)
{
offset = i;
break;
}
}
}
dwpDevice = *(LPDIRECT3DDEVICE9*)(dwEBP + offset);//取出指针
if (offset&&dwpDevice)
{//这个判断防止空指针,避免崩溃
/*
以下就可以进行菜单绘制等操作
*/
static bool dwIPfos = 0;
if (pFont)
{
pFont->Release();
pFont = NULL;
dwIPfos = false;
}
if (!dwIPfos)
{
D3DXCreateFont(pDevice, 15, 0, 800, 1, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial", &pFont);
dwIPfos = true;
}
WriteText(pFont, 150, 150, TextRed, L"德玛西亚");
dwpDevice->GetViewport(&VPort);
SCenterX = (float)VPort.Width / 2;
SCenterY = (float)VPort.Height / 2;
D3DRECT rec01 = { SCenterX - 2, SCenterY, SCenterX + 3, SCenterY + 1 };
D3DRECT rec02 = { SCenterX, SCenterY - 2, SCenterX + 1, SCenterY + 3 };
dwpDevice->Clear(1, &rec01, D3DCLEAR_TARGET, TextRed, 0, 0);
dwpDevice->Clear(1, &rec02, D3DCLEAR_TARGET, TextRed, 0, 0);
}
__asm popad
}
void __cdecl nDrawIndexedPrimitive(void)
{
static LPDIRECT3DDEVICE9 dwpDevice;
static DWORD dwEBP = 0, offset = 0;
__asm pushad
__asm MOV dwEBP, EBP
if (pDevice&&!offset)
{
for (int i = 0; i < 1024; i++)
{//遍历堆栈,取设备当前设备指针
if (*(DWORD*)(dwEBP + i) == (DWORD)pDevice)
{
offset = i;
break;//取到就跳出
}
}
}
dwpDevice = *(LPDIRECT3DDEVICE9*)(dwEBP + offset);//取出指针
if (offset&&dwpDevice)
{//这个判断防止空指针,避免崩溃
LPDIRECT3DVERTEXBUFFER9 Stream = NULL;
UINT Offset = 0;
UINT Stride = 0;
if (dwpDevice->GetStreamSource(0, &Stream, &Offset, &Stride) == D3D_OK)
Stream->Release();
if (Stride == 44 || Stride == 40){
pDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
}
}
_asm popad
}
static DWORD hHooking = NULL;
static DWORD hEndScene = NULL;
static DWORD hReset = NULL;
static DWORD hDrawIndexPrimtive = NULL;
typedef void (WINAPI * EnterCriticalSection_t) (LPCRITICAL_SECTION lpCriticalSection);
EnterCriticalSection_t pEnterCriticalSection;
void WINAPI nEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
_asm
{
MOV EAX, [EBP + 0x4]
MOV hHooking, EAX
}
// EndScene
if (hHooking == hEndScene)
{
__asm call[nEndScene]
}
//Reset
if (hHooking == hReset)
{
__asm call[nReset]
}
// DIP
if (hHooking == hDrawIndexPrimtive)
{
__asm call[nDrawIndexedPrimitive];
}
return pEnterCriticalSection(lpCriticalSection);
}
void* DetourCreate(BYTE *src, CONST BYTE *dst, CONST INT len)
{
BYTE *jmp = (BYTE*)malloc(len + 5);
DWORD dwback;
VirtualProtect(src, len, PAGE_READWRITE, &dwback);
memcpy(jmp, src, len); jmp += len;
jmp[0] = 0xE9;
*(DWORD*)(jmp + 1) = (DWORD)(src + len - jmp) - 5;
src[0] = 0xE9;
*(DWORD*)(src + 1) = (DWORD)(dst - src) - 5;
//VirtualProtect(src, len, dwback, &dwback);
return (jmp - len);
}
void InitDevice(void)
{
LPDIRECT3D9 pD3d9 = NULL;
DWORD oldflag;
LPDIRECT3DDEVICE9 pD3DDevice = NULL;
pD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
if (pD3d9 == NULL)
{
MessageBox(NULL, L"[ERROR] Direct3DCreate9 失败", L" Error", MB_ICONERROR | MB_ICONSTOP);
return;
}
D3DPRESENT_PARAMETERS pPresentParms;
ZeroMemory(&pPresentParms, sizeof(pPresentParms));
pPresentParms.Windowed = TRUE;
pPresentParms.BackBufferFormat = D3DFMT_UNKNOWN;
pPresentParms.SwapEffect = D3DSWAPEFFECT_DISCARD;
if (FAILED(pD3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow(), D3DCREATE_SOFTWARE_VERTEXPROCESSING, &pPresentParms, &pD3DDevice)))
{
MessageBox(NULL, L"[ERROR] CreateDevice Failed", L"Fatal Error", MB_ICONERROR | MB_ICONSTOP);
return;
}
DWORD * dwTable = (DWORD*)pD3DDevice;
dwTable = (DWORD*)dwTable[0];
PresentRetAddr = dwTable[17] + 5;
DetourCreate((PBYTE)dwTable[17], (PBYTE)&Present_Detour, 5);
}
void WINAPI Start()
{
//
DWORD hD3D, hCriticalSection;
do
{
hD3D = (DWORD)GetModuleHandle(L"d3d9.dll");
Sleep(100);
} while (!hD3D);
hCriticalSection = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0xffffff, (PBYTE)"\x74\x07\x00\xFF\x15\x00\x00\x00\x00\x8D\x00\x00", "xx?xx????x??")+5;
hCriticalSection =*(DWORD*)hCriticalSection;
if (!hCriticalSection)
{
MessageBox(NULL, L"Error Code (0)", L"Error", MB_ICONERROR);
exit(1);
}
//if (!hReset)
// hReset = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0xffffff, (PBYTE)"\xFF\x15\x00\x00\x00\x00\x3B\x43\x20\x74\x1B\x8B\x46\x18\x85\xC0\x74\x07\x56", "xx????xxxxxxxxxxxxx");// Win XP
//if (!hReset)
hReset = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0xffffff, (PBYTE)"\x57\xFF\x15\x00\x00\x00\x00\x8B\x45\x0C\x33\xF6\x39\x70\x20", "xxx????xxxxxxxx")+7;// Vista - Win7
if (!hReset)
hReset = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0xffffff, (PBYTE)"\x33\xC9\x39\x4F\x20\x75\x79\x8D\x44\x24\x38\x89\x44\x24\x1C\x32\xC0\x8B\xDE", "xxxxxxxxxxxxxxxxxxx");// Win 8.0
if (!hReset)
hReset = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0xffffff, (PBYTE)"\x8B\xCE\xE8\x00\x00\x00\x00\x8B\x4E\x0C\x48\xF7\xD8", "xxx????xxxxxx");// Win 8.1
if (!hReset)
{
MessageBox(NULL, L"Error Code (1)", L"Error", MB_ICONERROR);
exit(1);
}
// MessageBox(0, L"This", 0, 0);
//return;
//if (!hEndScene)
//hEndScene = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0xffffff, (PBYTE)"\x57\xFF\x15\x00\x00\x00\x00\xF6\x46\x00\x00\x89\x5D\xFC\x75\x0E\x8B\x86\x00\x00\x00\x00\xA8\x01\xC6\x45\x00\x00\x75\x24", "xxx????xx??xxxxxxx????xxxx??xx")+7; // Win XP
//if (!hEndScene)
hEndScene = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0xffffff, (PBYTE)"\x57\xFF\x15\x00\x00\x00\x00\xE9\x00\x00\x00\x00\x39\x5F\x18\x74\x07\x57\xFF\x15\x00\x00\x00\x00\xB8\x00\x00\x00\x00\x8B\x4D\xF4\x64\x89\x0D\x00\x00\x00\x00\x59\x5F\x5E\x5B\x8B\xE5\x5D\xC2\x04\x00\x68\xAD\x06\x00\x00", "xxx????x????xxxxxxxx????x????xxxxxx????xxxxxxxxxxxxx??")+7; // Vista Win7
if (!hEndScene)
hEndScene = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0xffffff, (PBYTE)"\x33\xC0\xE8\x00\x00\x00\x00\xC2\x04\x00\x8B\xDF\xEB\x8E\x53\xFF\x15\x00\x00\x00\x00\xEB\x90", "xxx????xxxxxxxxxx????xx")+21;// Win8 8.0 + 8.1
if (!hEndScene)
{
MessageBox(NULL, L"Error Code (2)", L"Error", MB_ICONERROR);
exit(1);
}
//if (!hDrawIndexPrimtive)
//hDrawIndexPrimtive = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0xffffff, (PBYTE)"\x53\xFF\x15\x00\x00\x00\x00\xF6\x46\x00\x00\x89\x7D\xFC\x74\x24\x39\x7B\x18\x74\x07\x53\xFF\x15\x00\x00\x00\x00\xB8\x00\x00\x00\x00\x8B\x4D\xF4\x64\x89\x0D\x00\x00\x00\x00\x5F\x5E\x5B\x8B\xE5\x5D\xC2\x1C\x00", "xxx????xx??xxxxxxxxxxxxx????x????xxxxxx????xxxxxxxxx")+7;// Win XP
//if (!hDrawIndexPrimtive)
hDrawIndexPrimtive = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0xffffff, (PBYTE)"\x56\xFF\x15\x00\x00\x00\x00\xE9\x00\x00\x00\x00\x39\x5E\x18\x74\x07\x56\xFF\x15\x00\x00\x00\x00\xB8\x00\x00\x00\x00\x8B\x4D\xF4\x64\x89\x0D\x00\x00\x00\x00\x59\x5F\x5E\x5B\x8B\xE5\x5D\xC2\x1C\x00\x39\x9E\x00\x00\x00\x00", "xxx????x????xxxxxxxx????x????xxxxxx????xxxxxxxxxxxx????")+7;// Vista - Win7
if (!hDrawIndexPrimtive)
hDrawIndexPrimtive = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0xffffff, (PBYTE)"\xE9\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\xE9\x00\x00\x00\x00\xC7\x45\x00\x00\x00\x00\x00\x8D\x4D\x00\xE8\x00\x00\x00\x00\xB8\x00\x00\x00\x00\xE9\x00\x00\x00\x00\x83\xBA\x00\x00\x00\x00\x00\x74\x00", "x?????x?????x????xx?????xx?x????x????x????xx?????x?")+12; // Win8 8.0 + 8.1
if (!hDrawIndexPrimtive)
{
MessageBox(NULL, L"Error Code (3)", L"Error", MB_ICONERROR);
exit(1);
}
if (hReset && hEndScene && hDrawIndexPrimtive)
{
DWORD dwBack;
VirtualProtect((void*)(hCriticalSection), 4, PAGE_EXECUTE_READWRITE, &dwBack);
pEnterCriticalSection = (EnterCriticalSection_t)*(DWORD*)(hCriticalSection);
*(DWORD*)(hCriticalSection) = (DWORD)nEnterCriticalSection;
VirtualProtect((void*)(hCriticalSection), 4, dwBack, &dwBack);
InitDevice();
return ;
}
return ;
}
BOOL WINAPI DllMain(HMODULE hDll, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Start, NULL, NULL, NULL);
}
return TRUE;
}