Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


DXTrainer Framework Kit Finally Complete!

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
SteveAndrew
Master Cheater
Reputation: 30

Joined: 02 Sep 2012
Posts: 323

PostPosted: Sun Apr 21, 2013 2:03 am    Post subject: DXTrainer Framework Kit Finally Complete! Reply with quote



Very Happy

EDIT: Odd I can't seem to upload my source even though I've even taken out the image binary files embedded as well... Well looks like the source will be found in the binary section as well! Get it there!

http://forum.cheatengine.org/viewtopic.php?t=564407

It's taken quite a bit of work but I finally pieced it all together! Not without the help of CETack (Alice0725) And CE itself (Dark Byte) though Wink

This is a C++ DX9 Trainer Framework Kit (Support for more directx versions coming soon) Or DXT-K

What can you do with this? Well you can instantly create and deploy a directx9 in-game GUI trainer without writing a single line of code, or even touching a compiler Very Happy

See it in action here: http://www.youtube.com/watch?v=yVnwyryAoak&feature=youtu.be

All you need is just a trainer image file with several supported formats, recommended .png for small file sizes and transparency! And a .CT File Very Happy Yes that's it! As you can see from the GUI images of two example trainers I deployed... You just give it an image file and a .CT (Cheat Engine Cheat Table) and then you customize the margin and spacing if you'd like, font size and font color, enter the process name (only so the deployed injector will know what process to target [the injected dll itself targets self (since it's already inside the process)]

Of course you can play around with the source which can be made more customizeable to you're liking (If you're a C++ Coder)

Take a guided tour through the source here: http://www.youtube.com/watch?v=UBipOllYW-8&feature=youtu.be


There are several moving parts which make this whole thing come together... The heart of it is CETack (Put together by Alice0725) and is powered by CE! It's mostly just the 'AutoAssembler' part of CE without much else! This is what makes actually enabling and disabling Auto Assembler scripts of .CT's possible! My C++ 'AutoAssembler' class is only just a wrapper for CETack!

There's also the CheatTable class which is responsible for loading .CT's in the easily readable and writable standard XML format! (tinyxml2 helped with that! So credit is also due to the tinyxml2 devs!)

Then as we get further into it, my x86HookClass (which is kind of like microsoft detours, but custom) It's able to automatically hook basically anything and at the same time automatically create a detour, thanks to a function called "DWORD __stdcall GetInstructionLength(BYTE *iptr0)" It's unknown who wrote it, but it's able to calculate the instruction length of any thing I've thrown at it so far! x86 that is! So kudos to the author of that code as well!

Then we have a LinkedList class I wrote, which is heavily used throughout for storing data objects because I started really disliking arrays for some reason, even auto-resizing array classes, that I was making before... And have just basically switched to linked lists! lol I know it's not good to always use them but in these cases here I think it's okay Smile


Then of course there's the DXTrainerMenu and DXHack classes which is what makes it so easy to just plug in different images or parameters and just have a nice in-game trainer being drawn for you Wink

DX9Trainer.cpp is the main source file which handles the directx hooking + image and custom trainer configuration loading (also XML) + ct loading (XML) + auto assembling and everything else inbetween...

So.... Getting down to how it all works together...

1. The 'DX Trainer Kit - Custom Trainer Deployer' After being configured and clicking 'Generate Custom DirectX9 Trainer Very Happy', does several things... First it creates the directory path which your custom trainer will be stored! It creates it's path in the %appdata% folder: "%appdata%\Steve Andrew\Alice0725\Dark Byte\[CustomTrainerName]" where custom trainer name is what you put in the first edit box of the Deployer app. Since it's created as a directory (and files named after it later on) it can't contain any characters not allowed in folder and file names... The file hierarchy chosen also demonstrates just how deep this project goes Wink (I'm only scratching away at the surface ha...)

2. It also copies the image file and .CT file you specified into that directory so the trainer has it's own copy (in case you moved the image or .ct or something it will still work)

3. It dumps first the actual fully compiled DX9TrainerFrameworkKit DLL (coded MSVC++ 2012 Express) but not before modifying a hard coded offset where I have purposely put some defined bytes to take up the space needed... It writes the config file path to that RVA Wink of the not loaded DLL file before dumping it... (that config file is an .xml file which contains all the information you have chosen in the Deployer application. It's used by the actual DX9TrainerFrameworkKit DLL to know where to load everything from and what font + size + color to use and such.

4. It dumps a customized injector for the custom trainer which it also writes the config file path to a hard coded offset so it knows what EXE to inject into (also it displays the image and trainer name just for fun Very Happy lol) You don't have to use the injector if you don't want, you can opt to inject it yourself with CE or another injector and it will still work perfectly fine! It's only there because I wanted to make it a total package where it can be all ready to go without needing anything else! A self sufficient tightly wrapped package! xD After the custom trainer is generated it simply pops open the directory it's contained it and you can make a shortcut to your desktop or whatever (maybe even modify the xml config file yourself if you don't like having it in the appdata folder Wink)

5. Finally it writes the special custom trainer configuration .XML file which contains various information required...this is an example of a generated config .xml file looks like:
Code:

<DXTrainerKitCustomTrainerConfigFile EngineeredBy="Steve Andrew (DXT-K); Alice0725 (CETack); Dark Byte (CE) :D">
    <CustomTrainerName>RE6Trainer</CustomTrainerName>
    <ProcessName>BH6.exe</ProcessName>
    <CTFilePath>C:\Users\Steve\AppData\Roaming\Steve Andrew\Alice0725\Dark Byte\RE6Trainer\Resident Evil 6 - Steve Andrew -RELEASE UPDATE 2.0.CT</CTFilePath>
    <ImageFilePath>C:\Users\Steve\AppData\Roaming\Steve Andrew\Alice0725\Dark Byte\RE6Trainer\DXKIT6.png</ImageFilePath>
    <ImageWidth>352</ImageWidth>
    <ImageHeight>524</ImageHeight>
    <Margin>10</Margin>
    <Spacing>20</Spacing>
    <fontD3DXCOLOR>FFF9F41C</fontD3DXCOLOR>
    <fontSIZE>10</fontSIZE>
</DXTrainerKitCustomTrainerConfigFile>



The DX Trainer Kit Deployer application is coded in Embarcadero RAD Studio XE 3 C++ (because I like how easy it is to graphically build a GUI but still at the same time get to use C && C++ code! [Reminds me of delphi or even pascal, but like I said I can write in C++ Very Happy])

The DXT-K InjeXz0R application is also developed in RAD Studio XE3 (Whenever I build Window Desktop GUI App, I usually use RAD to save time and, just doing it manually is a pain LOL [I'm use to using CreateWindow/CreateWindowEx for everything, writing everything in code manually and guessing and checking at window control positions, it's not fun! lol])

Finally the DX9TrainerFrameworkKit.dll (which is renamed to whatever custom name you called your trainer by the way) is written in Microsoft Visual C++ 2012 Express Edition! (It's actually a pretty clean and fast compiler! I mostly only use it for writing DLL's though Smile)

Oh and the DX9TrainerFrameworkKit DLL dumps CETack-x86.dll to whatever the game's directory is, whatever process it's injected into... I know I should've made it dump to the trainer directory, but I just forgot that detail when I was just happy to get it all working Very Happy

Like I said though I will update it to include more directx versions, and aside with above mentioned fact, also forgot to have the option to choose between rendering with EndScene or Present (right not it just uses EndScene, but the code is all set up to flip a switch and use the other, just have to add that to the XML config Wink)


I do see one problem with this however! Since everything is basically a package within a package within a package, there is binary data in my source files! LOL... I suppose the image files can be okay, but I'm going to have to post the certain header files (with hard coded binary) + the dxinjector resource file (embbedded in the Deployer app), separately in the binary section! So you'll not get a fully compile-able source here, but can compile the pieces and embed them yourself, or grab them from the binary section... Or grab the whole working application from the binary section Smile

Use an application like hex workshop, or a custom built application to encode the binary so it's pasteable as an unsigned char array...

For example the current CETack DLL is the only executable binary embedded within the DXTrainerFrameworkKit DLL in CETackDLLData.h and starts like this:
Code:

unsigned char EmbeddedCETackDLL[443904] = {
0x4D,0x5A,0x90,0x00,0x03,0x00,0x00,0x00,0x04,0x00


Other than that, there's some images embedded that aren't yet configurable (may make them in the future updates) [Checked + Unchecked images, CELogo, and a Mouse Pointer {So you can always see where your clicking even if the game isn't drawing it's pointer over your gui})

There's nothing embedded in the injector so that's okay to post the full source here...

Then there's the Deployer app which has two executable binaries embedded... One as a resource (the 8.46MB injector app [built without dynamic RTL and no runtime packages so it will run without having special borland packages, but it in turn makes it much bigger) Then the DX Trainer Framework Kit DLL embedded in a header file as an unsigned char array... which as said above inside of it has the CETack dll! LOL Wink


Ok Now let's get to the source code! Very Happy

DX9Trainer.h:
Code:

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include "DXTrainerMenu.h"
#include "AutoAssembler.h"
#include "x86HookClass.h"
#include "CETackDLLData.h"
#include "DXPointerImage.h"
#include "CELOGO.h"
//[DXT-K] "DirectX Trainer Kit" v1.0
//[Steve Andrew's Work: DXTrainerMenu class, DXHack class, AutoAssembler class, CheatTable class, x86HookClass class, LinkedList class, DbgPrinter class]
//Finished Coding and Released by Steve Andrew on 4/20/2013
//Full Credit to: Alice0725 for CETack (stand alone CE Auto Assembler)
//Full Credit to: Dark Byte for Cheat Engine itself (which has 'Auto Assembler' [the most awesome way to assemble just about anything!])
//Full Credit to: Creators of tinyxml2 (used for easy + quick XML loading / parsing)
//Full Credit to: Whoever wrote the ingenious function 'GetInstructionLength(BYTE *iptr0)' [#include "x86InstructionLength.h"]

//DX9 Function Pointer Definitions 8=========|;)
typedef HRESULT (WINAPI* BEGINSCENE)(LPDIRECT3DDEVICE9 pDevice);
typedef HRESULT (WINAPI* ENDSCENE)(LPDIRECT3DDEVICE9 pDevice);
typedef HRESULT (WINAPI* PRESENT)(LPDIRECT3DDEVICE9 pDevice, RECT* pSourceRect, RECT* pDestRect, HWND hDestWindowOverride, RGNDATA* pDirtyRegion);
typedef HRESULT (WINAPI* RESET)(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS *pParams);
//(;|=======8

//For creating our own D3D Device in our own window, which will give us the offsets we need :D
LRESULT CALLBACK DXHKWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void DXHookWindowThread();

//Threads (Only three threads, and only two end up running after main executes)
void MainThread();
void UpdateMousePointerThread();
void InputHandlerThread();

void InitializeTextures(LPDIRECT3DDEVICE9 pDevice);
void RestoreCheatToggledStates();

//My DX9 Hooked Functions 8=========|;)
HRESULT WINAPI myBeginScene(LPDIRECT3DDEVICE9 pDevice);
HRESULT WINAPI myEndScene(LPDIRECT3DDEVICE9 pDevice);
HRESULT WINAPI myPresent(LPDIRECT3DDEVICE9 pDevice, RECT* pSourceRect, RECT* pDestRect, HWND hDestWindowOverride, RGNDATA* pDirtyRegion);
HRESULT WINAPI myReset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS *pParams);
//(;|=======8

int LoadCustomTrainerConfig(char *LoadFromPath);


DX9Trainer.cpp:
Code:

#include "DX9Trainer.h"
//[DXT-K] "DirectX Trainer Kit" v1.0
//[Steve Andrew's Work: DXTrainerMenu class, DXHack class, AutoAssembler class, CheatTable class, x86HookClass class, LinkedList class, DbgPrinter class]
//Coded and Released by Steve Andrew on 4/20/2013
//Full Credit to: Alice0725 for CETack (stand alone CE Auto Assembler)
//Full Credit to: Dark Byte for Cheat Engine itself (which has 'Auto Assembler' [the most awesome way to assemble just about anything!])
//Full Credit to: Creators of tinyxml2 (used for easy + quick XML loading / parsing)
//Full Credit to: Whoever wrote the ingenious function 'GetInstructionLength(BYTE *iptr0)' [#include "x86InstructionLength.h"]

//CETackDLL AutoAssembler :D SPECIAL THANKS Alice0725 && Dark Byte!
AutoAssembler *Assembler = 0;

//DX9 Interfaces + DXTrainerMenu Class + Sprite + Extra Textures + Positions
LPDIRECT3D9 DX; //DX Interface
LPDIRECT3DDEVICE9 DXDev; //DX Device Interface
LPD3DXSPRITE pSprite = 0;

//DXTrainer Menu class! The heart of the dynamic DirectX Trainer Menu!
DXTrainerMenu *DXTrainer = 0;
//Mouse Pointer + CE Logo Textures (Extra Textures [not part of the menu])
IDirect3DTexture9 *DXPointerTexture = 0, *CELogoTexture = 0;
//Remembered position + cheat on/off states (for restoring after a call to reset); Pointer Position, CE Logo Position
D3DXVECTOR3 SavedTrainerPosition, DXPointerPosition, CELogoPosition;
LinkedList *EnabledDisabledInfo = 0;

//DX9 Hook Related
BEGINSCENE RealBeginScene;
ENDSCENE RealEndScene;
RESET RealReset;
PRESENT RealPresent;
HookClass *BeginSceneHook = 0;
HookClass *EndSceneHook = 0;
HookClass *ResetHook = 0;
HookClass *PresentHook = 0;
LPVOID BeginSceneAddress;
LPVOID EndSceneAddress;
LPVOID ResetAddress;
LPVOID PresentAddress;

bool Show = true; //if 'Show' == true, trainer window and mouse pointer and ce logo is drawn on top of game ;)
bool Unloading = false; //to inform threads to exit to safely unload the trainer
bool HookBeginScene = false; //Don't hook 'BeginScene' by default (not working properly for some reason on Vista/7/8+)
bool UsingEndSceneHook = true; //Use 'EndScene' hook rather than 'Present' hook by default (I think it's better)

HINSTANCE hInst;
HWND hWnd, GameWindow = 0;
//'CustomTrainerConfigFilePath' This will be overwritten, by the trainer deployer application ;)
//initialize it so it's all there
char CustomTrainerConfigFilePath[MAX_PATH] = {0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B,0xB0,0x0B};
char *CustomTrainerName = new char[260];
char *CustomTrainerCTPath = new char[260];
char *CustomTrainerImagePath = new char[260];
int CustomTrainerImageHeight = 0, CustomTrainerImageWidth = 0;
float CustomTrainerMargin = 10.0f, CustomTrainerSpacing = 20.0f;
D3DXCOLOR CustomTrainerFontColor = D3DXCOLOR(0xFFFFFFFF);
int CustomTrainerFontSize = 8;
//char dbg[260];

BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID lpReserved)
{
   if(reason == DLL_PROCESS_ATTACH)
   {
      hInst = hInstDll;
      DisableThreadLibraryCalls(hInst);

      //sprintf(dbg, "CustomTrainerConfigFilePath Address: %p; Approximate RVA: %X", CustomTrainerConfigFilePath, ((ULONG)&CustomTrainerConfigFilePath - (ULONG)hInst));
      //OutputDebugStringA(dbg);

      CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&MainThread, 0, 0, 0);
      CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&DXHookWindowThread, 0, 0, 0);
   }
   else if(reason == DLL_PROCESS_DETACH)
   {
      if(BeginSceneHook)
         delete BeginSceneHook;
      if(EndSceneHook)
         delete EndSceneHook;
      if(PresentHook)
         delete PresentHook;
      if(ResetHook)
         delete ResetHook;

      OutputDebugStringA("[DXT-K] Safely Ejected... ;)");
   }

   return TRUE;
}

