TSearch DMA Tutorial - ASM Game Hacking Explained

Abystus (ported from a SoftIce tutorial by [Sheep])
TSearch DMA Tutorial
ASM Game Hacking Explained
Subject: Code Injection - DMA To Static address with Tsearch
Tools Needed: Tsearch 1.6 or higher
Game Needed: Grand Theft Auto: Vice City
User Knowledge Needed: Basic Asm, Tsearch Functions
Tutorial Difficulty Level: Advanced
Written By: Abystus (aka Epic Cataclysm)
Based on: [Sheep]'s Tutorials for Softice
Time to rewrite one of [Sheep]'s tutorials for those of us who can't seem to fire up the old softice debugger for some reason or another. For those who can, well you are some of the lucky. I however have a radeon 9800, and softice didn't like that. So i have turned to Tsearch which seems to be neck and neck with softice in my opinion. Plus you dont have to worry about games protecting against softice when you are using Tsearch to hack everything that you need. In this tutorial, we are going to hack a vital code for Grand Theft Auto: Vice City. This code is Infinite Health.

Find the Initial Address:
Start a new game and make sure that your health is at 100 %. Next use Tsearch to search for a known value of 17096. Go back into the game and loose a bit of health. Alt+tab the game and do a search for "Value Has Decreased". Repeat this a few times until you come up with an address that works. *Note* Your address will not be the same as mine because of DMA.

Time to get Around DMA:
My address is A02DDE6. This is a DMA address and is not static. We need to set a breakpoint for read/write on this address to see what is reading and writing to this address. In Tsearch go to the menu "AutoHack" and choose "Enable Debugger". Next go to menu "AutoHack" and choose "AutoHack Window" to show the AutoHack window. Next go to menu "Edit" and choose "Set BreakPoint". A new screen will come up asking your for the address to set the breakpoint on, how many bytes, and the type of breakpoint. Enter your address that you found above, leave the byte settings like they are, and then choose "Read/Write" from the breakpoint list. Click "Set" to set the breakpoint for read/write on your address. REturn to the game and run around for a sec or so, then alt+tab and check autohack window. Notice all the offset addresses from your DMA address.

For Vice City the decreaser address affects everyone in the game, and not just you. Meaning that if you lock it then everyone in the game becomes immortal when you do. If you would have just set a write breakpoint you would have gotten just the pointer address that decreases everyones health, which is useless to us.

These are the offsets that you should see in the autohack window:

501973: fld dword ptr [ecx+0x354]
505CEA: fld dword ptr [ebx+0x354]
50A66B: fld dword ptr [ebx+0x354]
509FBB: fld dword ptr [ebx+0x354]
50F3A6: fld dword ptr [eax+0x354]
558A9D: fld dword ptr [eax+0x354]
558B41: fld dword ptr [eax+0x354]
5D30BC: fld dword ptr [ebp+0x354]
5267C0: fld dword ptr [ebx+0x354]
5267DE: fld dword ptr [ebx+0x354]
5267E8: fstp dword ptr [ebx+0x354]
5D3ABF: fld dword ptr [ebp+0x354]

Next we must set a BPX, or break on execution, on each of these addresses so that that we can see if they return a value. To do this, we take each address (example 501973) and go to menu "Edit" in the autohack window and choose "Disassemble", and enter your address. Choose the Disassembler tab from the bottom and you will see your address listed at the top. Right click your address from the list and choose "Register". Go to the register tab and you will see your address has been set for a Break on execute. Next look at the register that goes along with the address ([ecx+0x354] EAX in 501973's case), and choose it from the register list. Next click the box to the left of your address to enable the break and return to the game. Run around for a sec or so and alt+tab the game. If your address returns any value other than 0 and doesn't fluctuate in value then write the address down in notepad. Continue through all the values above until you have a list of working addresses.

My addresses are:

501973 fld dword ptr [ecx+0x354]
505CEA fld dword ptr [ebx+0x354]
50A66B fld dword ptr [ebx+0x354]
509FBB fld dword ptr [ebx+0x354]
558A9D fld dword ptr [eax+0x354]
558B41 fld dword ptr [eax+0x354]

All of the addresses above should have returned the same value. That value that they returned is an address in itself (remember, these are pointers to an address that holds a value of your life).

Ok, now gain some life to get your health % back to 100. Then take the value/address returned by the pointers above

Take the value of one of the pointers listed above and replace the original address you hacked (DMA address) with the value + 354h (example A01F331h + 354h = A01F685h). The reason we added 354h is because the pointer told us to add 354h to the register value. The value of that address that you just inserted will automatically change to a your health value. You address should return 1120403456 which is full health. Notice that in this game is it different from its counterpart value 17096 (DMA Address, Value).

Building Our Code Cave:
First thing we need to do is convert the value returned by the register value + 354h which is 1119754650 and convert it to hex which is 42C80000h. Next we will start building a code cave structure so that we can test our pointers above.

Memory in most games gets allocated from 0x10000, is used till 10950.., and then thereafter is empty space. So I am choosing 0x10bb0 to write my code cave to.

Ok, so we are ready to write some asm code now. Open the easywrite window by clicking the icon. Choose a new project and give that project a name (example "infinite health"). Next, write the following into the upper text area. Then press the "check" button to make sure everything is ok. Finally, press "OK" to save it.

offset 0x10bb0 <--- Address of our code cave
mov dword ptr [eax+0x354],0x42C80000 <--- Write max health into our health pointer
fld dword ptr [eax+0x354] <--- Reconstruct original instruction
jmp 0x501979 <--- Jump Back to original routine
offset 0x501973 <--- Address of our gateway
jmp 0x10bb0 <--- Jumps to our code cave
nop <--- Balance the instruction

To make the asm that we just wrote run, we need to check the little box to the left of "infinite health" (or whatever you've titled it), and return to the game to see if it worked. We are using the first pointer address 501973 in the above code cave. This code will write 42C80000h (1120403456) to each address you set it up with. Go through and test each pointer this way by replacing the pointer address 501973 and next address in line 501979 with a new address from above and the following address in line after it. To get the next address in line after your pointer address just go to the autohack window, choose "Disassemble", type your address in and then choose "Disassembler" tab from the bottom and look to see what address follows.

Through trial and error of 6 pointers you will find that the pointer of choice would be 558B41 fld dword ptr [eax+0x354]. It is the only one of the above codes that makes you invincible and everyone else mortal. So our code cave should look as follows:

offset 0x10bb0
mov dword ptr [eax+0x354],0x42C80000
fld dword ptr [eax+0x354]
jmp 0x558B47
offset 0x558B41
jmp 0x10bb0

To set the instruction of your address back to normal enter the asm below into the bottom text area, press "check" to make sure it is error free, and then "Ok" to accept. This sets the offset back to its normal instruction set (Letting you become mortal again).

offset 0x558B41
fld dword ptr [eax+0x354]

Converting Code Cave to TMK addresses:
To get the addresses to poke in TMK from the asm code we just created, in the easywrite window press the "TMK" button, then the "Check" button to reveal what you should put in TMK to get your code cave to work in a trainer.

Your converted code should look like:

Our Code Cave:

Poke 400E00 C7 80 54 03 00 00 00 00 C8 42 D9
Poke 400E0B 80 54 03 00 00 E9 32 7D 15 00
Poke 558B41 E9 BA 82 EA FF 90

Set Address Back to Original Instruction Set:

Poke 558B41 D9 80 54 03 00 00

Special thanks to all that helped:
[Sheep], Sain, Fahrenheit and anyone else that I am forgetting to mention.

No order, just great people...