Anatomy of a Hack: Darnell's Recount
-migrated-
Anatomy of a Hack: Darnell's Recount Posted on: 09/10/2009 6:50am
Quote Post
As I've been asked to show my working, I thought I'd post up how I did the take no damage hack for the above game.

I'll start by saying that I really don't like the game: the graphics, music, plot, concept and controls are abhorrent to me. Right, rant out of the way; on to the bits you want.

First off I used IE + Sothink SWF Decompiler plugin to pull the .swf file on to my local machine and then loaded it into Sothink.

Now we have to look for somewhere that we can find to hack. As Flash is a movie based runner, it follows the concept of frames, where animations and actions happen. Each frame can have several objects in, such as sprites and sprites may have scripts.

Our first task is to work out how player health is done, this can be a real pain, depending on how the programmer has programmed the game, I normally look for sprites that are related to the player, either by looking for the sprite, looking for labels, or if I'm lucky, looking for comments. In this case we're lucky, if you expand the action tab you can see that sprite 2781 has a comment of player!

Now click on the sprite and we can see the ActionScript that acts for this sprite. ActionScript is a version of ECMAscript, similar to Javascript. If we scroll through the ActionScript we can see three interesting functions: hitMedium, hitStrong and weakHit. These look to perform the actions when the player is hit, the weakHit (it is the smallest) is reproduced below:
Code: [Select]
function smallHit()
{
var _loc2 = 10;
hitPlayer();
health = health - _loc2;
xspeed = -6 + random(13);
if (jump == false)
{
yspeed = -5;
jump = true;
} // end if
this.gotoAndStop(5);
} // End of the function
For us the important bit is health = health - _loc2; This defines how much health we lose in the function. We could of course look for the function being called and NOP that out, but that could be a lot of changes and mess up the stack. So it's probably easiest to ensure that _loc2 is set to 0, which is easy as it's set in the function.

Before we continue, we need to know all places where health is affected, so looking through the functions we can see that it is reduced by _loc2 in smallHit and _loc3 in hitStrong and hitMedium, so we will need to alter the following statements:
hitMedium:
Code: [Select]
if (_root.bg.boss == false)
{
var _loc3 = 10;
}
else
{
_loc3 = 10;
} // end else if
hitStrong:
Code: [Select]
if (_root.bg.boss == false)
{
var _loc3 = 10;
}
else
{
_loc3 = 15;
} // end else if
smallHit:
Code: [Select]
var _loc2 = 10;
ActionScript is translated to a bytecode for the Flash interpreter to run, and this is what we hack in AoB hacks. We can see the bytecode by using the "Raw Data" button on the toolbar. Press this and navigate down to the function definition for hitMedium (search for hitMedium) and we can see where _loc3 is set in bytecode:
Code: [Select]
_push register2 "bg"
//4e
_getMember
//96 02 00 08 0e
_push "boss"
//4e
_getMember
//96 02 00 05 00
_push false
//49
_equals2
//12
_not
//9d 02 00 12 00
_if true goto #50
//96 05 00 07 0a 00 00 00
_push 10
//87 01 00 03
_storeRegister 3
//17
_pop
//99 02 00 0d 00
_jump to #53
#50 //96 05 00 07 0a 00 00 00
_push 10
//87 01 00 03
_storeRegister 3
If you're going to do bytecode hacking, you need to understand the principle of the stack: a stack is a data structure which is only accessible from the top, you can push items on to it and pop them off it. But items only pop off in a "most recent" pushed order, i.e. if I push 1 2 3 4, then when I pop I get 4 3 2 1.

So, we can see that where is sets the value is:
Code: [Select]
//96 05 00 07 0a 00 00 00
_push 10
//87 01 00 03
_storeRegister 3
96 is the opcode for push, it is followed by a length (05 00) and a parameter (07 0a 00 00 00). The first byte of the parameter is the datatype, in this case 07, which is an integer; followed by 0a 00 00 00, which is the value in little endian format, this is 10.

So the easiest way to hack this would be to alter the 07 0a 00 00 00 to 07 00 00 00 00, to ensure that you take 0 damage instead of 10. We can make our AoB:
96 05 00 07 0a 00 00 00 87 01 00 03 =>
96 05 00 07 00 00 00 00 87 01 00 03
(the extra few bytes are to match the storeRegister opcode, so that we don't effect any other places where 10 is pushed onto the stack). We also know that there are 3 instances of this (two from hitMedium, one from hitStrong).

We also need to have this for were we take 15 points of damage in hitStrong, which, if you follow the process above is: (should match 1 hit)
96 05 00 07 0f 00 00 00 87 01 00 03 =>
96 05 00 07 00 00 00 00 87 01 00 03

And finally, from smallHit (as it uses register 2, not 3):
96 05 00 07 0a 00 00 00 87 01 00 02 =>
96 05 00 07 00 00 00 00 87 01 00 02
Re: Anatomy of a Hack: Darnell's Recount Posted on: 12/23/2009 8:20pm
Quote Post
Excellent! Good tips on both finding the function and decoding the bytecode.

BUT, why is this NOT STICKIED??
Re: Anatomy of a Hack: Darnell's Recount Posted on: 02/13/2010 12:34pm
Quote Post
disgruntled old man
I'd give you karma if I knew how deity, This definitely helped me better understand what to look for when searching for AoB's...I agree with pythang on making this a sticky.



New to Kong Hack and want to learn the basics? Check out the [Kong Hack 101] and the [Hacking 101].
Wanna learn how we make the hacks? Start with getting [the tools], then check these out: [AoB tutorial] | [.sol guide] | [Unity3d tutorial] | kadat's [video tutorials]
And if you don't already have it, check out the [Kong Hack Ultra Trainer]. You'll be glad you did!