Sign in to follow this  
RuslanKysa

DX V-Table hook

Recommended Posts

RuslanKysa    102
[CODE]
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <windows.h>
#pragma comment(lib,"winmm.lib")
#include <d3d9.h>
#pragma comment(lib, "d3d9.lib")
#include <d3dx9.h>
#pragma comment(lib, "d3dx9.lib")
#define FPS 5
#include "keys.h"
#include <detours.h>
#pragma comment(lib, "detours.lib")
typedef HRESULT (WINAPI* hook_EndScene) (LPDIRECT3DDEVICE9 D3DDevice);
typedef HRESULT (WINAPI* hook_Present) (CONST RECT *pSourceRect,CONST RECT *pDestRect,HWND hDestWindowOverride,CONST RGNDATA *pDirtyRegion);
hook_EndScene EndScene;
hook_Present Present;
//DWORD *pixelMap = 0;
//unsigned int pixelMap_size = 0;
DWORD pixelMap[1280*1024];
D3DRECT testRect = {1,1,25,25};
INPUT input;
BOOL first_run = 1;
IDirect3DSwapChain9 *pSwapChain;
IDirect3DSurface9 *pSurface;
IDirect3DSurface9 *pBackBuffer;
D3DLOCKED_RECT rect;
D3DPRESENT_PARAMETERS settings;
BOOL ValidStart = 0;
SOCKET gsock = INVALID_SOCKET;
sockaddr_in dest;
WSADATA wsad;
char buff;
BOOL can_send = 1;
unsigned long timeStart;
unsigned long f = 0;
HANDLE hThread;
DWORD RecvThread(void *ptr)
{
while(true)
{
recv(gsock,&buff,1,0);
//can_send = 1;
}
}
HRESULT WINAPI hooked_EndScene(LPDIRECT3DDEVICE9 D3DDevice)
{
HRESULT error = 0;
BYTE *drvRef;
D3DDevice->Clear(1,&testRect, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(225,225,0,0),1.0f ,0);
//D3DDevice->
if(first_run)
{
error = D3DDevice->GetSwapChain(0,&pSwapChain);

if(error != D3D_OK)
MessageBox(0,"GetSwapChain() Fail",0,0);

error = pSwapChain->GetPresentParameters(&settings);

if(error != D3D_OK)
MessageBox(0,"GetPresentParamters() Fail",0,0);

error = D3DDevice->CreateOffscreenPlainSurface(settings.BackBufferWidth,settings.BackBufferHeight,
D3DFMT_X8R8G8B8,D3DPOOL_SYSTEMMEM,&pSurface,0);
if(error != D3D_OK)
MessageBox(0,"CreateOffscreenPlainSurface() Fail",0,0);

//D3DDevice->QueryInterface(IID_IUnknown,(void **)&self);

//pixelMap = (DWORD *)malloc(settings.BackBufferWidth * settings.BackBufferHeight * 4);
//pixelMap = (DWORD *)malloc( 640 * 480 * 4);
first_run = 0;

//char tmp[10];

//itoa(settings.BackBufferFormat,tmp,10);
//MessageBox(0,tmp,0,0);
}


input.ki.dwFlags=KEYEVENTF_KEYUP;
if(GetAsyncKeyState('F'))
{
input.ki.wScan = 0x0439 ;
input.ki.dwFlags=0;
ValidStart = 1;
MessageBox(0,"Run",0,0);

}

switch(buff)
{
case 'W':
input.ki.wScan = KEYBOARD_W;
input.ki.dwFlags = 0;
break;
case 'A':
input.ki.wScan = KEYBOARD_A;
input.ki.dwFlags = 0;
break;
case 'S':
input.ki.wScan = KEYBOARD_S;
input.ki.dwFlags = 0;
break;
case 'D':
input.ki.wScan = KEYBOARD_D;
input.ki.dwFlags = 0;
break;
default:
input.ki.dwFlags = 0;
break;
}
SendInput(1,&input,sizeof(INPUT));


if(ValidStart)
{

// if(f < (timeGetTime() - timeStart) * FPS / 1000)
//{
//error = pSwapChain->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&pBackBuffer);
error = D3DDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&pBackBuffer);
if(error != D3D_OK)
MessageBox(0,"GetBackBuffer() Fail",0,0);


error = D3DDevice->GetRenderTargetData(pBackBuffer,pSurface);

if(error != D3D_OK)
MessageBox(0,"GetRenderTargetData() Fail","Error",0);

//error = D3DDevice->GetFrontBufferData(0,pSurface);

error = pSurface->LockRect(&rect,0,D3DLOCK_READONLY);

if(error != D3D_OK)
MessageBox(0,"LockRectError",0,0);




drvRef = (BYTE *)rect.pBits;
int i,j;
for(i = 0;i<settings.BackBufferHeight;i++)
{
DWORD *color_ref = (DWORD *)drvRef;
for(j = 0;j<settings.BackBufferWidth;j++)
{
pixelMap[(i*settings.BackBufferWidth)+j] = color_ref[j];
}

drvRef += rect.Pitch;
}
//int err = send(gsock,(const char *)pixelMap, settings.BackBufferHeight * settings.BackBufferHeight * 4,0);
//if(can_send)
send(gsock,(const char *)pixelMap, 640*4*480,0);
//if(err == SOCKET_ERROR)
// return MessageBox(0,"CheckSock",0,0);


pSurface->UnlockRect();
pBackBuffer->Release();
//ValidStart = 1;
//can_send = 0;
//}
}


return EndScene(D3DDevice);
}

