{"id":456,"date":"2011-02-05T17:15:31","date_gmt":"2011-02-06T01:15:31","guid":{"rendered":"http:\/\/www.outflux.net\/blog\/?p=456"},"modified":"2011-02-05T17:15:31","modified_gmt":"2011-02-06T01:15:31","slug":"fun-with-game-memory","status":"publish","type":"post","link":"https:\/\/outflux.net\/blog\/archives\/2011\/02\/05\/fun-with-game-memory\/","title":{"rendered":"fun with game memory"},"content":{"rendered":"<p>So, I was testing a (closed source) single-player offline game recently and thought this exercise might be fun to document. I didn&#8217;t want to spend any time actually earning in-game money since I&#8217;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 &#8220;bank account number&#8221; of <strong>219393<\/strong> and account balance of <strong>3000<\/strong>, I dived right in.<\/p>\n<p>First up, what&#8217;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 &#8220;w&#8221; in the permissions column, from <code>\/proc\/PID\/maps<\/code>:<\/p>\n<blockquote><p>0827e000-08282000 rw-p 00000000 00:00 0<br \/>\n<strong>0a22e000<\/strong>&#8211;<strong>0b08a000<\/strong> rw-p 00000000 00:00 0                                  [heap]<br \/>\nefa59000-efd00000 rw-p 00000000 00:00 0<br \/>\nefd00000-efd21000 rw-p 00000000 00:00 0\n<\/p><\/blockquote>\n<p>Knowing these, I could use gdb&#8217;s &#8220;find&#8221; command, after attaching to the process:<\/p>\n<blockquote><p>\n$ gdb \/some\/cool\/game<br \/>\n&#8230;<br \/>\n(gdb) attach PID<br \/>\n&#8230;<br \/>\n(gdb) find \/w 0x0827e000, 0x08282000, <strong>219393<\/strong><br \/>\n(gdb) find \/w <strong>0x0a22e000<\/strong>, <strong>0x0b08a000<\/strong>, <strong>219393<\/strong><br \/>\n0xaf03d08<br \/>\n<strong>0xaf06ca8<\/strong>\n<\/p><\/blockquote>\n<p>No hits in the first region, but I see two hits for the account number value in the second region. Let&#8217;s start there and see what&#8217;s near them&#8230;<\/p>\n<blockquote><p>\n(gdb) x\/8x 0xaf03d08<br \/>\n0xaf03d08:\t0x00035901\t0x00000000\t0x00000000\t0x0af06ce0<br \/>\n0xaf03d18:\t0x0af06be0\t0x00000059\t0x0af03d98\t0x0af041e8<br \/>\n(gdb) x\/8x <strong>0xaf06ca8<\/strong><br \/>\n0xaf06ca8:\t0x00035901\t<strong>0x00000bb8<\/strong>\t<strong>0x00000bb8<\/strong>\t0x0820b148<br \/>\n0xaf06cb8:\t0x00000001\t0x00000000\t0x00000000\t0x00000000\n<\/p><\/blockquote>\n<p>In that second hit, I see the value <strong>0xBB8<\/strong>, which is <strong>3000<\/strong>, and matches our account balance. Let&#8217;s see what happens if we just change both of those to add a bit a few orders of magnitude above the current value&#8230;<\/p>\n<blockquote><p>\n(gdb) set var *0xaf06cac = 0x00100bb8<br \/>\n(gdb) set var *0xaf06cb0 = 0x00100bb8<br \/>\n(gdb) x\/32x 0xaf06cac<br \/>\n0xaf06cac:\t0x00100bb8\t0x00100bb8\t0x0820b148\t0x00000001<br \/>\n(gdb) continue\n<\/p><\/blockquote>\n<p>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.<\/p>\n<p style='text-align:left'>&copy; 2011, <a href=\"https:\/\/outflux.net\/blog\/\">Kees Cook<\/a>. This work is licensed under a <a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\">Creative Commons Attribution-ShareAlike 4.0 License<\/a>.<br \/><a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\"><img decoding=\"async\" alt=\"CC BY-SA 4.0\" style=\"border-width:0\" src=\"https:\/\/i.creativecommons.org\/l\/by-sa\/4.0\/88x31.png\" \/><\/a> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>So, I was testing a (closed source) single-player offline game recently and thought this exercise might be fun to document. I didn&#8217;t want to spend any time actually earning in-game money since I&#8217;d played it before and I wanted to just skip ahead to other aspects of the game. I was curious how straight-forward adjusting [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,18,1,10,14],"tags":[],"_links":{"self":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/456"}],"collection":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/comments?post=456"}],"version-history":[{"count":8,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/456\/revisions"}],"predecessor-version":[{"id":464,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/456\/revisions\/464"}],"wp:attachment":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/media?parent=456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/categories?post=456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/tags?post=456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}