Go Back

Torchlight Update

It seems Torchlight got updated on Steam this week, this meant the trainer was no longer working. I have fixed it and the trainer works again.

You can download it here.

Edit: Its really updated now! It seems upload failed and the old version didnt get overwritten.

Posted by: Da_Teach on Thursday, April 01, 2010  •  Comments (7)  •  Full story  •  Torchlight Trainer

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 (0)  •  Full story  •  Code Injection Torchlight Codecave

Torchlight Part #1

Just like with Trine, the health of the player character is lowered / increased using the same function. This means if you make the player invulnerable, the enemies will also be invulnerable.

Now we could do the same as with Trine, allocate memory and then redirect the program flow to our injected memory. But I wanted to do something different, so for Torchlight I decided to use a code cave.

Basically this means that we look for a piece of unused memory that has already been allocated and use that to inject our code. Up until today I never used a code cave for this purpose, I have to be honest I never thought about using code caves for anything.

But it works, its "safe" (as safe as code injection can be). The only trick is to find a code cave big enough to fit the code that you want. Luckily Cheat Engine has a nice function which searches for code caves, including a desired size.

Torchlight had an additional fun factor which I never played with before, both health and mana are stored as floating points. Now this in itself isn't something new, but I never worked with floating point assembly instructions (at least not changed them).

The instruction for unlimited health was at 490649h (fstp dword ptr [esi+394]) and the two instructions for unlimited mana are at 490894h and 4908C3h (both fstp dword ptr [esi+3b8]).

All three instructions use fstp, the description for this function is "Copy ST(0) to m32fp and pop register stack". The last part causes an issue if you only nop the instruction. Not executing the instruction causes the register stack to stay the same which caused several other issues in the game (including gfx errors and crashes).

To get around this issue you have to execute a "fstp st(0)" whenever you do not execute the original instruction. This causes the register stack to pop into nothingness.

As with Trine, we have to figure out how to identify the player. With Torchlight its a bit easier then Trine. There's a pointer to the Player structure at [[E2B6A4h]+1Ch], so we can use this in our code redirection to check who's health (or mana) is getting lowered.

In part #2 I'll show some assembly code which can be used (in the code cave) to accomplish exactly that. I have some code lying around but I want to play with it a bit more before releasing it.

Posted by: Da_Teach on Tuesday, January 19, 2010  •  Comments (0)  •  Full story  •  Torchlight Codecave Cheat Engine