LRESULT CALLBACK DXHKWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

void DXHookWindowThread()
{
   WNDCLASSEXW wcex;
   wcex.cbSize = sizeof(WNDCLASSEX);
   wcex.style = CS_HREDRAW | CS_VREDRAW;
   wcex.lpfnWndProc = (WNDPROC)DXHKWndProc;
   wcex.cbClsExtra = 0;
   wcex.cbWndExtra = 0;
   wcex.hInstance = hInst;
   wcex.hIcon = 0;
   wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
   wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
   wcex.lpszMenuName = 0;
   wcex.lpszClassName = L"DXHKW";
   wcex.hIconSm = 0;

   RegisterClassExW(&wcex);

   ULONG WindowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
   hWnd = CreateWindowA("DXHKW", "DXHKWindow", WindowStyle, CW_USEDEFAULT, CW_USEDEFAULT, 420, 420, 0, 0, hInst, 0);

   ShowWindow(hWnd, SW_HIDE);
   UpdateWindow(hWnd);

   MSG Msg;
   while(GetMessage(&Msg, 0, 0, 0) > 0)
   {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
   }

   //OutputDebugStringA("DXWindow thread exiting...");
}

void MainThread()
{
   FILE *DumpCETackDLL = fopen("CETack-x86.dll", "wb");
   if(DumpCETackDLL)
   {
      fwrite(&EmbeddedCETackDLL, sizeof(EmbeddedCETackDLL), 1, DumpCETackDLL);
      fclose(DumpCETackDLL);
   }

   Assembler = new AutoAssembler("CETack-x86.dll");

   if(!Assembler)
   {
      OutputDebugStringA("[DXT-K: TOTAL FAILURE] Could not create AA Object! Ejecting...");
      PostMessageA(hWnd, WM_CLOSE, 0, 0);
      Sleep(1000);
      FreeLibraryAndExitThread(hInst, 0);
   }

   Sleep(1000); //Wait a second to make sure our dx window has been born long enough to create a d3d device ourself :D

   if(!(DX = Direct3DCreate9(D3D_SDK_VERSION)))
   {
      OutputDebugStringA("[DXT-K: TOTAL FAILURE] Could Not Create Direct3D Interface! (retry maybe)");
      PostMessageA(hWnd, WM_CLOSE, 0, 0);
      Sleep(1000);
      FreeLibraryAndExitThread(hInst, 0);
      return;
   }

   D3DPRESENT_PARAMETERS d3dpp;
   ZeroMemory(&d3dpp, sizeof(d3dpp));
   d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
   d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
   d3dpp.Windowed         = TRUE;

   DX->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &DXDev);
   if(!DXDev)
   {
      OutputDebugStringA("[DXT-K: FAILURE] Could Not Create Direct3D Device Interface! (try again maybe)");
      PostMessageA(hWnd, WM_CLOSE, 0, 0);
      Sleep(1000);
      FreeLibraryAndExitThread(hInst, 0);
      return;
   }

   PostMessageA(hWnd, WM_CLOSE, 0, 0);
   OutputDebugStringA("[DXT-K: SUCCESS!] Got Direct3D Device!");

   //if(!LoadCustomTrainerConfig("C:\\Users\\Steve\\AppData\\Roaming\\Steve Andrew\\Alice0725\\Dark Byte\\FinalFinalTEST\\FinalFinalTEST.xml"))
   if(!LoadCustomTrainerConfig(CustomTrainerConfigFilePath))
   {
      OutputDebugStringA("[DXT-K: FAILURE] Could not load xml config file! (Improperly deployed?)");
      Sleep(1000);
      //FreeLibraryAndExitThread(hInst, 0);
      return;
   }

   ULONG *d3dMethods = (ULONG*)*(ULONG*)DXDev;

   BeginSceneAddress = (LPVOID)d3dMethods[41];
   EndSceneAddress = (LPVOID)d3dMethods[42];
   ResetAddress = (LPVOID)d3dMethods[16];
   PresentAddress = (LPVOID)d3dMethods[17];

   //sprintf(dbg, "BeginSceneAddress: %p EndSceneAddress: %p; ResetAddress: %p; PresentAddress: %p \n", BeginSceneAddress, EndSceneAddress, ResetAddress, PresentAddress);
   //OutputDebugStringA(dbg);

   //Reset MUST be hooked! :D
   ResetHook = new HookClass((DWORD)ResetAddress, (DWORD)&myReset);
   RealReset = (RESET)ResetHook->DetouredFunction;

   if(HookBeginScene) //If wanting to hook 'BeginScene' for whatever reason...
   {
      BeginSceneHook = new HookClass((DWORD)BeginSceneAddress, (DWORD)&myBeginScene);
      RealBeginScene = (BEGINSCENE)EndSceneHook->DetouredFunction;
   }

   if(UsingEndSceneHook) //Hook either 'EndScene' or 'Present' but NOT both! xD
   {
      EndSceneHook = new HookClass((DWORD)EndSceneAddress, (DWORD)&myEndScene);
      RealEndScene = (ENDSCENE)EndSceneHook->DetouredFunction;
   }
   else
   {
      PresentHook = new HookClass((DWORD)PresentAddress, (DWORD)&myPresent);
      RealPresent = (PRESENT)PresentHook->DetouredFunction;
   }

   ZeroMemory(&SavedTrainerPosition, sizeof(D3DXVECTOR3));
   ZeroMemory(&DXPointerPosition, sizeof(D3DXVECTOR3));
   ZeroMemory(&CELogoPosition, sizeof(D3DXVECTOR3));

   //Assembler->CT->LoadCT("C:\\Users\\Steve\\Desktop\\My Cheat Tables\\Tables\\Dark Souls\\Dark Souls FINAL v1.1-SteveAndrew.CT");
   //Assembler->CT->LoadCT((char*)&RE6CheatTable, sizeof(RE6CheatTable));
   Assembler->CT->LoadCT(CustomTrainerCTPath);
   Assembler->AttachTo(0, 0, 0); //Since we are injected inside target process we attach to self, targetself:= (HANDLE)-1

   CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&UpdateMousePointerThread, 0, 0, 0);
   CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&InputHandlerThread, 0, 0, 0);
}

