So, I was testing a (closed source) single-player offline game recently and thought this exercise might be fun to document. I didn’t want to spend any time actually earning in-game money since I’d played it before and I wanted to just skip ahead to other aspects of the game. I was curious how straight-forward adjusting my cash might be. So, noting the in-game “bank account number” of 219393 and account balance of 3000, I dived right in.
First up, what’s the memory layout of the heap look like? I looked at the brk and the mmap regions without a mapped library or file, marked with “w” in the permissions column, from /proc/PID/maps
:
0827e000-08282000 rw-p 00000000 00:00 0
0a22e000–0b08a000 rw-p 00000000 00:00 0 [heap]
efa59000-efd00000 rw-p 00000000 00:00 0
efd00000-efd21000 rw-p 00000000 00:00 0
Knowing these, I could use gdb’s “find” command, after attaching to the process:
$ gdb /some/cool/game
…
(gdb) attach PID
…
(gdb) find /w 0x0827e000, 0x08282000, 219393
(gdb) find /w 0x0a22e000, 0x0b08a000, 219393
0xaf03d08
0xaf06ca8
No hits in the first region, but I see two hits for the account number value in the second region. Let’s start there and see what’s near them…
(gdb) x/8x 0xaf03d08
0xaf03d08: 0x00035901 0x00000000 0x00000000 0x0af06ce0
0xaf03d18: 0x0af06be0 0x00000059 0x0af03d98 0x0af041e8
(gdb) x/8x 0xaf06ca8
0xaf06ca8: 0x00035901 0x00000bb8 0x00000bb8 0x0820b148
0xaf06cb8: 0x00000001 0x00000000 0x00000000 0x00000000
In that second hit, I see the value 0xBB8, which is 3000, and matches our account balance. Let’s see what happens if we just change both of those to add a bit a few orders of magnitude above the current value…
(gdb) set var *0xaf06cac = 0x00100bb8
(gdb) set var *0xaf06cb0 = 0x00100bb8
(gdb) x/32x 0xaf06cac
0xaf06cac: 0x00100bb8 0x00100bb8 0x0820b148 0x00000001
(gdb) continue
And presto, clicking on the bank account details in-game shows a huge account balance of 1051576 now. No need to reverse-engineer any saved games, whew.
© 2011, Kees Cook. This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 License.
reminded me of this: http://hick.org/code/skape/papers/closed-source-reveng.pdf
Comment by a — February 5, 2011 @ 5:23 pm
OMG You hax0red a bank!
Comment by Jonathan Carter — February 5, 2011 @ 5:29 pm
Was this a Wine game by chance?
Comment by Scott Ritchie — February 5, 2011 @ 7:37 pm
There is a tool for precisely this. It is packaged and called scanmem. For this task it is quite a bit easier.
Comment by Helmut — February 6, 2011 @ 6:12 am
Next time you want extra money or whatnot in a game, check out the program scanmem. It does what you did, only without all that typing. :-)
Comment by Jannich Brendle — February 6, 2011 @ 7:46 am
Now only if it was this easy to increase my real life bank account’s balance… :)
Comment by Cody Somerville — February 6, 2011 @ 8:25 am
Scanmem is also useful: http://taviso.decsystem.org/scanmem.html
Comment by me — February 6, 2011 @ 8:47 am
@Scott no, actually a native Linux game.
Re: scanmem, yeah, excellent stuff. I just wanted to do it by hand and document “find” for myself. :)
Comment by kees — February 6, 2011 @ 8:51 am
Awesome :-)
Comment by Dustin Kirkland — February 10, 2011 @ 2:44 am