This is a hook on
IDirect3DSwapChain9::Present. From this hook you can draw menu, esp, ect. Anything done in endscene/beginscene/present should be able to be done from here yet on games that detect hooks on those 3 Swapchain Present is normally undetected. Xfire also hooks Swapchain Present in the battlefield series and maybe other game so if PB/another anti cheat detects this they will probably be detecting Xfire.
There is two different ways to get SC Presents address in the hook, number one is offset based. I got this offset by seeing where Xfire hooks Battlefield 2142 with
Hookshark. Number two finds SC Presents address but signature scanning it. The signature is the first 20 lines from SC Present. To get the device(for text drawing ect.) I use a discovery hook on endscene, once endscene is called the hook is removed hopefully before an AC sees it. Anyways lets start off with Main.h
Code:
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#include <detours.h>
#include <stdio.h>
#include <fstream>
#include <tlhelp32.h>
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
using namespace std;
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////End includes///////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
#define HookType 2 //1 use offset 2 uses scan
#define SCP "\x8B\xFF\x55\x8B\xEC\x83\xEC\x00\x53\x8B\x5D\x00\x8B\x43\x00\x85\xC0\x56\x74\x00\x8D\x70\x00\xEB\x00\x33\xF6\x8B\x46\x00\x85\xC0\x89\x75\x00\x89\x75\x00\xC7\x45\x00\x00\x00\x00\x00\x74\x00\x56"
#define SCPM "xxxxxxx?xxx?xx?xxxx?xx?x?xxxx?xxxx?xx?xx?????x?"
#define SCPoffset 0x39230
typedef HRESULT (WINAPI* TPresent)(CONST RECT*, CONST RECT*, HWND, CONST RGNDATA*, DWORD);
TPresent PPresent;
typedef HRESULT (WINAPI* TEndScene)(LPDIRECT3DDEVICE9);
TEndScene PEndScene;
HRESULT WINAPI HPresent(CONST RECT* Rect1, CONST RECT* Rect2, HWND hWnd, CONST RGNDATA* RGNDATA, DWORD Flags);
bool DrawMyText(int x, int y, D3DCOLOR Color, ID3DXFont *font, const char* fmt, ...);
DWORD FindPattern(DWORD dwAddress,DWORD dwLen,BYTE *bMask,char * szMask);
bool Match(const BYTE* pData, const BYTE* bMask, const char* szMask);
DWORD GetModuleSize(DWORD processID, char* DllName);
HRESULT WINAPI HEndScene(LPDIRECT3DDEVICE9 Device);
void __cdecl add_log (const char *fmt, ...);
DWORD Hook(LPVOID);
ofstream Log;
bool PresentCalled = false, EndSceneCalled = false;
LPDIRECT3DDEVICE9 pDevice = NULL;
ID3DXFont *MainFont = NULL;
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////End declares///////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
Main.cpp
Code:
#include "Main.h"
HRESULT WINAPI HPresent(CONST RECT* Rect1, CONST RECT* Rect2, HWND hWnd, CONST RGNDATA* RGNDATA, DWORD Flags) // Instead of calling the normal function our hooks make it call this
{
if(PresentCalled == false)
{
PresentCalled = true;
add_log("Present called!");
}
if(pDevice == NULL)
{
add_log("Device NULL");
return PPresent(Rect1, Rect2, hWnd, RGNDATA, Flags);
}
if(MainFont == NULL)
D3DXCreateFont(pDevice, 15, 0, FW_BOLD, 0, FALSE,DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Verdana", &MainFont);
DrawMyText( 50, 50, D3DCOLOR_XRGB(255,0,0),MainFont, "SgtMattBaker was here");
return PPresent(Rect1, Rect2, hWnd, RGNDATA, Flags);
}
HRESULT WINAPI HEndScene(LPDIRECT3DDEVICE9 Device)
{
__asm pushad;
pDevice = Device;
EndSceneCalled = true;
add_log("Endscene called, got device!");
__asm popad;
return PEndScene(Device);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){return DefWindowProc(hwnd, msg, wParam, lParam);}
DWORD Hook(LPVOID)
{
add_log("Starting ES hook...");
WNDCLASSEX wc = {sizeof(WNDCLASSEX),CS_CLASSDC,WndProc,0L,0L,GetModuleHandle(NULL),NULL,NULL,NULL,NULL,"DX",NULL};
RegisterClassEx(&wc);
HWND hWnd = CreateWindow("DX",NULL,WS_OVERLAPPEDWINDOW,100,100,300,300,GetDesktopWindow(),NULL,wc.hInstance,NULL);
LPDIRECT3D9 pD3D = Direct3DCreate9( D3D_SDK_VERSION );
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
LPDIRECT3DDEVICE9 pd3dDevice;
pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&pd3dDevice);
DWORD* pVTable = (DWORD*)pd3dDevice;
pVTable = (DWORD*)pVTable[0];
// Credits to strife for this part and WndProc
//////////////////////////////////////////////
DWORD dwES = pVTable[42];
PEndScene = (TEndScene)DetourFunction((PBYTE)dwES, (PBYTE)&HEndScene);
while(EndSceneCalled == false)
Sleep(1000);
DetourRemove((PBYTE)PEndScene, (PBYTE)HEndScene);
add_log("Starting SCP hook...");
bool Hooked = false;
while(1)
{
DWORD d3d9Base = (DWORD)GetModuleHandle("d3d9.dll");
DWORD PID = GetProcessId(GetCurrentProcess());
DWORD d3d9Size = GetModuleSize(PID, "d3d9.dll");
if(d3d9Base != NULL && Hooked == false)
{
DWORD Present;
if(HookType == 1)
Present = (d3d9Base + SCPoffset);
else
Present = FindPattern(d3d9Base, (d3d9Base + d3d9Size), (unsigned char*)SCP, SCPM);
add_log("Got SCP %X", Present);
PPresent = (TPresent)DetourFunction((PBYTE)Present, (PBYTE)HPresent);
add_log("Hooked Spawchain Present, started repatch loop.");
Hooked = true;
}
Sleep(5000);
if(PresentCalled == true)
{
add_log("Exiting hook thread!");
return 0;
}
}
return 0;
}
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpvReserved)
{
if(dwReason == DLL_PROCESS_ATTACH) {
Log.open("SCP Log.txt");
add_log("////////// Made by SgtMattBaker ////////");
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)Hook, 0, 0, 0);
}
else if(dwReason == DLL_PROCESS_DETACH) {
add_log("/////Hack Closed/////");
Log.close();
}
return TRUE;
}
void __cdecl add_log (const char *fmt, ...) // Function made by azorbix
{
if(Log != NULL)
{
if(!fmt) { return; }
va_list va_alist;
char logbuf[256] = {0};
va_start (va_alist, fmt);
_vsnprintf (logbuf+strlen(logbuf), sizeof(logbuf) - strlen(logbuf), fmt, va_alist);
va_end (va_alist);
Log << logbuf << endl;
}
}
bool DrawMyText(int x, int y, D3DCOLOR Color, ID3DXFont *font, const char* fmt, ...)
{
if(font == NULL)
return false;
RECT FontRect;
FontRect.top = y;
FontRect.left = x;
FontRect.bottom = y + 17;
FontRect.right = x + 300;
char buf[1024] = {'\0'};
va_list va_alist;
va_start(va_alist, fmt);
vsprintf(buf, fmt, va_alist);
va_end(va_alist);
if(font->DrawText( NULL, buf, -1, &FontRect, DT_LEFT | DT_WORDBREAK, Color) != 0)
return true;
else
return false;
}
bool Match(const BYTE* pData, const BYTE* bMask, const char* szMask) //Dunno who made this but I love this and the FindPattern func
{
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) // same as above
{
for(DWORD i=0; i < dwLen; i++)
if( Match( (BYTE*)( dwAddress+i ),bMask,szMask) )
return (DWORD)(dwAddress+i);
return 0;
}
DWORD GetModuleSize(DWORD processID, char* DllName)//Dunno who made this also
{
HANDLE hSnap;
MODULEENTRY32 xModule;
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID);
xModule.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnap, &xModule)) {
while (Module32Next(hSnap, &xModule)) {
if (!strncmp((char*)xModule.szModule,DllName, 8)) {
CloseHandle(hSnap);
return (DWORD)xModule.modBaseSize;
}
}
}
CloseHandle(hSnap);
return 0;
}
The offsets in this hack will work for XP SP3(and maybe other SP's) but won't work for vista and maybe other XP SP's.
Pic:
http://img401.imageshack.us/img401/8144/scppic.png
That is what this source if compiled as posted would do.
Credits go out to
Hookshark creators
R4z8r
strife
azorbix
and most contributing members on UC Forums