{"id":3407,"date":"2011-06-06T23:01:24","date_gmt":"2011-06-07T06:01:24","guid":{"rendered":"http:\/\/multimedia.cx\/eggs\/?p=3407"},"modified":"2011-06-07T09:45:55","modified_gmt":"2011-06-07T16:45:55","slug":"cracking-aztec-game-audio","status":"publish","type":"post","link":"https:\/\/multimedia.cx\/eggs\/cracking-aztec-game-audio\/","title":{"rendered":"Cracking Aztec Game Audio"},"content":{"rendered":"<p>Here&#8217;s a mild multimedia-related reverse engineering challenge for you. It&#8217;s pretty straightforward for those skilled in the art.<\/p>\n<p><strong>The Setup<\/strong><br \/>\nOne side effect of running this ridiculously niche interest blog at the intersection of multimedia, reverse engineering, and game hacking is that people occasionally contact me for assistance on those very matters. So it was when one of my <a href=\"http:\/\/mobygames.com\/\">MobyGames<\/a> peers asked if I can help to extract some music from a game called <a href=\"http:\/\/www.mobygames.com\/game\/windows\/aztec-wars\">Aztec Wars<\/a>. The game consists of 2 discs, each with a music.xbe file that contains multiple tunes and is hundreds of megabytes large.<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.mobygames.com\/game\/windows\/aztec-wars\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/multimedia.cx\/eggs\/wp-content\/uploads\/2011\/06\/aztec-wars-cover.jpg\" alt=\"\" title=\"Aztec Wars cover\" width=\"120\" height=\"166\" class=\"aligncenter size-full wp-image-3408\" \/><br \/>\n<\/a><\/center><\/p>\n<p>That&#8217;s all the data I received from the first email. At first I&#8217;m wondering what makes people think I have some magical insight into cracking these formats with such little information. Ordinarily, I would need to have the entire data file to work with and possibly the game binaries. But I didn&#8217;t want to ask him to upload hundreds of megabytes of data and I didn&#8217;t feel like downloading it; commitment issues and all.<\/p>\n<p>But then I gathered a little confidence and remembered that the .xbe files are probably just Game Resource Archive Formats (GRAF) which are, traditionally, absurdly simple. I asked my colleague to send me a hexdump of the first kilobyte of one of the .xbe GRAFs (<code>'hexdump -C -n 1024 music.xbe &gt; file'<\/code>) as well as the total file size of the GRAF.<\/p>\n<p><strong>The Hexdump<\/strong><br \/>\nThe first music.xbe file is 192817376 bytes large. These are the first <strike>1024<\/strike> <em>144<\/em> bytes (more than enough):<\/p>\n<pre>\r\n00000000  01 00 00 00 60 04 00 00  14 00 00 00 01 00 00 00  |....`...........|\r\n00000010  0d 00 00 00 48 00 00 00  94 39 63 01 1c a4 21 03  |....H....9c..\u00a4!.|\r\n00000020  7a d2 54 04 04 28 ad 05  d8 88 fd 06 d8 88 fd 06  |z\u00d2T..(\u00ad.\u00d8.\u00fd.\u00d8.\u00fd.|\r\n00000030  2a 6e 46 08 2a 6e 46 08  2a 6e 46 08 2a 6e 46 08  |*nF.*nF.*nF.*nF.|\r\n00000040  50 13 2f 0a e0 28 7e 0b  52 49 46 46 44 39 63 01  |P.\/.\u00e0(~.RIFFD9c.|\r\n00000050  57 41 56 45 66 6d 74 20  10 00 00 00 01 00 02 00  |WAVEfmt ........|\r\n00000060  44 ac 00 00 10 b1 02 00  04 00 10 00 64 61 74 61  |D\u00ac...\u00b1......data|\r\n00000070  fc 13 63 01 00 00 00 00  00 00 00 00 00 00 00 00  |\u00fc.c.............|\r\n00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n<\/pre>\n<p><strong>The Challenge<\/strong><br \/>\nArmed with only the information in the foregoing section, figure out a method for extracting all the audio files in that file and advise on their playback\/conversion. Ideally, this method should require minimal effort from both you and the person on the other end of the conversation.<\/p>\n<p><strong>The Resolution<\/strong><br \/>\nThe reason I ask is because I came up with a solution but knew, deep down, that there must be a slightly easier way. How would you solve this?<\/p>\n<p><a href=\"http:\/\/www.youtube.com\/playlist?p=PL4165E0DB23EA9865\">The music files in question are now preserved on YouTube<\/a> (until they see fit to remove them for one reason or another).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A quick game hacking challenge<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29],"tags":[],"class_list":["post-3407","post","type-post","status-publish","format-standard","hentry","category-game-hacking"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/multimedia.cx\/eggs\/wp-json\/wp\/v2\/posts\/3407","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/multimedia.cx\/eggs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/multimedia.cx\/eggs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/multimedia.cx\/eggs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/multimedia.cx\/eggs\/wp-json\/wp\/v2\/comments?post=3407"}],"version-history":[{"count":13,"href":"https:\/\/multimedia.cx\/eggs\/wp-json\/wp\/v2\/posts\/3407\/revisions"}],"predecessor-version":[{"id":3421,"href":"https:\/\/multimedia.cx\/eggs\/wp-json\/wp\/v2\/posts\/3407\/revisions\/3421"}],"wp:attachment":[{"href":"https:\/\/multimedia.cx\/eggs\/wp-json\/wp\/v2\/media?parent=3407"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/multimedia.cx\/eggs\/wp-json\/wp\/v2\/categories?post=3407"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/multimedia.cx\/eggs\/wp-json\/wp\/v2\/tags?post=3407"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}