Code:
//=====================================================================================
#include <windows.h>
#include <conio.h>
#include <d3d9.h>
#pragma comment(lib, "d3d9.lib")
#include <d3dx9.h>
#pragma comment(lib, "d3dx9.lib")
typedef HRESULT ( WINAPI * DrawIPrim )
( LPDIRECT3DDEVICE9, D3DPRIMITIVETYPE,
INT, UINT, UINT, UINT, UINT );
void Jump( DWORD Address, DWORD Your_Detour );
DWORD Old = NULL;
LPDIRECT3DDEVICE9 m_pD3Ddev;
LPDIRECT3D9 pD3D;
DrawIPrim pDrawIPrim = NULL;
DWORD dwEndscene_hook = NULL;
DWORD dwEndscene_ret = NULL;
DWORD dwDIP_hook = NULL;
DWORD dwDIP_ret = NULL;
DWORD dwReset_hook = NULL;
DWORD dwReset_ret = NULL;
DWORD bJump = NULL;
D3DVIEWPORT9 Viewport;
D3DRECT RectA;
D3DRECT RectB;
DWORD CrossHairColor = D3DCOLOR_ARGB( 255, 20, 255, 20 );
DWORD ScreenCenterX = NULL;
DWORD ScreenCenterY = NULL;
LPD3DXFONT pFont = NULL;
HMODULE D3D9 = NULL;
UINT fHeight = 16;
RECT FontRect;
D3DPRESENT_PARAMETERS D3D_PP = {0};
IDirect3D9 * (WINAPI *oDirect3DCreate9)(UINT SDKVersion);
//=====================================================================================
VOID WINAPI MY_MAIN_ENDSCENE( LPDIRECT3DDEVICE9 pDev )
{
pDev->GetViewport( &Viewport );
ScreenCenterX = ( Viewport.Width / 2 );
ScreenCenterY = ( Viewport.Height / 2 );
RectA.x1 = ScreenCenterX - 40;
RectA.x2 = ScreenCenterX + 40;
RectA.y1 = ScreenCenterY;
RectA.y2 = ScreenCenterY + 1;
RectB.x1 = ScreenCenterX;
RectB.x2 = ScreenCenterX + 1;
RectB.y1 = ScreenCenterY - 40;
RectB.y2 = ScreenCenterY + 40;
pDev->Clear( 1, &RectA, D3DCLEAR_TARGET, CrossHairColor, 0, 0 );
pDev->Clear( 1, &RectB, D3DCLEAR_TARGET, CrossHairColor, 0, 0 );
if( pFont == NULL )
D3DXCreateFontA( pDev, fHeight, 0, FW_BOLD, 0, TRUE,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, "Calibri", &pFont );
if( pFont != NULL )
{
int istrlen = strlen( "HELLO" ) * 3;
FontRect.left = ScreenCenterX - istrlen;
FontRect.top = Viewport.Height - fHeight - fHeight;
FontRect.right = Viewport.Width;
FontRect.bottom = Viewport.Height;
pFont->DrawTextA( 0, "HELLO", -1, &FontRect,
DT_NOCLIP, D3DCOLOR_ARGB( 255, 20, 128, 255 ) );
}
}
__declspec(naked) void MyEndscene( )
{
__asm
{
MOV DWORD PTR SS:[EBP-0x10],ESP
MOV ESI,DWORD PTR SS:[EBP+0x8]
XOR EBX,EBX //replace patched code
PUSHFD
PUSHAD
PUSH [EBP+0x8]
CALL MY_MAIN_ENDSCENE;
POPAD
POPFD
CMP ESI,EBX //replace patched code
jmp dwEndscene_ret; //jump back to normal endscene
}
}
VOID WINAPI MY_MAIN_DIP( LPDIRECT3DDEVICE9 pDev,
D3DPRIMITIVETYPE Type, INT BIndex, UINT MIndex,
UINT NVertices, UINT SIndex, UINT PCount )
{
LPDIRECT3DVERTEXBUFFER9 Stream_Data;
UINT Offset = 0;
UINT Stride = 0;
if( pDev->GetStreamSource( 0, &Stream_Data, &Offset, &Stride ) == S_OK )
Stream_Data->Release();
if( Stride == 32 )
{
bJump = TRUE;
pDev->SetRenderState( D3DRS_ZENABLE, FALSE );
pDrawIPrim( pDev, Type, BIndex, MIndex,
NVertices, SIndex, PCount );
pDev->SetRenderState( D3DRS_ZENABLE, TRUE );
bJump = FALSE;
}
}
__declspec(naked) void MyDIP( )
{
__asm
{
MOV EDI,DWORD PTR SS:[EBP+0x8]
XOR EBX,EBX
CMP EDI,EBX // replace patched code
PUSHFD
PUSHAD
MOV EDX,[bJump]
CMP EDX,0x0
JG DONE
PUSH [EBP+0x20] // Push arguments of DIP
PUSH [EBP+0x1C]
PUSH [EBP+0x18]
PUSH [EBP+0x14]
PUSH [EBP+0x10]
PUSH [EBP+0x0C]
PUSH [EBP+0x08]
CALL MY_MAIN_DIP
DONE: POPAD
POPFD
jmp dwDIP_ret; // jump back to normal DIP
}
}
VOID WINAPI MY_MAIN_RESET( )
{
if( pFont != NULL )
if( pFont->Release( ) == S_OK )
pFont = NULL;
}
__declspec(naked) void MyReset( )
{
__asm
{
PUSHAD
PUSHFD
CALL MY_MAIN_RESET
POPFD
POPAD
MOV ESI,DWORD PTR SS:[EBP-0x08]
MOV EDI,DWORD PTR SS:[EBP-0x04]
POP EBX
JMP dwReset_ret
}
}
//=====================================================================================
VOID WINAPI GETD3D( VOID )
{
HWND ConsoleWindow = GetConsoleWindow( );
//ShowWindow( ConsoleWindow, SW_HIDE ); // Your Choice ...
while( D3D9 == NULL )
{
D3D9 = GetModuleHandleA( "d3d9.dll" );
Sleep( 100 );
}
*(PDWORD)&oDirect3DCreate9 = (DWORD)
GetProcAddress( D3D9, "Direct3DCreate9" );
_cprintf( "Direct3DCreate9\n" );
pD3D = oDirect3DCreate9( D3D_SDK_VERSION );
D3D_PP.Windowed = TRUE;
D3D_PP.SwapEffect = D3DSWAPEFFECT_DISCARD;
D3D_PP.BackBufferFormat = D3DFMT_UNKNOWN;
_cprintf( "CreateDevice\n" );
pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
ConsoleWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&D3D_PP, &m_pD3Ddev );
PDWORD VTABLE = *(DWORD**)m_pD3Ddev;
dwEndscene_hook = VTABLE[42] + 0x2A;
dwEndscene_ret = dwEndscene_hook + 0x0A;
dwDIP_hook = VTABLE[82] + 0x2D;
dwDIP_ret = dwDIP_hook + 0x7;
dwReset_hook = VTABLE[16] + 165;
dwReset_ret = dwReset_hook + 0x7;
*(PDWORD)&pDrawIPrim = (DWORD)VTABLE[82];
_cprintf( "Jump\n" );
Jump( (DWORD)dwEndscene_hook, (DWORD)MyEndscene );
Jump( (DWORD)dwDIP_hook, (DWORD)MyDIP );
Jump( (DWORD)dwReset_hook, (DWORD)MyReset );
_cprintf( "Done\n" );
Sleep( 400 );
m_pD3Ddev->Release( );
pD3D->Release( );
FreeConsole( );
}
//=====================================================================================
BOOL WINAPI DllMain( HINSTANCE hModule, DWORD dwReason, LPVOID lpvReserved )
{
if( dwReason == DLL_PROCESS_ATTACH )
{
DisableThreadLibraryCalls( hModule );
AllocConsole( );
_cprintf( "Ready\n" );
CreateThread( NULL, NULL, (LPTHREAD_START_ROUTINE)
GETD3D, NULL, NULL, NULL);
}
return TRUE;
}
//=====================================================================================
void Jump( DWORD Address, DWORD Your_Detour )
{
VirtualProtect( (LPVOID)Address, 5,
PAGE_EXECUTE_READWRITE, &Old );
*(PBYTE)Address = (BYTE)0xE9;
*(PDWORD)(Address + 1) =
( Your_Detour - Address - 5) ;
VirtualProtect( (LPVOID)Address, 5,
Old, &Old );
}
//=====================================================================================