void UpdateMousePointerThread()
{
   POINT CursorPos;

   for(;; Sleep(10))
   {
      if(Unloading) break;

      GetCursorPos(&CursorPos);
      ScreenToClient(GameWindow, &CursorPos);
      DXPointerPosition.x = (float)CursorPos.x;
      DXPointerPosition.y = (float)CursorPos.y;
   }

   //OutputDebugStringA("Mouse pointer updating thread exiting...");
}

void InputHandlerThread()

   for(;; Sleep(10))
   {
      if(GetAsyncKeyState(VK_F12) & 0x8000) //Show/Hide Trainer Window!
      {
         Show ^= 1;
         Sleep(150);
      }

      if(Show && DXTrainer && GetAsyncKeyState(VK_LBUTTON) & 0x8000) //Check for checkbox toggling + window repositioning! :D
      {
         GameWindow = GetForegroundWindow(); //cheap way of getting the game's window handle lol

         //If checkbox is clicked, attempt to toggle cheat using auto assembler
         //If successfully toggled, toggle 'CheatEnabled' variable of that 'DXHack' to show either a checked/unchecked checkbox
         DXHack *FirstHack = (DXHack*)DXTrainer->TrainerHacks->GetFirstNode();
         DXHack *NextHack;
         if(FirstHack)
         {   
            if(DXPointerPosition.x >= (FirstHack->CheckboxPosition.x - 4.0f) && DXPointerPosition.x <= (FirstHack->CheckboxPosition.x + 13.0f)
               && DXPointerPosition.y >= (FirstHack->CheckboxPosition.y - 4.0f) && DXPointerPosition.y <= (FirstHack->CheckboxPosition.y + 13.0f))
            {
               if(Assembler->ToggleCheat(FirstHack->CheatId)) FirstHack->CheatEnabled ^= 1;
               //Beep(520, 100);
               continue;
            }

            while(NextHack = (DXHack*)DXTrainer->TrainerHacks->GetNextNode())
            {
               if(DXPointerPosition.x >= (NextHack->CheckboxPosition.x - 4.0f) && DXPointerPosition.x <= (NextHack->CheckboxPosition.x + 13.0f)
                  && DXPointerPosition.y >= (NextHack->CheckboxPosition.y - 4.0f) && DXPointerPosition.y <= (NextHack->CheckboxPosition.y + 13.0f))
               {
                  if(Assembler->ToggleCheat(NextHack->CheatId)) NextHack->CheatEnabled ^= 1;
                  //Beep(520, 100);
                  break;
               }
            }
         }

         //Move trainer menu by clicking and dragging any part of the window besides a toggle cheat checkbox
         if(DXPointerPosition.x >= DXTrainer->TrainerPosition.x && DXPointerPosition.x <= DXTrainer->TrainerPosition.x + CustomTrainerImageWidth
            && DXPointerPosition.y >= DXTrainer->TrainerPosition.y && DXPointerPosition.y <= DXTrainer->TrainerPosition.y + CustomTrainerImageHeight)
         {
            POINT CapturedCursorPos, CurrentCursorPos;
            D3DXVECTOR3 Difference;
            while(GetAsyncKeyState(VK_LBUTTON) & 0x8000)
            {
               GetCursorPos(&CapturedCursorPos);
               Sleep(10);
               GetCursorPos(&CurrentCursorPos);

               Difference.x = (float)(CurrentCursorPos.x - CapturedCursorPos.x);
               Difference.y = (float)(CurrentCursorPos.y - CapturedCursorPos.y);

               DXTrainer->Move(Difference);
               SavedTrainerPosition = DXTrainer->TrainerPosition;

               CELogoPosition.x = DXTrainer->TrainerPosition.x + (DXTrainer->TrainerWidth - (30.0f + 10.0f));
               CELogoPosition.y = DXTrainer->TrainerPosition.y + (DXTrainer->TrainerHeight - (30.0f + 10.0f));
            }   
         }
      }

      //[Hotkey: CTRL + ALT + U] Safely unload trainer
      if(GetKeyState(VK_LCONTROL) & 0x8000 && GetKeyState(VK_LMENU) & 0x8000 && GetKeyState('U') & 0x8000)
      {
         //Allow all threads to exit, and unload the directx trainer safetly
         Unloading = true;
         //Prevent drawing of trainer menu gui while were freeing it's resources ;)
         Show = false;
         
         if(DXTrainer)
         {
            //Safely release all things created by DXTrainerMenu class and produce cheat on/off state record then free that!
            EnabledDisabledInfo = DXTrainer->Release();
            delete DXTrainer;
            if(EnabledDisabledInfo) delete EnabledDisabledInfo;
         }

         //Safely release extra textures + sprite object
         saferelease(CELogoTexture);
         saferelease(pSprite);

         //Free AutoAssembler object and it's loaded CT, as well as closing any open handles + freeing the 'CETack' library! :P
         if(Assembler) delete Assembler;
         
         OutputDebugStringA("[DXT-K: Safely Unloading]... Please Wait...");
         Sleep(3000); //about 3 seconds should be enough for threads to break from operations and exit
         FreeLibraryAndExitThread(hInst, 0); //Freeing will unhook any in place dx hooks
      }
   }
}

