Code:
#define DBG_READ_WRITE 0x3C001 // break on read/write but not on execution
#define DBG_EXEC 0x1 // break on execution
#define DBG_NODBG 0x0 // remove the breakpoint
DWORD SetDebugReg(DWORD hThreadID, DWORD HookAddres, DWORD AccessRestriction, PDWORD CallBackFunction){
MyOpenThread = (OpenThread)GetProcAddress(GetModuleHandle("Kernel32.dll"), "OpenThread");
HANDLE hThread = MyOpenThread(THREAD_ALL_ACCESS, FALSE, hThreadID);
SuspendThread(hThread);
CONTEXT c;
c.ContextFlags=CONTEXT_DEBUG_REGISTERS;
GetThreadContext(hThread,&c);
c.Dr0=(DWORD)HookAddres;
c.Dr6=0;
c.Dr7 = AccessRestriction;
SetThreadContext(hThread,&c);
ResumeThread(hThread);
CloseHandle(hThread);
MyAddVectoredExceptionHandler = (AddVectoredExceptionHandler)GetProcAddress(GetModuleHandle("Kernel32.dll"), "AddVectoredExceptionHandler");
MyAddVectoredExceptionHandler( 1, (PDWORD)CallBackFunction);
return 0;
}
Example usage:
Code:
#include <windows.h>
#include <iostream>
#include <string.h>
#include <fstream>
#include <stdio.h>
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\d3d9.h>
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\d3dx9.h>
#pragma comment (lib, "C:\\Program Files (x86)\\Microsoft DirectX SDK (June 2010)\\Lib\\x86\\d3dx9.lib")
#pragma comment(lib, "VtableScan.lib")
#define _WIN32_WINNT 0x0500 //is needed for AddVectoredExceptionHandler function
#define DBG_READ_WRITE 0x3C001
#define DBG_EXEC 0x1
#define DBG_NODBG 0x0
extern "C"{
DWORD _stdcall ScanTable();
DWORD _stdcall Hook(DWORD TargetAddress, DWORD HookAddress);
DWORD _stdcall ReturnFromHook(DWORD GhookAddress, DWORD NumberOfArguments);
DWORD _stdcall RemoveHook(DWORD GGhookAddress);
DWORD _stdcall MidFunctionHook(DWORD MidFunctionTargetAddress,DWORD MidFunctionHookAddress,DWORD InstructionSize);
DWORD _stdcall PreparePseudoStack(DWORD FistArgument, DWORD PreviousPseudoStack);
DWORD _stdcall RewindStackForReturn(DWORD StackBasePointer);
}
void MainThread(); // [82]
DWORD SetDebugReg(DWORD hThreadID, DWORD HookAddres, DWORD AccessRestriction, PDWORD CallBackFunction);
HRESULT hkDip(LPDIRECT3DDEVICE9 Device, D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount);
typedef DWORD (__stdcall *AddVectoredExceptionHandler) ( ULONG FirstHandler, PDWORD VectoredHandler);
AddVectoredExceptionHandler MyAddVectoredExceptionHandler;
typedef DWORD (__stdcall *OrigionalDIP) (LPDIRECT3DDEVICE9 Device, D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount);
OrigionalDIP oDIP;
typedef HANDLE (__stdcall *OpenThread) (DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId);
OpenThread MyOpenThread;
DWORD heThread;
DWORD Target;
DWORD HookTrampoline;
bool bCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)
{
for(;*szMask;++szMask,++pData,++bMask)
if(*szMask=='x' && *pData!=*bMask) return 0;
return (*szMask) == NULL;
}
DWORD FindPattern(DWORD dwdwAdd,DWORD dwLen,BYTE *bMask,char * szMask)
{
for(DWORD i=0; i<dwLen; i++)
if (bCompare((BYTE*)(dwdwAdd+i),bMask,szMask)) return (DWORD)(dwdwAdd+i);
return 0;
}
BOOL APIENTRY DllMain( HANDLE hModule, DWORD fdwReason, LPVOID lpReserved ){
if( fdwReason == DLL_PROCESS_ATTACH){
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&MainThread, NULL, NULL, NULL);
return TRUE;
}
return TRUE;
}
__declspec(naked) HRESULT hkDip(LPDIRECT3DDEVICE9 Device, D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount){
__asm pushad
Device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
__asm{
popad
push -1
mov eax, oDIP
jmp eax
}
}
LONG CALLBACK VectoredHandler( PEXCEPTION_POINTERS ExceptionInfo){
if( ExceptionInfo->ExceptionRecord->ExceptionCode==EXCEPTION_SINGLE_STEP){
ExceptionInfo->ContextRecord->Eip = (DWORD) hkDip;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
HRESULT OneTimeDipHook(LPDIRECT3DDEVICE9 Device, D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount){
__asm pushad
heThread = GetCurrentThreadId();
__asm popad
ReturnFromHook(HookTrampoline, 1);
}
void MainThread(){
while(!GetModuleHandle("d3d9.dll")){
Sleep(1000);
}
DWORD* Vtable = (DWORD*) ScanTable();
while(1){
if(GetAsyncKeyState(VK_INSERT)){
break;
}
Sleep(100);
}
Sleep(5000);
oDIP = (OrigionalDIP)Vtable[82];
__asm{
mov eax, oDIP
add eax, 07h
mov oDIP, eax
}
HookTrampoline = Hook((DWORD)Vtable[82], (DWORD)&OneTimeDipHook);
Sleep(5000);
RemoveHook(HookTrampoline);
Sleep(1000);
Target = (DWORD)Vtable[82];
__asm{
mov eax, Target
add eax, 05h
mov Target, eax
}
while(1){
if(GetAsyncKeyState(VK_INSERT)){
SetDebugReg(heThread, (DWORD)Target, DBG_EXEC, (PDWORD)&VectoredHandler);
}
if(GetAsyncKeyState(VK_END)){
SetDebugReg(heThread, (DWORD)Target, DBG_NODBG, (PDWORD)&VectoredHandler);
}
Sleep(100);
}
}
DWORD SetDebugReg(DWORD hThreadID, DWORD HookAddres, DWORD AccessRestriction, PDWORD CallBackFunction){
MyOpenThread = (OpenThread)GetProcAddress(GetModuleHandle("Kernel32.dll"), "OpenThread");
HANDLE hThread = MyOpenThread(THREAD_ALL_ACCESS, FALSE, hThreadID);
SuspendThread(hThread);
CONTEXT c;
c.ContextFlags=CONTEXT_DEBUG_REGISTERS;
GetThreadContext(hThread,&c);
c.Dr0=(DWORD)HookAddres;
c.Dr6=0;
c.Dr7 = AccessRestriction;
SetThreadContext(hThread,&c);
ResumeThread(hThread);
CloseHandle(hThread);
MyAddVectoredExceptionHandler = (AddVectoredExceptionHandler)GetProcAddress(GetModuleHandle("Kernel32.dll"), "AddVectoredExceptionHandler");
MyAddVectoredExceptionHandler( 1, (PDWORD)CallBackFunction);
return 0;
}