Additional Info
|
Required tools: flasm, flare, scanmem, dhex
Required skills: Basic command line, locating the game swf Useful reference: Super happy unofficial Flash 5 actionscript bytecode speccy fun Let's work with a relatively simple game. http://www.kongregate.com/games/squidsquid/sproing Download the swf (and make a copy so we don't have to redownload it if we mess something up) Code: [Select] # wget http://chat.kongregate.com/game_files/0000/2632/sproing_kong.swf -O orig.swf Get the actionscript (This creates orig.flr)Code: [Select] # flare orig.swf Decompress if it's compressedCode: [Select] # flasm -x a.swf DisassembleCode: [Select] # flasm -d a.swf > a.flm It might return warnings, some of which we can ignore, but the one that comes up with the game I chose happens to break the reassembly. Code: [Select] > branch target not found: -32449 So, let's find the line and fix it so it can recompile. Since we're not actually going to run it, it doesn't matter if this breaks the game logic. A quick search brings usCode: [Select] 6515 | label196: I'm just going to change this so it compilesCode: [Select] 6515 | label196: Bam. Reassemble, it'll be quite different than orig.swf, but that's okay, the parts we're modifying are the same in memory.Code: [Select] # flasm -a a.flm Create a copy, we'll be changing this and then comparing it to a.swf. Thus when we change b.flm, we'll be able to find the bytes that changed in b.swfCode: [Select] # cp a.swf b.swf Okay, let's open up an editor or two. I'm using vim with a vertical split, orig.flr on one side, b.flm on the other. We're going to change the amount of health the health bonus circle restores, so let's search around for "health" in orig.flr. Eventually you'll find:Code: [Select] 1280 | if (bonustype == 'health_bonus') { Now we must find it in the assembly (b.flm). I'm going to search for health_bonus. After poking around, here's the relevant section. You can tell by context because "sHealthBonus.start" and "healthBar._width" are also in this same sectionCode: [Select] 5245 | push 'health_bonus' The part we really care about is the addition of the 15, to health. Code: [Select] 5254 | push 'health', 'health' Flash is stack based, I'm going to show how each step changes the stack. Let's assume we're at 55 health. Code: [Select] 5254 | push 'health', 'health' So, it's simple enough to increase the amount it heals. I'm going to replace "push 15" with "push 50". Note, we can't add commands because that would change how everything lines up later in the program. We can remove commands by replacing them with 02 (no-op, nop), but we don't need to do any of that with this.Save, and recompile. Code: [Select] # flasm -a b.flm Now we have a.swf and b.swf, which differ solely by the change of the 15 to 50I use dhex, which is a diff hex editor, which makes it super easy to find the differences. Code: [Select] # dhex a.swf b.swf Hitting 'n' brings us to the first (and only) difference. We see that 0x0f (15) changed to 0x32 (50).The command starts at the 96 right before it. Code: [Select] | 96 05 00 07 0f 00 00 00 Which has fieldsCode: [Select] | 96, 05 00, (07, 0f 00 00 00) Code: [Select] | push, length, (integer, integer_data) It's little-endian, so all the multibyte fields are backward. e.g. Code: [Select] | 0f 00 00 00 is 0x0000000f (15)Back to the point, our array of bytes needs to get enough of the surroundings so that there aren't other matches when we use scanmem. Let's grab some bytes from before and after the push command Code: [Select] | 08 3b 1c 96 05 00 07 0f 00 00 00 47 1d 96 Change the 0x0f (15) to 0x32 (100)Code: [Select] | 08 3b 1c 96 05 00 07 32 00 00 00 47 1d 96 And we're done! We have our bytes. Now to test it.Start scanmem (following works if you only have one instance of flash running), change the scan data type to bytearray, and search for the original bytes Code: [Select] # scanmem $(pgrep -f flash) Success! Only one match. Now to get the memory address (yours will be different) and write the new valueCode: [Select] # list Worst that will happen is you crash/freeze flash. It's easy enough to restart. I use `pkill -f flash` and then with a refresh of the page and it should reload. You'll have to restart scanmem too.Anyway. Success! You might now notice that sometimes the health bar width doesn't line up with your actual health If you look up, you'll see that we only changed the health addition to 50, not the healthBar width. If you really care that much, I'm sure you can fix it yourself now (broken image removed) |