void InitializeTextures(LPDIRECT3DDEVICE9 pDevice)
{
   D3DXIMAGE_INFO imageinfo;

   if(!pSprite)
      D3DXCreateSprite(pDevice, &pSprite);

   if(!DXPointerTexture)
   {
      ZeroMemory(&imageinfo, sizeof(imageinfo));
      D3DXCreateTextureFromFileInMemoryEx(pDevice, &DXPointerImageData, sizeof(DXPointerImageData), 18, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_DEFAULT, 0, &imageinfo, 0, &DXPointerTexture);
      //D3DXCreateTextureFromFileInMemory(pDevice, &DXPointerImageData, sizeof(DXPointerImageData), &DXPointerTexture);
   }

   if(!CELogoTexture)
   {
      ZeroMemory(&imageinfo, sizeof(imageinfo));
      D3DXCreateTextureFromFileInMemoryEx(pDevice, &CELogoData, sizeof(CELogoData), 30, 30, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_DEFAULT, 0, &imageinfo, 0, &CELogoTexture);
      //D3DXCreateTextureFromFileInMemory(pDevice, &CELogoData, sizeof(CELogoData), &CELogoTexture);
   }

   if(!DXTrainer)
   {
      //Create DX Trainer Menu and have it generate the cheat list :D // CUSTOM DEPLOYED :D
      DXTrainer = new DXTrainerMenu(pDevice, CustomTrainerImagePath, L"Arial", CustomTrainerFontColor, CustomTrainerFontSize, CustomTrainerImageWidth, CustomTrainerImageHeight);
      if(DXTrainer)
      {
         DXTrainer->AddCheatsToMenu(Assembler->CT);

         //Move Trainer to wherever it was before dx device was reset (or default position if hasn't been moved)
         DXTrainer->Move(SavedTrainerPosition);

         //Position CE Logo at the bottom right of DX Trainer Menu window!
         CELogoPosition.x = DXTrainer->TrainerPosition.x + (DXTrainer->TrainerWidth - (30.0f + 10.0f));
         CELogoPosition.y = DXTrainer->TrainerPosition.y + (DXTrainer->TrainerHeight - (30.0f + 10.0f));

         //Restore toggled on/off state for each cheat
         RestoreCheatToggledStates();
      }
   }

   //Code to create texture from a raw bitmap in memory
   //D3DXCreateTexture(pDevice, BitmapBitInfo.bmiHeader.biWidth, BitmapBitInfo.bmiHeader.biHeight, 0, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &RawBitmapInMemory);
   
   //Code to create texture loaded from a file
   //D3DXCreateTextureFromFile(pDevice, L"C:\\Users\\Steve\\My Documents\\MousePointerBlack.png", &DXPointerTexture);
}

