Creating a cheat table - Health Hack

From Cheat Engine
Revision as of 12:57, 14 August 2020 by Dykis (talk | contribs) (One hit kills: "sense" -> "since".)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search


This page is a sub page of: Creating a cheat table - Full guide

Now after a restart, this is what my table looks like.

Tutorials.Dishonored.HealthHack.01.png


And if you have followed along then you already have the health address so lets just start with the hook.

But all we really need is the health address to start.


Step 1

With the health address in the address list let's check to see what accesses the address, in both normal conditions and when in combat.

Tutorials.Dishonored.HealthHack.02.png

So here is what I found, the green is normal conditions, purple is when the player hits a combatant, and red is the player being hit by a combatant.


And it looks like we found the player's death check. But these may just be checks the compiler or engine put in place to stop arithmetic problems.

cmp dword ptr [ecx+00000344],00
cmp dword ptr [ebx+00000344],00

Top is when hitting a combatant, and the bottom is when being hit: Tutorials.Dishonored.HealthHack.03.png


So let's start with the player hit death check (bottom death check), select the instruction and click the Show disassembler button. And in the memory view form right click the instruction line and select Find out what addresses this instruction accesses.

And here is what I found.

Tutorials.Dishonored.HealthHack.04.png


So this instruction works on the player's and the combatants' health, probably shared by all actor objects in the game. So I think that the actor class will hold some kind of "Decrease Health" function that the player inherits.

When the game or engine is written, actors and players might be written like this.

//// Actor, base for all actors class Actor(object){ string Name = 'Actor'; ... int Health = 70; ... function decreaseHealth(self, amount) { ... if (self.Health == 0) { self.Die() } } } //// Player class Player(Actor){ //// Player inherits form Actor string Name = 'Player'; ... }


Now there are different ways of handling shared instructions, we could look at the structures to find a unique identifier. But since we have a good base address for the player we can just check against that to determine if the actor is the player, no need for guess work here.

Step 2

So lets get a base script up, and then work from there.

Tutorials.Dishonored.HealthHack.05.png


So if the base address was a multi-level pointer then to check it we would need some thing like this:

n_code:
    push esi
    mov esi,[ptrCoordBase]
    test exi,esi
    jz @f  // jump forward to the next label (@b is jmp back).
        mov esi,[esi+{the base offset}]
        test esi,esi
        jz @f
            cmp esi,ebx
            jne @f
                mov [ebx+{health offset}],(int)100
    @@:
    pop esi
o_code:
    cmp dword ptr [ebx+00000344],00


But our base address is at the same level as the health address, so this is all we need.

Note: The "Coord. Hook" must be enabled to have access to the "ptrCoordBase" symbol, if not enabled then this script will fail on syntax check and on injection.

Note: Later I will set the "Coord. Hook" as a primary script with the other script(s) as it's child record(s), or in the table Lua script, to be run first.

Tutorials.Dishonored.HealthHack.06.png


Step 3

But if we look back at the debugger form we see that 1 instruction is constantly checking the player health, and another is constantly writing to the player health. My bet is that some where in there it checks to see if we are over the maximum health and the the other sets it to the maximum if over.

Tutorials.Dishonored.HealthHack.07.png


So let's look for our health maximum, in the memory view form.

Tutorials.Dishonored.HealthHack.08.png


