/* The reason for sharing the source of the Wallhack designed for those who are not will be the place.
How do you understand this, and I do not know how to write, but I think this is also a field. Will wish to develop in the minds of the public. */

#include "cBase.h"
#include "cDetour.h"
#include "cMenu.h"

#pragma comment(lib, "d3d8.lib")
#pragma comment(lib, "d3dx8.lib")

cDetour *Detour;
cBase Base;
cMenu Menu;
copt opt;

void PreReset( LPDIRECT3DDEVICE8 pDevice )
{

Menu.PreReset();
return;
}

void PostReset( LPDIRECT3DDEVICE8 pDevice )
{

Menu.PostReset(pDevice);
return;
}

typedef HRESULT ( WINAPI* oReset )( LPDIRECT3DDEVICE8 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters );
oReset pReset;

HRESULT APIENTRY myReset( LPDIRECT3DDEVICE8 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters )
{
_asm pushad;

PreReset( pDevice );
HRESULT hRet = pReset( pDevice, pPresentationParameters );

if( SUCCEEDED( hRet ) )
{
PostReset( pDevice );
}

_asm popad;
return hRet;
}

typedef HRESULT (WINAPI* oPresent) (LPDIRECT3DDEVICE8 pDevice, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion);
oPresent pPresent;

HRESULT APIENTRY myPresent(LPDIRECT3DDEVICE8 pDevice, CONST RECT* pSourceRect,CONST RECT* pDestRect, HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion)
{
_asm pushad;

_asm popad;
return pPresent(pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
}


typedef HRESULT ( WINAPI* oBeginScene )( LPDIRECT3DDEVICE8 pDevice );
oBeginScene pBeginScene;

HRESULT APIENTRY myBeginScene( LPDIRECT3DDEVICE8 pDevice )
{
_asm pushad;

_asm popad;
return pBeginScene( pDevice );
}


typedef HRESULT ( WINAPI* oEndScene )( LPDIRECT3DDEVICE8 pDevice );
oEndScene pEndScene;

HRESULT APIENTRY myEndScene( LPDIRECT3DDEVICE8 pDevice )
{
_asm pushad;
PostReset(pDevice);
Menu.ShowMenu(pDevice);
PreReset(pDevice);
_asm popad;

return pEndScene( pDevice );
}

typedef HRESULT (WINAPI* oDrawIndexedPrimitive) (LPDIRECT3DDEVICE8 pDevice, D3DPRIMITIVETYPE pType, UINT nMinIndex, UINT nNumVertices, UINT nStartIndex, UINT nPrimitiveCount );
oDrawIndexedPrimitive pDrawIndexedPrimitive;

HRESULT APIENTRY myDrawIndexedPrimitive(LPDIRECT3DDEVICE8 pDevice, D3DPRIMITIVETYPE pType, UINT nMinIndex, UINT nNumVertices, UINT nStartIndex, UINT nPrimitiveCount)
{
_asm pushad;
LPDIRECT3DVERTEXBUFFER8 Stream;
UINT m_Stride;

if(pDevice->GetStreamSource(0,&Stream,&m_Stride)==D3D_OK)Stre am->Release();

if(m_Stride==44 && opt.chams.chams)
{
pDevice->SetRenderState(D3DRS_ZENABLE,false);

if(opt.chams.type==3)
{
pDevice->SetTexture(0,NULL);
}

if(opt.chams.chamsb==0)
pDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(255,255,0,0));

pDrawIndexedPrimitive(pDevice,pType,nMinIndex, nNumVertices, nStartIndex, nPrimitiveCount);
pDevice->SetRenderState(D3DRS_ZENABLE,true);

if(opt.chams.chamsf==0)
pDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(255,255,0,0));

}

_asm popad;
return pDrawIndexedPrimitive(pDevice, pType, nMinIndex, nNumVertices, nStartIndex, nPrimitiveCount);
}


template <typename C,typename VF >
DWORD* VirtualFuncResolver(C obj, VF fun)
{
DWORD ofs_vfun = (DWORD)(((*(DWORD***)((DWORD*)((DWORD)*(DWORD**)&f un + 0x8)))));
if(ofs_vfun>=0xA0000000)ofs_vfun = ofs_vfun & 0xFF;
DWORD adr_obj = (DWORD)(**(DWORD****)&obj);
DWORD* ENTRY = (DWORD*)(*(DWORD**)(adr_obj+ofs_vfun));
return ENTRY;
}

DWORD* FindDevice(DWORD Base) // Credits to Croner at ******.com Simple Pattern Scan Function
{
for(long i= 0,n = 0; i < 0x128000; i++ ) // 128000;
{
if(*(BYTE *)(Base+i+0x00)==0xC7)n++;
if(*(BYTE *)(Base+i+0x01)==0x06)n++;
if(*(BYTE *)(Base+i+0x06)==0x89)n++;
if(*(BYTE *)(Base+i+0x07)==0x86)n++;
if(*(BYTE *)(Base+i+0x0C)==0x89)n++;
if(*(BYTE *)(Base+i+0x0D)==0x86)n++;

if(n == 6) return (DWORD*) //6
(Base + i + 2);n = 0;
}
return(0);
}

typedef HRESULT ( WINAPI* oSetTransform ) (LPDIRECT3DDEVICE8 pDevice, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix);
oSetTransform pSetTransform;

HRESULT WINAPI mySetTransform(LPDIRECT3DDEVICE8 pDevice, D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix)
{
// Code Here
return pSetTransform(pDevice, State, pMatrix);
}

int iDIRECT3D(void)
{

HMODULE hD3D = NULL;

do
{
hD3D = GetModuleHandle("d3d8.dll");
Sleep(100);
}
while(!hD3D);

DWORD_PTR * pDevice = FindDevice((DWORD)hD3D);
DWORD_PTR * Vtable = 0;
*(DWORD_PTR *)&Vtable = *(DWORD_PTR *)pDevice;

// pReset = (oReset) Detour->Create((PBYTE)VirtualFuncResolver(pDevice, &IDirect3DDevice8::Reset),(PBYTE)myReset,6);
// pPresent = (oPresent) Detour->Create((PBYTE)VirtualFuncResolver(pDevice, &IDirect3DDevice8::Present),(PBYTE)myPresent,6) ;
// pBeginScene = (oBeginScene) Detour->Create((PBYTE)VirtualFuncResolver(pDevice, &IDirect3DDevice8::BeginScene),(PBYTE)myBeginScene ,6);
pEndScene = (oEndScene) Detour->Create((PBYTE)VirtualFuncResolver(pDevice, &IDirect3DDevice8::EndScene),(PBYTE)myEndScene,DET OUR_TYPE_OBS_XOR);// this works fine
pDrawIndexedPrimitive = (oDrawIndexedPrimitive) Detour->Create((PBYTE)VirtualFuncResolver(pDevice, &IDirect3DDevice8:rawIndexedPrimitive), (PBYTE)myDrawIndexedPrimitive,DETOUR_TYPE_OBS_XOR );
pSetTransform = (oSetTransform) Detour->Create((PBYTE)Vtable[37], (PBYTE)mySetTransform,DETOUR_TYPE_OBS_XOR);
return 0;
}

char* cBase::GetFile(char *file)
{
static char path[320];
for(int i= 0;i<strlen(path);i++)
path[i]=0;
strcpy(path, Base.dllpath);
strcat(path, file);
return path;
}


BOOL WINAPI DllMain(HMODULE hDll, DWORD dwReason, LPVOID lpReserved){
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)iDIRECT3D, NULL, NULL, NULL);

break;

case DLL_PROCESS_DETACH:

break;

}return TRUE;
}