void RestoreCheatToggledStates()
{
   if(EnabledDisabledInfo)
   {
      DXHack *dxh = (DXHack*)DXTrainer->TrainerHacks->GetFirstNode();
      DXCheatEnabledDisabled *dxc = (DXCheatEnabledDisabled*)EnabledDisabledInfo->GetFirstNode();
      if(dxc && dxh)
      {
         if(dxh->CheatId == dxc->CheatId && strcmp(dxh->NameOfCheat, dxc->CheatDescription) == 0)
         {
            //Assembler->CT->dbg->Print(0, "First Cheat Match Found, Enabled value: %u; id: %u; desc: %s", dxc->CheatEnabled, dxc->CheatId, dxc->CheatDescription);
            dxh->CheatEnabled = dxc->CheatEnabled;
         }

         dxh = (DXHack*)DXTrainer->TrainerHacks->GetNextNode();
         dxc = (DXCheatEnabledDisabled*)EnabledDisabledInfo->GetNextNode();
         while(dxc && dxh)
         {
            if(dxh->CheatId == dxc->CheatId && strcmp(dxh->NameOfCheat, dxc->CheatDescription) == 0)
            {
               //Assembler->CT->dbg->Print(0, "Match Found, Enabled value: %u; id: %u; desc: %s", dxc->CheatEnabled, dxc->CheatId, dxc->CheatDescription);
               dxh->CheatEnabled = dxc->CheatEnabled;
            }

            dxh = (DXHack*)DXTrainer->TrainerHacks->GetNextNode();
            dxc = (DXCheatEnabledDisabled*)EnabledDisabledInfo->GetNextNode();
         }
      }

      delete EnabledDisabledInfo;
      EnabledDisabledInfo = 0;
   }
}

