Go Back

Alien Breed: Impact

I recently bought Alien Breed: Impact from Steam, an Arcade Shooter (as they call it themselves) that gave me back 'old' feelings (they don't make that many games like it anymore). Anyways, I played it for a while but the controls of the game are horrid. I ended up getting annoyed by the controls. So the logical next step is to hack it ;)  By the way, if the controls where better, it would be a lot more fun to play.

However, Alien Breed uses the Unreal 3 Engine. Several other games use it too, like Mass Effect 2, which made me 'worry' a bit. The Unreal 3 Engine takes OO-programing to another level. As soon as I found some values (ammo/health) my suspicions where confirmed. Just like Mass Effect 2, Alien Breed uses 1 function to subtract nearly every value in the game.

Initially I wanted to give up, not that hacking it is impossible. It is just a lot of work and is it really worth it? I decided not to give up. And my decision will probably make me look into Mass Effect 2 again.

After putting a (memory-write) break-point on the ammo value, I saw that the instruction at 0x4BE228 is responsible for subtracting health, ammo, enemies health, cash, etc. Replacing the the "sub [ebx], eax" instruction with nothing (nop's) worked.  Ammo was frozen and I couldn't die. But it also made it creatures, windows, etc invincible.

The next step in the chain was to trace (using Syser) the function's return address (which was 0x4C5331), that was a dead-end too. All values used this same function. Instead of digging deeper, I decided to try and find something in the call-arguments of the subtract function (0x4BE180) that allowed me to identify the values it was subtracting from.

To do this I had to figure out a bit on how the subtract function worked. This wasn't easy, mainly because the function accepts a wide array of values it has to subtract from. Through tracing I found out that the first call within the function (call edx at 0x4BE1B5) retrieves the pointer to the value it is going to subtract from.

Looking at the first call that it does, we find out it bases this call on the value that is present at the first argument + 0x18 (it loads the first argument in esi @ 0x4BE183 and then loads a the pointer from [esi+0x18] into eax). It loads a byte from the pointer that it gets, and then uses that to call the function for the address to the value. For ammo, health, cash, that value is 1. The function that it calls when the value is 1 is 0x4BB610.

Inspecting this function gets us to the following conclusion, [[[first argument + 0x18] + 0] + 0x64] contains the offset of value compared to the class that is calling the subtract function. While checking out the memory address that [[first argument + 0x18] + 0] points to, I saw that [[[first argument + 0x18] + 0] + 4] points to a value identifier. For ammo this identifier is 32810 and for health its 5685.

With this info we can determine when to subtract the value, and when to keep the value the same. The problem however was that the function overwrites several things before it finally gets to the actual subtract instruction (at 0x4BE228). So the decision to subtract or not would have to be made at the start of the function. (perhaps its possible to get the  original esi value back, but I gave up looking for it)

This brought me back to the function that calls our subtract function, which was the 0x4C5331 function (or well, thats the return address). In this function we see that it gets the subtract function from a look up array (see 0x4C5322), using Cheat Engine we find that the subtract function-address is stored in 0x11C9438. I decided to make a detour function and write its address into 0x11C9438.

With the detour function in place, my first try was to not-execute the subtract function if it concerned ammo/health/etc. This quickly led to a crash. Apparently the subtract function does more then subtract. My next try was to get the pointer to the value, and increase it with the value being subtracted (as such, subtract would then have no effect). This quickly led to an issue, the value it subtracts from the main value (ok too many value's in one sentence) is also stored in an object.

It was getting late, and I was getting bored real quick with these objects in objects. So I decided to actually change the code depending on the main value. If the value is ammo/etc, I change the subtract instruction at 0x4BE228 to nop, if the value is something else, I change subtract the instruction at 0x4BE228 back to its normal value.

This worked!  So while probably not the most elegant method to success, it definitely works. I had to put in one additional check for Health. Because the Health identifier was the same for everyone (e.g. also enemies), I had to check if the health was player-health or enemy-health, I did this by checking the v-table of the calling-class (for the player its 0xF4FE60).

The end result is this +4 trainer.

Posted by: Da_Teach on Saturday, July 3, 2010  •  Comments (83)  •  Full story  •  C# Code Injection Pointers Syser Codecave Trainer Alien Breed: Impact

Torchlight Part #2

And I thought I'd seen it all, but I was wrong :)  I have to admit I knew it was possible, but I never ever saw an executable change its base address each time it loads. That is, until I loaded up Torchlight.

While it was always on the 'standard' base address in my virtual pc (40000h), on my main pc it kept changing. Could it be a Windows 7 64-Bit thing?

Anyway, this means that all pointers have to be relative to the base address, not fixed. Its not a huge issue, whenever you find a pointer just subtract the base address from it and you have the relative pointer.

But back to the Torchlight and using a code cave. As I mentioned in part #1, I wanted to try something different. Instead of allocating memory for my code detour, I decided to use a code cave instead. Using the handy code cave finder in Cheat Engine, I found that at Torchlight.exe + 2D0h there's a code cave big enough to fit my injected code.

I decided to inject this code (I highlighted points of interest using bold-comment code):
2D0 - push eax // Start of new-health detour
2D1 - call 2f1 // Compare ESI to the Player / Pet Pointer
2D6 - cmp al,00 // Is it an enemy?
2D8 - je 2e5 // Yes, set the new health
2DA - fcom dword ptr [esi+00000394] // No, is the new value higher?
2E0 - fnstsw ax
2E2 - sahf
2E3 - jb 2ed // No, its lower
2E5 - fstp dword ptr [esi+00000394] // Set the new health value
2EB - jmp 2ef
2ED - fstp st(0)
2EF - pop eax
2F0 - ret // Return back to the normal flow (end of new health detour)
2F1 - mov eax,[Torchlight.exe+A2B6A4] // Load base pointer (start of player / pet compare)
2F6 - mov eax,[eax+1c] // Load actual player pointer
2F9 - cmp eax,esi // Compare player pointer to ESI
2FB - je 312 // Is it the player?
2FD - mov eax,[Torchlight.exe+A2B6A4] // Load base pointer
302 - mov eax,[eax+000002d4] // Load pet offset
308 - mov eax,[eax+2c] // Load pet pointer
30B - cmp eax,esi // Compare pet pointer to ESI
30D - je 312 // is it the pet?
30F - mov al,00 // Its an enemy
311 - ret // End of player / pet compare
312 - mov al,01 // Its player or pet
314 - ret // End of player / pet compare
315 - push eax // Start of new mana detour
316 - call 2f1
31B - cmp al,00
31D - je 32a
31F - fcom dword ptr [esi+000003b8]
325 - fnstsw ax
327 - sahf
328 - jb 332
32A - fstp dword ptr [esi+000003b8]
330 - jmp 334
332 - fstp st(0)
334 - pop eax
335 - ret // End of new mana detour

The above code shows 3 functions, the first function is the "new health" detour function. It checks it the health is set for an enemy or player (or pet). If its the player then it will check the new health, if its lower then it wont set the new health, if its higher it will set the new health.

That function is then copied to the "new mana" detour function (the last function).

The middle function is a small helper function (as I needed it for both new health/mana detours), it will compare the esi register with the player/pet pointers and return 1 (player/pet) or 0 (enemy).

I can write this injected code into Torchlight.exe + 2D0h, I can then detour the new health/mana instructions using a call to this injected code. And voila, you cant die, but when you level up you can get more health :)

I do have to say that my first code cave experience was a good one and I'll probably use them more. A nice thing is that almost all the injected code and detour code doesn't change because the code cave doesn't change its address.

In the trainer that I put online I added a few functions. Like change your experience, fame, pet experience, money, stat points and spell point. You can also freeze the enchantment difficulty of items. It'll basically let you enchant with almost no risk (there's still 2% risk).

You can download it here, enjoy.

Posted by: Da_Teach on Friday, January 22, 2010  •  Comments (13)  •  Full story  •  Code Injection Torchlight Codecave

Trine Part #2

I planned to write this blog a few days ago, but my main PC (the one I hack on) decided to die on me and couldnt get it fixed until late last night. But its up and running and I finally got around to finishing my trainer for Trine.

As mentioned in my previous blog, turning on "Unlimited Health" made enemies invincible too. That ruins the playability of the game a bit. So one of the first things you check is to see if the function that decreases health is used on a different spot for players then for enemies. This wasn't the case, my guess is that the players are part of the same entity-array as the enemies.

Since we couldn't use that as a base-reference, I did a quick search  (using Cheat Engine) for a static address for the player-structure. Perhaps its in there somewhere, but I got bored of looking for it ;)

So whats left? Well figure out how the game "knows" its a player instead of an enemy. I wont post the entire decompiled function (it has 1300 lines!) but you can download it by clicking here.

If you download the function, then you'll see that at line 1254 the new health is calculated. Whats interesting is the part where it would decrease the damage by certain collectible items. It starts at line 1186 and ends at 1249. Now I didnt really care to figure out what it did there, but the if at line 1186 was interesting.

This "if ( (a2->byte212 && a2->dword1D4 || a2->dword1CC) && a2->dword960 != 1 )" basically checks if the current entity is the player or an enemy, as enemies don't have items. Some further analysis (using pointers found with Cheat Engine) reveals that pointer + 960h = 2 for a player while its 1 for enemies.

Now we have a way to check if the type of entity (who's health is being decreased). Now we have to modify the instruction at 691BB2h to only decrease health for enemies. However we can't magically add instructions to an executable, so we have to allocate some memory (or use a codecave, but thats something for another day) in Trine, write the instructions in there that we want to "add" and then redirect the program flow to this newly created piece of code.

First we have to write some assembler which we can write to the allocated piece of memory, I chose for this:
cmp dword ptr [ebx+960], 2  // Check if its a player
je 691BB8 // Yes, jump back
mov [ebx+254], esi // No, decrease health
jmp 691BB8 // Jump back

What we basically do is check if its a player, if it is we jump back to the original function, if its not we decrease health and jump back. We have to decrease the health, because thats the function we are replacing. You could possibly change "mov [ebx+254], esi " into "mov [ebx+254], 0" which would instantly kill everything when you hit it.

After we created this code inside our newly allocated memory, its just a matter of replacing the instruction at 691BB2h with a jump to our piece of code and voilla. Players stay alive and enemies die.

I made a small trainer which you can download here. It includes a modified "Unlimited Energy" as nop'ing that function didn't always have the desired effect. My new modification is to always write the maximum energy into the current-energy field.

Posted by: Da_Teach on Saturday, January 16, 2010  •  Comments (13)  •  Full story  •  Code Injection Trine Decompiler Trainer