proof that hacks are not hard to write (180 lines main.cpp, thats the only code)
Code:
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#define _WIN32_WINDOWS 0x0410
#define _WIN32_IE 0x0600
#include <windows.h>
#include <detours.h>
#include <d3d8.h>
#include "d3dx8.h"
#include <process.h>
#pragma comment( lib, "d3d8" )
#pragma comment( lib, "d3dx8" )
#pragma warning( disable: 4312 )
IDirect3DDevice8** pGameDev = NULL; //(IDirect3DDevice8**)0x00720BE4;
IDirect3DDevice8* pDev = NULL;
bool bInit = false;
bool bPlayers = false;
bool bItems = false;
const char InvD[]= "ps.1.0\n\
def c0, 1.0f, 1.0f,1.0f, 1.0f\n\
tex t0\n\
sub r0,c0,t0";
DWORD InvPS = NULL;
void release_stuff()
{
bInit = false;
if( InvPS )
pDev->DeletePixelShader( InvPS );
InvPS = NULL;
}
void init_stuff()
{
VIRTUALIZER1_START
LPD3DXBUFFER pCode = NULL;
LPD3DXBUFFER pErrorMsgs = NULL;
D3DXAssembleShader( InvD,sizeof(InvD) -1, 0, NULL, &pCode, &pErrorMsgs );
pDev->CreatePixelShader( (DWORD *)pCode->GetBufferPointer(), &InvPS );
bInit = true;
VIRTUALIZER_END
}
HRESULT (__stdcall* or_DrawIndexedPrimitive)(IDirect3DDevice8* dev, D3DPRIMITIVETYPE type,UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) = NULL;
HRESULT __stdcall my_DrawIndexedPrimitive(IDirect3DDevice8* dev, D3DPRIMITIVETYPE type,UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount)
{
if( !bInit ) return or_DrawIndexedPrimitive( dev, type, minIndex, NumVertices, startIndex, primCount );
HRESULT hRet;
IDirect3DVertexBuffer8* pStreamData;
UINT Stride;
dev->GetStreamSource( NULL, &pStreamData, &Stride );
pStreamData->Release();
if( (Stride == 64 && bPlayers) || (Stride == 32 && bItems) ) {
dev->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
dev->SetRenderState( D3DRS_FOGENABLE, D3DZB_FALSE );
dev->SetPixelShader( InvPS );
}
hRet = or_DrawIndexedPrimitive( dev, type, minIndex, NumVertices, startIndex, primCount );
if( (Stride == 64 && bPlayers) || (Stride == 32 && bItems) ) {
dev->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
dev->SetPixelShader( NULL );
or_DrawIndexedPrimitive( dev, type, minIndex, NumVertices, startIndex, primCount );
return hRet;
}
return hRet;
}
HRESULT (__stdcall* or_EndScene)( IDirect3DDevice8* dev );
HRESULT __stdcall my_EndScene( IDirect3DDevice8* dev )
{
if( !bInit ) init_stuff();
if( GetAsyncKeyState( VK_HOME ) &1 ) {
bPlayers = !bPlayers;
}
if( GetAsyncKeyState( VK_END ) &1 ) {
bItems = !bItems;
}
return or_EndScene( dev );
}
HRESULT (__stdcall* or_Reset)( IDirect3DDevice8* dev, D3DPRESENT_PARAMETERS* pPresentationParameters );
HRESULT __stdcall my_Reset( IDirect3DDevice8* dev, D3DPRESENT_PARAMETERS* pPresentationParameters )
{
release_stuff();
HRESULT hRet = or_Reset( dev, pPresentationParameters );
if( SUCCEEDED(hRet) )
init_stuff();
return hRet;
}
unsigned char findT[] = "\xA1\xA7\xA7\xA7\xA7\x8B\x08\x6A\x00\x50\xFF\x51\x18\xC3";
char *findText( const char *start, const char *dwEnd, unsigned char *patt, size_t iMax )
{
char *finder = (char*)start;
char *pbMaxAddr = (char*)dwEnd;
size_t i = 0;
for( ; i < iMax && finder < pbMaxAddr; )
{
if( ( (*finder & 0xff) == (patt[i] & 0xff)) || patt[i] == 0xA7 )
i++;
else if( i != 0 ) {
finder -= i;
i = 0;
}
finder++;
}
if( i == iMax ) {
return (finder-i);
}
return 0;
}
bool bRun = true;
void wait_func( void* )
{
char * find = findText( (const char*)0x401000, (const char *)0x401000 + 0x293000, findT, sizeof(findT)-1 );
if( !find )
return;
DWORD * dwAdd = (DWORD*)*(DWORD*)(find+1);
pGameDev = (IDirect3DDevice8 **)(dwAdd+1);
MessageBeep( 0xFFFFFFFF );
while( !*pGameDev )
Sleep( 100 );
while( bRun ) {
if( pDev != *pGameDev ) {
pDev = *pGameDev;
UINT *vTable = (UINT*)pDev;
vTable = (UINT*)*vTable;
DWORD dwOld;
VirtualProtect( vTable, 500, PAGE_EXECUTE_READWRITE, &dwOld );
*(void**)&or_DrawIndexedPrimitive = (void*)vTable[71];
*(void**)&vTable[71] = (void*)my_DrawIndexedPrimitive;
*(void**)&or_EndScene = (void*)vTable[35];
*(void**)&vTable[35] = (void*)my_EndScene;
*(void**)&or_Reset = (void*)vTable[14];
*(void**)&vTable[14] = (void*)my_Reset;
bInit = false;
}
Sleep( 100 );
}
pDev = *pGameDev;
UINT *vTable = (UINT*)pDev;
vTable = (UINT*)*vTable;
DWORD dwOld;
VirtualProtect( vTable, 500, PAGE_EXECUTE_READWRITE, &dwOld );
*(void**)&vTable[71] = (void*)or_DrawIndexedPrimitive;
*(void**)&vTable[35] = (void*)or_EndScene;
*(void**)&vTable[14] = (void*)or_Reset;
release_stuff();
}
BOOL APIENTRY DllMain( HMODULE /*hModule*/, DWORD dwReason, LPVOID /*lpReserved*/ )
{
if( dwReason == DLL_PROCESS_ATTACH ) {
_beginthread( wait_func, NULL, NULL );
} else if( dwReason == DLL_PROCESS_DETACH ) {
bRun = false;
Sleep( 500 );
}
return TRUE;
}