//BeginScene hook (in case you wanted to do something after begin scene is called, currently not working right on Vista/7/8+, so currently not hooked)
HRESULT WINAPI myBeginScene(LPDIRECT3DDEVICE9 pDevice)
{
   __asm pushad
   HRESULT Result = RealBeginScene(pDevice);
   
   //if(Show) InitializeTextures(pDevice);
   
   __asm popad
   return Result;
}

//Note: Only use either or, don't hook both!
//'EndScene' hook, if using 'EndScene' hook instead of 'Present' hook!
HRESULT WINAPI myEndScene(LPDIRECT3DDEVICE9 pDevice)
{
   __asm pushad
   InitializeTextures(pDevice);
   if(Show)
   {
      if(pSprite && DXTrainer && CELogoTexture && DXPointerTexture)
      {
         pSprite->Begin(D3DXSPRITE_ALPHABLEND);
         {
            DXTrainer->Draw(pSprite);
            pSprite->Draw(CELogoTexture, 0, 0, &CELogoPosition, 0xffffffff);
            pSprite->Draw(DXPointerTexture, 0, 0, &DXPointerPosition, 0xffffffff);
         }
         pSprite->End();
      }
   }
   __asm popad

   return RealEndScene(pDevice);
}

//'Present' hook, if using 'Present' hook instead of 'EndScene' hook!
HRESULT WINAPI myPresent(LPDIRECT3DDEVICE9 pDevice, RECT* pSourceRect, RECT* pDestRect, HWND hDestWindowOverride, RGNDATA* pDirtyRegion)
{
   __asm pushad
   InitializeTextures(pDevice);
   if(Show)
   {
      if(pSprite && DXTrainer && CELogoTexture && DXPointerTexture)
      {
         pSprite->Begin(D3DXSPRITE_ALPHABLEND);
         {
            DXTrainer->Draw(pSprite);
            pSprite->Draw(CELogoTexture, 0, 0, &CELogoPosition, 0xffffffff);
            pSprite->Draw(DXPointerTexture, 0, 0, &DXPointerPosition, 0xffffffff);
         }
         pSprite->End();
      }
   }
   __asm popad

   return RealPresent(pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
}

//On dx device reset, you MUST release any dx object(s) you've created!
//Therefore 'Reset' MUST be hooked!
HRESULT WINAPI myReset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS *pParams)
{
   __asm pushad
   
   if(DXTrainer)
   {
      //Safely release all things created by DXTrainerMenu class and produce cheat on/off state record
      EnabledDisabledInfo = DXTrainer->Release();
      delete DXTrainer;
      DXTrainer = 0;
   }

   //Safely release extra textures + sprite object
   saferelease(DXPointerTexture);
   DXPointerTexture = 0;

   saferelease(CELogoTexture);
   CELogoTexture = 0;

   saferelease(pSprite);
   pSprite = 0;

   __asm popad

   return RealReset(pDevice, pParams);
}

