This TuT is actually kinda old but many have forgotten about it. I did not make this tut. Credits go to Psych NOT ME. Only thing I added to this is where you can find a list of games using the Unreal Engine 2.
---------------------------------------------------
Subject: Hacking Health in Unreal Engine 2 Games
---------------------------------------------------
Author: [Psych]
--------------------
Difficulty: Advanced
---------------------------------------------------------------------------------------
Pre-reqs: Knowledge of DMA, debugging, code-injection and code-shifting would be ideal
(This is so you can relate better to what is happening during this tutorial)
----------------------------------------------------------------------------------------
Target: Unreal Tournament 2004 Demo (v3334)
-----------------------------------------------
Date: 04-10-08
--------------------
================================================== ======================================
------------------------------------------------------
*Best read at 1024x768px or higher with word-wrap on*
------------------------------------------------------
-------
|Intro|
-------
Welcome to another tutorial! This will cover a method of obtaining infinite health/god mode in games based on the Unreal 2 engine. This was recently brought to my attention on a forum, and I decided to make a tutorial out of it, so others can benefit. I will try to make this tutorial as clear and as accurate as I can. If anyone has any suggestions, feedback or requests, please send it my way: psych[at]live[dot]co[dot]uk (spamproof, replace the works in brackets).
This tutorial may be translated if someone wishes to do so, but please let me know this is happening so I can review it. Like all my tutorials this document may be posted freely on any site on these conditions:
- It doesn't infringe upon the specific site rules
- All credits are left intact
- It isn't altered in any way
- You don't rip elements from it and claim as your own
With that out of the way, i'll just mention the target game briefly. UT2004 is based, unsuprisingly, on the Unreal 2 game engine. A framework if you will, on which many other games where also based upon. This game is now fairly old, but I believe there is still something for people to learn from this. Besides, there was only ever 1 trainer released for this game, and that sported a most fantastic +1 option! Granted, certain aspects of gamehacking and reversing were harder back then, with less tools and features that could make life easier.
I will cover a method of creating a God Mode/Infinite Health hack for this game. The same principal can be applied for other options too, be it adrenaline, ammo, armour or even the game timer. I will assume that you have a good understanding of memory searching, know what DMA is (and how to beat it), code-injection techniques and what code-shifting is (and how to beat it). I have to assume this, because otherwise I would spending most of my time explaining fundamental concepts rather than been able to focus on the improtant bits of this tutorial.
So, lets get underway...
------------------------
|(1) Finding our health|
------------------------
Load into the game and search for your current health value. After all the usual scanning and filtering you should be left with about 4 results. One of these is the real address. Using trial-and-error find out which one has an effect on your real health address in-game. The real one may not necessarily be the one that makes a visual change on the game screen. Keep that in mind. Raise the value and get hit by an enemy to test it.
---------------------------
|(2) Debugging the address|
---------------------------
Once you have it we need to debug the address. We will set a write breakpoint on the address, and not a read breakpoint. Why? Because in the majority of cases, the opcode what writes to your address is the one that ultimately causes us to die. So if we intercept this opcode and modify the gamecode here, it is a much more effective way of creating infinite health. Suppose we found an opcode which accessed our health, and it did that many times a second. We could inject code here to always write max health into it. That would probably be sufficient enough for protecting against bullets and small explosions and falls, but a huge amount of damage could still take away all of our health in one go, before the instruction has a chance to refill the health amount. Use whatever debugger you prefer. Softice, Olly, CE, MHS, any you want. Get hit and we will break. A snippet of my results follow:
101268A6 - 8b 03 - mov eax,[ebx]
101268A8 - 8b 54 24 10 - mov edx,[esp+10]
101268AC - 29 d0 - sub eax,edx
101268AE - 89 03 - mov [ebx],eax <-- I break Here
101268B0 - 8b d8 - mov ebx,eax
101268B2 - 8b 44 24 14 - mov eax,[esp+14]
These results will be different on a restart of the game as the game uses code-shifting. It's .dlls get loaded into different locations at runtime. Therefore if you are to commit any hacks into a trainer, you must make sure your trainer has a function to calculate the base address of the module, add the offset and then write to that location. There are tutorials for this floating around. For this tutorial, just remember that the above opcodes reside in the core.dll module. We'll need to have this information later.
I break at the location I have indicated above. The new value of EAX (the health value) has been calculated and is been stored into memory. EBX at this location holds our current health address when we break. However, EBX will not always hold our health address. As well as controlling the enemies health, this routine is also used for many other game functions, such as ammo and timers. So we need to find some way of differentiating our health address with any other address that may end up landing in EBX. On many other games, this would simply be a case of finding some area of memory to compare with, or it may be that a certain register could hold an ID that would identify the player. Or, we could find an instruction that accesses only the player, dump the address, and then compare EBX at this location with the address. With the unreal engine 2 though, this is extremely difficult. All opcodes that you bring up are shared between player and enemy, and deal with other variables too. So, what the hell do we do now? I will demonstrate one method of doing this, that works.
--------------------------------------
(3) Finding something to compare with|
--------------------------------------
Note the address of that instruction down, we'll need to use it again later. Now, cheat engine (CE) has a feature for pointer scanning. MHS has a similar feature, but as CE is my memory scanner of choice, i'll be referring to that. We will run a pointer-scan on the health address to see if we can find a path in memory that will always lead us to our location of health. This path would always be valid after a respawn, reload or restart, and so we would be left with something static to compare with.
Right-click the address and CE and choose pointer scan (default option is fine). All fields can be left at the defaults with the exception of a few. Firstly, on the left we have a list of currently loaded modules. We need to choose the core.dll module, as that is where we landed when debugging earlier. There is a high probability that there will be a pointer path in this module that will reference the player health at all times. Notice that CE will auto-populate the base pointer path with the start and end addresses of that module. If you have a dual-core CPU or an otherwise fast processor, then it makes sense to increase the number of threads scanning a little. In the max level field choose 2. This is how deep we want to scan for pointers. A level one scan is rarely useful, and the chance of there been a base pointer at that level is very low on most modern games. The size of structure should be set at 2048.
Hit scan...
When this pointer scan has finished, you may be left with anywhere from hundreds to thousands of results. Just like when scanning for normal memory addresses, we need to filter that amount down. Most of these will become invalid after a few seconds/minutes, some will become invalid after dying, some after reloaded and so on. So with that knowledge, die in game and respawn. Re-find your health value (make sure to test it to make sure it is indeed the real one), and then in the pointer scan window choose Rescan memory from the menu. Input this new address and hit ok. It will narrow the results down. You will still have a lot though, so repeat the above process until you are left with a handful of addresses in the scan window. Mix it up a bit. Restart the game, change gamemodes and so on to try to eliminate bad pointers faster.
When you are left with a manageable amount, double-click on them all to add them to the cheat list. If at any point you see one point to the wrong address or hold a strange value then delete it, as its not stable enough for our usage. One last time, kill your player, but keep an eye on what the pointers do when your character is in the dead state. We need to keep those that point to nothing (????????), but delete the ones that revert to a high value or some other address. This will just make things easier later on. At this point, after that work, you may wish to ensure you have saved these results.
We now have at least a couple of stable pointers that will always point to the current players health, no matter what. We can now go back to the previous instruction we found that writes to the player health value, and create an injection. For the purposes on this tutorial, I will display a pointer I found. I will use this in the next section for creating the hack. If you are using the same game and version as me then this will work for you as well:
[ [ [ Core.dll+00164570 ] + 350 ] +470 ]
Putting this another way:
Core.dll+00164570 is the base + offset we need to use as the game is code-shifting.
This base address will be different each time, so to reach it we need to use base + offset notation. What CE is doing for us, is reading from that base address and finding what value it holds. The value is holds is another address, which it is essentially pointing to. Onto this address we simply add the value 350 which you can see above, and this gets us to level1 of the pointer path. Again, this address is read for its value, which is an address like before. Onto this address we add the final offset of 470 which gets us to the current health address. And thats all it is.
What you can do is make a trainer calculate the above address and then write to that health value. You would have to include a function to calculate the base address of Core.dll, and then add the offset to get the base offset (look into using CreateToolHelp32Snaphot, and search for tutorials on code-shifting for more on this). Then you would need to use ReadProcessMemory and WriteProcessMemory in order to calculate the pointer levels and write to the resulting address. However, this would not be a true god mode as you could still be killed if you got damaged enough. It is also extremely bad practice to use pointers as they are in trainers, as you are relying very much on the trainer engine itself rather than making the gamecode do what you want.
-----------------------
|(4) Creating the hack|
-----------------------
Ok, referring back to this code:
101268A6 - 8b 03 - mov eax,[ebx]
101268A8 - 8b 54 24 10 - mov edx,[esp+10]
101268AC - 29 d0 - sub eax,edx
101268AE - 89 03 - mov [ebx],eax <-- I break Here
101268B0 - 8b d8 - mov ebx,eax
101268B2 - 8b 44 24 14 - mov eax,[esp+14]
We need to create a compare in here which will ensure we only end up writing max health when EBX = player health address. If we mess up here, with such a strongly shared instruction, it will most certainly have disastrous effects on the game. I have chosen to create the whole injection first. What I will then do is break it all down, and explain what it all does. I written this in a pseudocode style, so its a little easier to follow:
.--> <cave>: //empty cave location
| mov edx,[esp+10]
| sub eax,edx
| push eax
| mov eax,[core.dll+00164570]
| mov eax,[eax+350]
| lea eax,[eax+470] //move our address into eax
| cmp ebx,eax //is this player health?
| pop eax
| jne <end> //if its not, then skip
| mov eax,64 //if it is, copy full health
| <end>:
| jmp <gamecode> ->. //jump back to normal gamecode
| |
| core.dll+268a8: | //where we jump out from...
^<-- jmp cave | //...to our cave
nop | //clean-up leftover bytes ^_^
<gamecode>: <-' //this is where we jump back to later
Alright, firstly we create the cave, which we will use to store our injection. This is where we will route the flow of execution from the original code, through our own, and then back where it needs to be. Simple code-injection concept.
I have chosen to jump out of gamecode before the instruction we need. This, for me, was the best approach to use here. This means that I am recreating two destroyed instructions as the first step in the cave:
mov edx,[esp+10]
sub eax,edx
Just for your information, there was a call just before these two opcodes, and in this call, the game determined the value to take away from eax. A damage value in this case, as when we get hit, the game uses this code to handle health. So thats what is happening here. EDX is handed this amount, and then this is taken away from EAX.
Right, now we get to work. This is where the whole compare and modified code comes into play. The push eax instruction is saving the value of EAX. We are doing this because we are about to use eax as a temporary holding area, so we will need to restore it later to make sure the game continues as it should (without bad side-effects).
We copy the pointer base address into EAX. We then add the offsets, by moving the value held in [eax+350] into EAX (level1) and then [eax+470] into EAX (level2). This results in the current player address sitting in EAX. If you remember from earlier EBX held the address of player health when we got hit, so this is what we will compare with. We compare eax (always points to player health) with ebx (only player health when we get hit), and also pop eax (as we don't need it anymore). If it is not equal we break out of the code and ultimately jump back to normal game code. If, however, it is equal, then we know its the player health address and so we continue.
Following on from above, we now copy the value of 0x64 (100 in decimal - full health) into eax. Now at this point we jump back to normal gamecode. The address that follows this injection is the one we first broke at:
101268AE - 89 03 - mov [ebx],eax
What happened in the cave will determine what value is passed here into the address. If it was the player getting hit and losing health, then EAX will be holding 100, which will be placed into the player health address, making us invincible. If on the other hand this wasn't the player getting damaged, then this instruction will be doing something different entirely, which we are not concerned about. As long as we make it so that gamecode executes normally if it doesn't match up with the pointer, then nothing bad will happen.
-------
|Outro|
-------
And thats it. That brings us to the end of this tutorial. I hope everyone got at least something new out of this. It wouldn't be much of a tutorial if it didn't benefit at least some people. Now I expect at least one of you reading this to make a trainer for this game and send it to me. You can use this approach for other varibles in game too, so theres no excuse for a +1 trainer!
--------
|Greetz|
--------
Greetz fly out to my Team over at extali*****m and all those that contribute there,
all those at gamehacking.com and doxcoding.com, Wiccaan, RiSiCO, Sunbeam, Lab, STN.
Finally, keep up the good work Brewers, ASXDox, Unleashed & Reloaded...
~Psych
Added by Me:
List of Unreal Engine games - Wikipedia, the free encyclopedia
This works for all games using the engine just the coding WILL defer.