And here I am betting that the "+348" is our health max which is just 4 bytes down from our health (this is so common that I always check around the value's address for it's maximum, but this was my process when first learning) so let's add that to the table. If it looks good then let's add it to the script, so if the health maximum goes up the script will still fill it. Now some people will just cram a large value in the address, but I have even seen this done on a 2 byte address with a 3 byte number being used, so there was numeric overflow that would corrupt the game saves (and that's no good, plus if it overflows to say the health maximum then that would get set very low and that is the opposite of what I am looking for, at least with this hack).

So let's work on that script again.

Tutorials.Dishonored.HealthHack.09.png


Step 4

And let's test the script (remember to save your tables before injections just in case, even saving be for AOB scans is a good idea to me).

But mine didn't work and if you just copied mine then I bet yours didn't work too.


Debugging your script

Now I found my type-o but lets debug our script to find the problem. So lets look at that instruction when injecting to see that it is, in fact, injecting to the right spot.

Tutorials.Dishonored.HealthHack.10.png

Now re-enable the script while looking at the memory view form.

Tutorials.Dishonored.HealthHack.11.png

Then let's follow that to our assembled memory for the health hack. So right click the instruction line and select Follow.

Tutorials.Dishonored.HealthHack.12.png


Then on the first line "cmp [ptrCoordBase],ebx" let's see what's going on, so right click and select Find out what addresses this instruction accesses, and go back to the game and get hit again to test.

Now since we are looking at a base address let's view it in hexadecimal format, so right click the debugger form and select Show as hexadecimal.

Tutorials.Dishonored.HealthHack.13.png


Now let's check the registry so in the debugger form right click the address and select Show register states.

Tutorials.Dishonored.HealthHack.14.png


Tutorials.Dishonored.HealthHack.15.png

So I first check EDX and see that the address is wrong, but I see that EBX is the right address and then see that I used the wrong registry, so lets disable the script and then make the correction.

n_code:
    cmp [ptrCoordBase],ebx  // here I typed the right one
    jne @f
        push eax
        mov eax,[edx+348]  // wrong one used here
        mov [edx+344],eax  // wrong one used here again
        pop eax
o_code:
    cmp dword ptr [ebx+00000344],00

Now, having written to an unknown address or addresses, I will be closing the game to keep from screwing up the game or hack testing (I will close it with task manager or the form close button if in windowed mode, knowing that it doesn't save then, to insure nothing gets saved). And because Cheat Engine can't account for my mistakes, I will also be restarting Cheat Engine to make sure I didn't mess it up too.


So let's restart (the game and Cheat Engine) and correct the script re-inject and retest the script.

So here is my corrected script.

Tutorials.Dishonored.HealthHack.16.png

So let's retest that script, don't just test to see if you have infinite health also test if the combatants can still be killed.


So I will kill a combatant (try both standard sword kill and an animated stealth kill) and then stand in the middle of a group for a minute to see how this works out.

Tutorials.Dishonored.HealthHack.17.png

And I now have a working health hack.

This was after about 20 hits, now we could look for a better spot so our meter stays filled, but I am fine with it so moving on.

Tip: The best place to insure that the display value and the real value match is in a write instruction.


One hit kills

And sense this instruction handles all actors health let's just set this up as a primary script with 2 flags one for the player and the second for the combatants.

So here is the new script.

Tutorials.Dishonored.HealthHack.18.png


Now add the flags to the address list right click the player health flag and select Set/Change dropdown selection options.

Tutorials.Dishonored.HealthHack.19.png

And set it like this.

Tutorials.Dishonored.HealthHack.20.png


Then right click the combatant health flag and select Set/Change dropdown selection options.

And set it like this.

Tutorials.Dishonored.HealthHack.21.png


We could also add a toggle script for the flags:

////
//// ------------------------------ ENABLE ------------------------------
[ENABLE]
flgPlayerHealthHook:
    db 01
////
//// ------------------------------ DISABLE ------------------------------
[DISABLE]
flgPlayerHealthHook:
    db 00
////
//// ------------------------------ ENABLE ------------------------------
[ENABLE]
flgCombatantHealthHook:
    db 01
////
//// ------------------------------ DISABLE ------------------------------
[DISABLE]
flgCombatantHealthHook:
    db 00


Now time to test. So let's inject the new script, and set a flag to test it out.

Let's test the infinite health first, then one hit kills, then disable infinite health with one hit kills enabled to make sure we are not subject to one hit kills.

So It looks like the infinite health works but one hit kills is not working, so let's have look at the other death check instruction.

But in checking what addresses that instruction accesses I find only the player's health, so what we want is instruction that writes to actor health, this is where I had to just try different ones until I found the right area, test what addresses the instruction accesses to find a write that has all health run thought it.

This is the one hit kills script that ended up working.

Tutorials.Dishonored.HealthHack.22.png


And this is the cleaned up infinite health script.

Tutorials.Dishonored.HealthHack.23.png


So I will be doing a little more testing (the best kind of testing), to insure it is working be for moving one. I also like to test going though load screens to insure no crashes for new scripts that write values.


And, with every thing working, on to the next hack.



Links