int LoadCustomTrainerConfig(char *LoadFromPath)
{
   tinyxml2::XMLDocument *Doc = new tinyxml2::XMLDocument();

   if(Doc && Doc->LoadFile(LoadFromPath) == 0)
   {
      tinyxml2::XMLElement* TrainerKitConfig = Doc->FirstChildElement();
      if(TrainerKitConfig && TrainerKitConfig->FirstAttribute() && strcmp(TrainerKitConfig->FirstAttribute()->Name(), "EngineeredBy") == 0)
      {
         if(strcmp(TrainerKitConfig->FirstAttribute()->Value(), "Steve Andrew (DXT-K); Alice0725 (CETack); Dark Byte (CE) :D") != 0)
         {
            OutputDebugStringW(L"Invalid Kit Configuration File! ;)"); //AHAHHA!
            delete Doc;
            return 0;
         }

         tinyxml2::XMLElement *TrainerName = TrainerKitConfig->FirstChildElement("CustomTrainerName");
         if(TrainerName)
         {
            memcpy(CustomTrainerName, TrainerName->GetText(), strlen(TrainerName->GetText())+1);
         }

         tinyxml2::XMLElement *CTFilePath = TrainerKitConfig->FirstChildElement("CTFilePath");
         if(CTFilePath)
         {
            memcpy(CustomTrainerCTPath, CTFilePath->GetText(), strlen(CTFilePath->GetText())+1);
         }

         tinyxml2::XMLElement *ImageFilePath = TrainerKitConfig->FirstChildElement("ImageFilePath");
         if(ImageFilePath)
         {
            memcpy(CustomTrainerImagePath, ImageFilePath->GetText(), strlen(ImageFilePath->GetText())+1);
         }

         tinyxml2::XMLElement *ImageWidth = TrainerKitConfig->FirstChildElement("ImageWidth");
         if(ImageWidth)
         {
            CustomTrainerImageWidth = atoi(ImageWidth->GetText());
         }

         tinyxml2::XMLElement *ImageHeight = TrainerKitConfig->FirstChildElement("ImageHeight");
         if(ImageHeight)
         {
            CustomTrainerImageHeight = atoi(ImageHeight->GetText());
         }

         tinyxml2::XMLElement *Margin = TrainerKitConfig->FirstChildElement("Margin");
         if(Margin)
         {
            CustomTrainerMargin = atof(Margin->GetText());
         }

         tinyxml2::XMLElement *Spacing = TrainerKitConfig->FirstChildElement("Spacing");
         if(Spacing)
         {
            CustomTrainerMargin = atof(Spacing->GetText());
         }

         tinyxml2::XMLElement *DXTFontColor = TrainerKitConfig->FirstChildElement("fontD3DXCOLOR");
         if(DXTFontColor)
         {
            CustomTrainerFontColor = D3DXCOLOR((DWORD)strtoul(DXTFontColor->GetText(), 0, 16));
         }

         tinyxml2::XMLElement *DXTFontSize = TrainerKitConfig->FirstChildElement("fontSIZE");
         if(DXTFontSize)
         {
            CustomTrainerFontSize = atoi(DXTFontSize->GetText());
         }

         delete Doc;
         return 1;
      }
   }

   delete Doc;
   return 0;
}



AutoAssembler.h:
Code:

#pragma once
#include "CheatTable.h"

typedef PCHAR (WINAPI *GETCETACKVERSION)();
typedef ULONG (WINAPI *GETADDRESS)(HANDLE processhandle, void *symbolname);
typedef bool (WINAPI *AUTOASSEMBLE)(HANDLE processhandle, char *script, bool enabledisable, bool popupmessages);
typedef ULONG (WINAPI *GETPROCESSIDNAME)(char *processname);
typedef ULONG (WINAPI *GETPROCESSIDWINDOW)(char *classname, char *windowname);

class AutoAssembler
{
   public:
   CheatTable *CT;
   HANDLE ProcessHandle;
   HMODULE CETackDLL;
   bool ShowPopupMessages;

   AutoAssembler(char *CETackDllPath, bool ShowMessages = false); //default: don't show popup messages
   ~AutoAssembler();
   ULONG GetAddr(char *SymbolName);
   bool Assemble(char *Script, bool EnableOrDisable, bool PopupMessages);
   bool AttachTo(char *ProcessName, char *WindowClassName, char *WindowName);
   bool EnableDisableCheat(ULONG ByCheatID, char *OrCheatDescription, bool EnableOrDisable);
   bool EnableDisableEncodedCheat(ULONG ByCheatID, char *OrCheatDescription, bool EnableOrDisable);
   int ToggleCheat(ULONG CheatID);
   int ToggleCheat(char *CheatDescription);

   private:
   GETCETACKVERSION GetCETackVersion;
   GETADDRESS GetAddress;
   AUTOASSEMBLE AutoAssemble;
   GETPROCESSIDNAME GetProcessIdName;
   GETPROCESSIDWINDOW GetProcessIdWindow;
};


AutoAssembler.cpp:
Code:

#include "AutoAssembler.h"