DWORD * FindDevice(VOID)
{
DWORD Base = (DWORD)LoadLibraryA("d3d9.dll");

for(DWORD i = 0; i < 0x128000; i++ )
{
if ( (*(BYTE *)(Base+i+0x00))==0xC7
&& (*(BYTE *)(Base+i+0x01))==0x06
&& (*(BYTE *)(Base+i+0x06))==0x89
&& (*(BYTE *)(Base+i+0x07))==0x86
&& (*(BYTE *)(Base+i+0x0C))==0x89
&& (*(BYTE *)(Base+i+0x0D))==0x86 )
return (DWORD *)(Base + i + 2);
}
return NULL;
}

BOOL APIENTRY DllMain( HMODULE hInstance, DWORD dwReason, LPVOID lpReserved )
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
{
DWORD *VTable ;
DWORD *VtablePtr;
DWORD *devicePtr;
GetModuleHandleA("d3d9.dll");

VtablePtr = FindDevice();
devicePtr = ***(DWORD****)VtablePtr;
*(DWORD *)&VTable = *(DWORD *)VtablePtr;
EndScene = (hook_EndScene) (DWORD)VTable[42];
Present = (hook_Present) (DWORD)VTable[17];

DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)EndScene, hooked_EndScene);
//DetourAttach(&(PVOID &)Present,hooked_Present);
DetourTransactionCommit();

memset(&input,0,sizeof(INPUT));
input.type=1;
WSAStartup(MAKEWORD(2,2),&wsad);
memset(&input,0,sizeof(input));
input.type = 1;

gsock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(gsock ==INVALID_SOCKET )
MessageBox(0,"socket fail",0,0);

dest.sin_addr.S_un.S_addr = inet_addr("192.168.0.1");
dest.sin_family = AF_INET;
dest.sin_port = htons(27015);

int error = connect(gsock,(const sockaddr *)&dest,sizeof(sockaddr_in));

if(error == SOCKET_ERROR)
MessageBox(0,"Connect Fail",0,0);
hThread= CreateThread(0,0,(LPTHREAD_START_ROUTINE)RecvThread,0,0,0);
timeStart = timeGetTime();
}



break;

case DLL_PROCESS_DETACH:
break;
}

return TRUE;
}


/*
DisableThreadLibraryCalls(Module);
if (Reason == DLL_PROCESS_ATTACH)
{
memset(&input,0,sizeof(INPUT));
input.type=INPUT_KEYBOARD;
CreateThread(NULL, NULL, newThread, NULL, NULL, NULL);
}
*/[/CODE]
The more important part is

[CODE]
DWORD * FindDevice(VOID)
{
DWORD Base = (DWORD)LoadLibraryA("d3d9.dll");

for(DWORD i = 0; i < 0x128000; i++ )
{
if ( (*(BYTE *)(Base+i+0x00))==0xC7
&& (*(BYTE *)(Base+i+0x01))==0x06
&& (*(BYTE *)(Base+i+0x06))==0x89
&& (*(BYTE *)(Base+i+0x07))==0x86
&& (*(BYTE *)(Base+i+0x0C))==0x89
&& (*(BYTE *)(Base+i+0x0D))==0x86 )
return (DWORD *)(Base + i + 2);
}
return NULL;
}

BOOL APIENTRY DllMain( HMODULE hInstance, DWORD dwReason, LPVOID lpReserved )
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
{
DWORD *VTable ;
DWORD *VtablePtr;
DWORD *devicePtr;
GetModuleHandleA("d3d9.dll");

VtablePtr = FindDevice();
devicePtr = ***(DWORD****)VtablePtr;
*(DWORD *)&VTable = *(DWORD *)VtablePtr;
EndScene = (hook_EndScene) (DWORD)VTable[42];
Present = (hook_Present) (DWORD)VTable[17];

DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)EndScene, hooked_EndScene);
//DetourAttach(&(PVOID &)Present,hooked_Present);
DetourTransactionCommit();

memset(&input,0,sizeof(INPUT));
input.type=1;
WSAStartup(MAKEWORD(2,2),&wsad);
memset(&input,0,sizeof(input));
input.type = 1;

gsock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(gsock ==INVALID_SOCKET )
MessageBox(0,"socket fail",0,0);

dest.sin_addr.S_un.S_addr = inet_addr("192.168.0.1");
dest.sin_family = AF_INET;
dest.sin_port = htons(27015);

int error = connect(gsock,(const sockaddr *)&dest,sizeof(sockaddr_in));

if(error == SOCKET_ERROR)
MessageBox(0,"Connect Fail",0,0);
hThread= CreateThread(0,0,(LPTHREAD_START_ROUTINE)RecvThread,0,0,0);
timeStart = timeGetTime();
}



break;

case DLL_PROCESS_DETACH:
break;
}

return TRUE;
}


/*
DisableThreadLibraryCalls(Module);
if (Reason == DLL_PROCESS_ATTACH)
{
memset(&input,0,sizeof(INPUT));
input.type=INPUT_KEYBOARD;
CreateThread(NULL, NULL, newThread, NULL, NULL, NULL);
}[/CODE]
When I try it on my PC it works perfect,but when I try to do it(inject) on a notebook it doesnt work
Any ideas why ?

Share this post


Link to post
Share on other sites
Evil Steve    2017
Define "doesn't work".

That looks like a pretty horrible way to find a vtable in a DLL - what does it actually do, search for assembly JMP instructions or something? If it's looking for hard-coded pointer values assuming d3d9.dll is loaded into memory at the same address, remember that won't won't on Windows 7 due to address space randomisation.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this