I was going to post this originally on the UC forums but the crowd there sucks. Since you all are much cooler you get this code. Please don't paste this on other forums. Link back here and support Fleep!
I've finally got my DLL to the point where it will make a good starting point for any hack. The attached code will hook into a target Direct3D application and display AntTweakBar. AntTweakBar makes a professional looking menu for your hacks and it is relatively easy to use. If you aren't familiar with it go to the link above and check it out. Now on to the code!
The most common method of injecting into a process is to use a remote thread however if you do so after the application is running you need to use pattern scanners, offsets, or other tricks to find EndScene. If you create a suspended process and use a remote thread then you can make a cleaner hook but this can cause problems with applications that use launchers. For my hook I decided to install a global hook with SetWindowsHookEx. Here is the code for installing and uninstalling the global hook which is exported from my DLL.
This code is called from a hack manager application before you launch the target process. See the attached zip file for a C# example manager app.
extern "C" void InstallHook(HWND hWnd, const char *pName)
hwnd = hWnd;
targetName = 0;
if( pName )
hHook = SetWindowsHookEx(WH_CBT, (HOOKPROC)HookProc, hins, 0);
if (NULL == hHook)
wsprintf(msg, TEXT("Cannot install hook, code: %d"), GetLastError());
MessageBox(hwnd, msg, TEXT("error"), MB_ICONERROR);
extern "C" void ReleaseHook()
if (hHook != NULL)
BOOL bRes = UnhookWindowsHookEx(hHook);
if (!bRes) MessageBox(hwnd, TEXT("Cannot remove hook."), TEXT("error"), MB_ICONERROR);
The hook DLL relies on global shared memory for passing data from the manager application and all instances of the target process. This shared data segment is the same for every process which has our DLL injected into it. The code for initializing the share data is shown below.
Now let's look at the window hook code. This code is called by Windows for a variety of reasons. See the CBTProc documentation for more details. The event we are interested in is HCBT_CREATEWND which is called when the application calls CreateWindow. Since you need to call CreateWindow before calling Direct3DCreate9 we can safely hook up Direct3D with a clean and portable hook. Here is the CBT callback code.
#pragma data_seg (".shared")
// only INITIALIZED variables in this block will actually end up in the shared section!!!
static HHOOK hHook = NULL;
static HINSTANCE hins = NULL;
static HWND hwnd = NULL;
static char targetName[MAX_PATH] = "";
#pragma data_seg ()
This code looks for a given module name to decide whether to hook Direct3D. Once we find the target process we set a flag so we can quickly exit this callback. This function is called a lot so it is important not to hog resources here.
extern "C" LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
if( HCBT_CREATEWND == nCode )
if( inTarget == false )
if( GetModuleFileNameA( NULL, szPath, MAX_PATH ) )
if( strstr(szPath,targetName) )
OutputDebugString(_T("Found target process. Hooking DirectX...\n"));
tDirect3DCreate9 _Direct3DCreate9 = (tDirect3DCreate9)GetProcAddress(GetModuleHandle(TEXT("d3d9.dll")),"Direct3DCreate9");
if( _Direct3DCreate9 != NULL )
dDirect3DCreate9 = new DetourXS(_Direct3DCreate9, hDirect3DCreate9);
oDirect3DCreate9 = (tDirect3DCreate9) dDirect3DCreate9->GetTrampoline();
inTarget = true;
return CallNextHookEx(hHook, nCode, wParam, lParam);
Now that we have Direct3DCreate9 detoured we can chain hook our way to EndScene in the usual manner. See the attached file for the full code. Next we need to initialize AntTweakBar and hook into the message queue and IDirect3D9::CreateDevice() is the perfect place to do it. Here is the code from that detour.
The code above creates a bar with one color selector. See the AntTweakBar site for more examples on how to setup bars. Next we get the target window handle which was given to us and setup a new window procedure so we can intercept messages. Here is the code for the window procedure.
pBar = TwNewBar("TESTBAR");
TwDefine(" GLOBAL help='This example shows how to integrate AntTweakBar in a DirectX9 application.' "); // Message added to the help bar.
TwDefine(" TESTBAR color='128 224 160' text=dark "); // Change TweakBar color and use dark text
TwAddVarRW(pBar, "Color", TW_TYPE_COLOR3F, &gColor, " label='Strip color' ");
drawTwBar = true;
targetWindow = hFocusWindow != NULL ? hFocusWindow : pPresentationParameters->hDeviceWindow;
if( targetWindow != NULL )
OldWindowProc = (WNDPROC)SetWindowLongPtr(targetWindow,GWL_WNDPROC,(LONG_PTR)WindowProc);
This code uses the WM_CLOSE message as a signal to cleanup the bars. The rest of the messages are passed to the AntTweakBar message pump and then on to the target application only if AntTweakBar didn't handle the message.
extern "C" LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
int handled = 0;
if(WM_CLOSE == message)
drawTwBar = false;
handled = TwEventWin(hWnd,message,wParam,lParam);
return handled ? 0 : CallWindowProc(OldWindowProc, hWnd, message, wParam, lParam);
Below are screenshots of it all in action. Enjoy.
DetourXS: Easy to use detour library with x86 and x64 support. https://dreaminpixels.co.uk/detourxs...tours-library/
LDE64: Small length disassembler to feed DetourXS. https://beatrix2004.free.fr/tools.html
DirectXTutorials.com: Great site. Ripped the D3D test app from there. https://www.directxtutorial.com/Less...lessonid=9-4-1
AntTweakBar: Powerful UI for 3D apps. https://anttweakbar.sourceforge.net/doc/
EDIT: I fixed the x64 build problem. Here's the new code and new v-scan. https://www.virustotal.com/en/file/f...is/1365032140/