AutoAssembler::AutoAssembler(char *CETackDLLPath, bool ShowMessages) //load the dll, and initialize
{
   if(CETackDLLPath)
      CETackDLL = LoadLibraryA(CETackDLLPath);
   else
   {
      //OutputDebugStringA("Loading CETack lib from memory...[not implemented yet]");
   }

   if(CETackDLL)
   {
      OutputDebugStringA("[DXT-K: SUCCESS!] 'CETK' lib loaded sucessfully...");
      GetCETackVersion = (GETCETACKVERSION)GetProcAddress(CETackDLL, "GetCETackVersion");
      GetAddress = (GETADDRESS)GetProcAddress(CETackDLL, "GetAddress");
      AutoAssemble = (AUTOASSEMBLE)GetProcAddress(CETackDLL, "AutoAssemble");
      GetProcessIdName = (GETPROCESSIDNAME)GetProcAddress(CETackDLL, "GetProcessIdByName");
      GetProcessIdWindow = (GETPROCESSIDWINDOW)GetProcAddress(CETackDLL, "GetProcessIdByWindow");

      if(GetCETackVersion && GetAddress && AutoAssemble && GetProcessIdName && GetProcessIdWindow)
      {
         OutputDebugStringA("[DXT-K: SUCCESS!] Got all 'CETK' lib exports successfully!");
      }
   }

   CT = new CheatTable();
   ShowPopupMessages = ShowMessages;
   ProcessHandle = 0;
}

AutoAssembler::~AutoAssembler()
{
   if(ProcessHandle) CloseHandle(ProcessHandle);
   if(CETackDLL) FreeLibrary(CETackDLL);
   if(CT) delete CT;
}

//Get's a registered symbols address or address of an API
ULONG AutoAssembler::GetAddr(char *SymbolName)
{
   return GetAddress(ProcessHandle, SymbolName);
}

//Assemble method which calls 'AutoAssemble' export from DLL
bool AutoAssembler::Assemble(char *Script, bool EnableOrDisable, bool PopupMessages)
{
   if(AutoAssemble) return AutoAssemble(ProcessHandle, Script, EnableOrDisable, PopupMessages);

   return false;
}

//Attach to process name or window name or class name all in one function
bool AutoAssembler::AttachTo(char *ProcessName, char *WindowClassName, char *WindowName)
{
   if(GetProcessIdName && GetProcessIdWindow)
   {
      if(ProcessName)
      {
         ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, GetProcessIdName(ProcessName));
      }   
      else if(WindowClassName || WindowClassName)
      {
         ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, GetProcessIdWindow(WindowClassName, WindowName));
      }
      else
      {
         //Targeting self...
         ProcessHandle = (HANDLE)-1;
         OutputDebugStringA("[DXT-K: Targeting Self...] You'd better be inside if using it like this!");
         return 1;
      }

      if(ProcessHandle)
      {
         CT->dbg->Print(1, "[DXT-K: SUCESSS!] OP-> \"%s\" / [Wnd: \"%s\"] / [Class: \"%s\"]", ProcessName, WindowName, WindowClassName);
         return 1;
      }
   }

   return 0;
}

bool AutoAssembler::EnableDisableCheat(ULONG ByCheatID, char *OrCheatDescription, bool EnableOrDisable)
{
   Cheat *cheat = 0;

   if(ByCheatID)
      cheat = CT->GetCheat(ByCheatID);
   else if(OrCheatDescription)
      cheat = CT->GetCheat(OrCheatDescription);

   if(cheat && Assemble(cheat->AssemblerScript, EnableOrDisable, ShowPopupMessages)) return true;

   return false;
}

bool AutoAssembler::EnableDisableEncodedCheat(ULONG ByCheatID, char *OrCheatDescription, bool EnableOrDisable)
{
   Cheat *cheat = CT->GetEncodedCheat(ByCheatID, OrCheatDescription);
   if(cheat) //if successfully decoded and got the cheat then re-encoded
      return Assemble(cheat->AssemblerScript, EnableOrDisable, ShowPopupMessages);

   return false;
}

int AutoAssembler::ToggleCheat(ULONG CheatID)
{
   Cheat *cheat = CT->GetCheat(CheatID);
   if(cheat)
   {
      if(!cheat->Enabled && Assemble(cheat->AssemblerScript, 1, ShowPopupMessages))
      {
         cheat->Enabled ^= 1;
         return 1; //Cheat Enabled!
      }
      else if(Assemble(cheat->AssemblerScript, 0, ShowPopupMessages))
      {
         cheat->Enabled ^= 1;
         return 2; //Cheat Disabled!
        }
   }

   return 0;
}

int AutoAssembler::ToggleCheat(char *CheatDescription)
{
   Cheat *cheat = CT->GetCheat(CheatDescription);
   if(cheat)
   {
      if(!cheat->Enabled && Assemble(cheat->AssemblerScript, 1, ShowPopupMessages))
      {
         cheat->Enabled ^= 1;
         return 1; //Cheat Enabled!
      }
      else if(Assemble(cheat->AssemblerScript, 0, ShowPopupMessages))
      {
            cheat->Enabled ^= 1;
            return 2; //Cheat Disabled!
      }
   }

   return 0;
}


And the page formatting is already starting to get screwed up so I suppose I'll have to attach the rest of the source! And See the top of this post where the binary link will be posted (in the binary section, which by the way hasn't seen a new binary release for quite a while Very Happy)!

_________________
Back to top
View user's profile Send private message
Alice0725
Expert Cheater
Reputation: 11

Joined: 24 Jul 2012
Posts: 145

PostPosted: Thu May 23, 2013 5:54 am    Post subject: Reply with quote

Hi, Steve. I've download your DXT-k. Did some modification and made a launcher. Now, It's be a portable D3DTrainer kits. All you have to do it's just download a table and put it to DXT-K dir.

At the same time, I've made some cleanup of CETack( Laughing add a CETack static library too), the file size has decreased more than 20%. So, this DXT-k.dll it's just less than 450kb, mpressed file will be less than 156kb.

_________________
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites