Display results as :

Rechercher Advanced Search

Latest topics
» ~=?{The future is here, TastyExploit officially open to the public}?=~
Tue Mar 02, 2010 11:00 pm by Dami

» My first aa script
Tue Mar 02, 2010 7:00 am by wafflemaster

» the real story behind Maverin
Tue Mar 02, 2010 1:33 am by SoundOfDeat

» Random spam
Mon Mar 01, 2010 11:52 pm by Danny1994

» [Request] EMS v56 Exe
Mon Mar 01, 2010 12:39 am by Dami

» [Blacklist] NX-Trading Blacklist.
Mon Mar 01, 2010 12:38 am by Danny1994

» I have a question regarding the meso farmer
Sat Feb 27, 2010 10:30 pm by Dami

» What are you listening to now?
Sat Feb 27, 2010 7:57 pm by Noname111111

» Video(s) Of The Day
Sat Feb 27, 2010 7:37 pm by Noname111111

free forum

Creating A Simple In-Game Trainer

Go down

Creating A Simple In-Game Trainer

Post by Dami on Fri Oct 30, 2009 6:11 pm


I wrote this tutorial a few months ago.

I tried to make this tutorial and the example codes as understandable as possible.

The following can be used in nearly any game.
I will not provide any screenshots and this is not a spoonfed tutorial.
Most examples are in AA style because I don't know all the code sizes (for a per address example). I wrote the final example in ollydbg style, so refer to that if the AA style confuses you.
The PE header in this tutorial is at 0x00400000.

- Basic knowledge of the x86 assembly language.
- Basic knowledge of PEs.
- Basic knowledge of win32 API.
- A little bit experience with both CFF explorer and ollydbg.
- CFF explorer
- An unpacked version of the target.
- And last but certainly not least, ollydbg.

Alright, fire up CFF explorer and load the target in CFF explorer.
The first thing we should do is create a nice little space for our trainer and the hook that will create our trainer.
Create a section (I always set the size to 0x1000), be sure to set the section flags correctly else it will **** up. (I always use E0000020), write down the virtual address of our section.

Now we should check if the IAT has the functions we need, add the functions if they are not complete;
We use: CreateThread, GetASyncKeyState and Sleep in this tutorial, alternates are:
- keybd_event/mouse_event or Send/PostMessage or a directinput hook or whatever for an implented bot.
- The use of GDI functions or a directx hook for an ingame GUI.
- LoadLibraryA/W/ExA/ExW if you want to include dlls.

Be sure to get the offsets of the required APIs, write them down. (CreateThread, GetASyncKeyState and Sleep)
If the imports aren't added, you should add them yourself;
To add an import, go to import adder and add the import from the dll (CreateThread and Sleep are kernel32.dll, GetASyncKeyState is in user32.dll)
Now we will get the offsets of the APIs and write them down (my CFF explorer has a calculation error and it ****s up sometimes, so if the offset is wrong you should search around a little or check intermodular calls in olly) go to import directory and go to the dll that contains the import, now find the API and click it, then write down the value that appear right under the "FTs (IAT)" (not under the Dword). Do this for all the APIs we need.

NOTE: the IAT_ApiName here is 0x00400000+the api offset you wrote down.

Now we should save our file, go to the section headers, right click and rebuild image size AND pe header. Then save the file.
We are done in CFF explorer now, close it and open your file in olly.

The first thing we want to do is decide how it creates our trainer thread.
We can do this 2 ways;
- We can set the EP to our code (the added section) in which we will create the thread and then jump back to the OEP.
- We can hook a part of the EP to jump to our CreateThread code, place the overwritten instructions there, and jump back.

Do whichever you like, just don't **** it up (stack).

We will write this all later, first we need to write our own code;

For our CreateThread code, you need to know the CreateThread API:

  SIZE_T dwStackSize,
  LPVOID lpParameter,
  DWORD dwCreationFlags,
  LPDWORD lpThreadId

As you know, it is pushed "vice-versa" in ASM in simple terms.

Go to our code section (0x00400000+the virtual address)

Now we will write our code: (in this example I pretend like 0x00702000 is our code section), I use the AA style here, because I don't know all the code sizes.

push 0 // lpThreadId
push 0 // dwCreationFlags
push 0 // lpParameter
push 00702100 // lpStartAddress
push 0 // dwStackSize
push 0 // lpThreadAttributes
call dword ptr [IAT_CreateThread]
possible overwritten code here
jmp back

00702100: // lpStartAddress
... Thread code here, we will write this later.

Now we will write our "trainer".
There are several methods to implent "hacks";
- Writing: Using mov's and rep mov's (string operations) you can write bytes, words, dword, array of bytes, array of words and array of dwords.
- Hooking (code injection): Infile changes to a code so you can alter it freely in your code.

Example writing:

00702200: // our write code
cmp byte ptr [00705000], 1 // check if the user wants it "on" or not, we will come to setting these values later
jne 00702300 // else dont execute the write
mov dword ptr [00405000], 12345678 // sets the (DWORD)value of 00405000 to 12345678
mov ecx, 7 // 7 bytes
mov esi, source // source = address holding our 7 bytes to be written
mov edi, 00406000 // 00406000 = address we want to write to
rep movsb // move our bytes

Example hooking:
jmp 00702200

00702200: // our hooked code
cmp byte ptr [00705000], 1 // check if the user wants it "on" or not, we will come to setting these values later
jne 00702300 // else dont execute our functions
push eax // Store registers in stack here
mov eax, [00620000] // example code
mov eax, [eax+0C] // example code
mov [ecx], eax // example code
pop eax // Register restore here
00702300: // pretend like this is the next address after the previous pop eax
Overwritten code(s) here
jmp 00407005 // jmp back

For our GetASyncKeyState code, to capture keystrokes and handle them and an example of Sleep (to keep things in the hand):

00702100: // our thread
push 64 // 0x64 = 100
call dword ptr [IAT_Sleep] // Sleep for 100 msec
push 61 // 0x61 = (VK_KEY)numpad 1
call dword ptr [IAT_GetASyncKeyState]
test eax, eax // orly
jnz 00702200 // jump if pressed to our bool handler
.. blahblah next thingy here

00702200: // I KNOW there are faster and better ways to do this, I'm just using the easy understandable method
cmp byte ptr [00703000], 0 // our bool
je 00702220
mov byte ptr [00703000], 0
jmp 00702230
mov byte ptr [00703000], 1
jmp 00702160

For the complete virtual key list, go HERE.

Now for our final example code (olly style):

00702000  PUSH 0
00702002  PUSH 0
00702004  PUSH 0
00702006  PUSH 70201A // our thread
0070200B  PUSH 0
0070200D  PUSH 0
0070200F  CALL DWORD PTR DS:[IAT_CreateThread] // Call CreateThread
00702015  JMP 00401000 // jump back to EP or next code (depending on what kind of method you chose)

0070201A  PUSH 64 // 100
0070201C  CALL DWORD PTR DS:[IAT_Sleep] // Sleep for 100 msec, to prevent heavy lag, you can alter this if the keys ****up (too little or too big sleep)

00702022  PUSH 61 // NUM_1
00702024  CALL DWORD PTR DS:[IAT_GetASyncKeyState] // check keystate
0070202A  TEST EAX,EAX // check if pressed
0070202C  JNZ SHORT 00702060 // if pressed goto

0070202E  PUSH 62 // NUM_2
00702030  CALL DWORD PTR DS:[IAT_GetASyncKeyState] // check keystate
00702036  TEST EAX,EAX // check if pressed
00702038  JNZ SHORT 0070207B // if pressed goto

0070203A  CMP BYTE PTR DS:[702200],1 // check if BOOL1 is true
00702041  JNE SHORT 0070205E // if not true go to the next write (none here, so it jumps to the jump back to the start)
00702043  MOV DWORD PTR DS:[405000],12345678 // if its true it does the write here, check the example I wrote earlier if you dont understand the next codes
0070204D  MOV ECX,7
00702052  MOV ESI, 00800000 // our source
00702057  MOV EDI, 00406000
0070205C  REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] // rep movsb
0070205E  JMP SHORT 0070201A // jmp back to the very start of this function

00702060  CMP BYTE PTR DS:[702200],0 // BOOL1
00702067  JE SHORT 00702072
00702069  MOV BYTE PTR DS:[702200],0
00702070  JMP SHORT 00702079
00702072  MOV BYTE PTR DS:[702200],1
00702079  JMP SHORT 0070202E

0070207B  CMP BYTE PTR DS:[702201],0 // BOOL2
00702082  JE SHORT 0070208D
00702084  MOV BYTE PTR DS:[702201],0
0070208B  JMP SHORT 00702094
0070208D  MOV BYTE PTR DS:[702201],1
00702094    JMP SHORT 0070203A

00702096  CMP BYTE PTR DS:[702201],1 // jmps at 00407000 goes here
0070209D  JNE SHORT 007020AB
0070209F  PUSH EAX
007020A0  MOV EAX,DWORD PTR DS:[620000]
007020AA  POP EAX
007020AB  NOP // overwritten code here
007020AC  JMP 00407005 // jmp back

Posts : 1414
Join date : 2009-08-10
Age : 28
Location : Finland

Back to top Go down

Re: Creating A Simple In-Game Trainer

Post by Tom on Fri Oct 30, 2009 7:06 pm

Thanks for posting this Dami, I am going to attempt this soon Smile.
New member
New member

Posts : 63
Join date : 2009-09-17
Age : 22
Location : England, a dump.

Back to top Go down

Back to top

- Similar topics

Permissions in this forum:
You cannot reply to topics in this forum