> One of Santa's Little Helpers received an unusual Christmas wish, a > copy of the yet to be released Deus Hex game. All they managed to > find were fragments from the dialogue system. Can you decode the > last one? This challenge's tarball contains BIN, PNG and TXT files. The image and text files contain the same dialogue, presumably generated from the BIN file. Our task is to understand the BIN files enough to figure out the included text. Let's take a look with a hex editor and see whether there's anything special about them: 0x00000000 5469 4e79 4d65 5461 0000 0010 0000 0002 TiNyMeTa........ 0x00000010 0008 0008 080c 0048 0002 002a 5478 5472 .......H...*TxTr 0x00000020 0000 0301 8950 4e47 0d0a 1a0a 0000 000d .....PNG........ 0x00000030 4948 4452 0000 0040 0000 0060 0103 0000 IHDR...@...`.... [...] 0x00000300 443e ef4a 0e02 bd7b a59c 81fd e3dd 4cf9 D>.J...{......L. 0x00000310 0707 9205 d0b7 2b6c e400 0000 0049 454e ......+l.....IEN 0x00000320 44ae 4260 824c 694e 6500 0000 3c05 0103 D.B`.LiNe...<... 0x00000330 0a04 0806 0903 0700 0500 0a01 0b00 0502 ................ 0x00000340 0704 0806 0700 0403 0b07 0a05 0b05 0905 ................ 0x00000350 0905 0904 0802 0505 0905 0905 0904 0802 ................ 0x00000360 0505 0905 0905 0906 074c 694e 6500 0000 .........LiNe... 0x00000370 5405 0103 0a04 0806 0903 0700 0500 0a01 T............... 0x00000380 0b00 0502 0704 0806 0702 0504 0800 0a00 ................ 0x00000390 0901 0b07 0a01 0700 0900 0a04 0805 0701 ................ 0x000003a0 0b07 0a04 0800 0603 0707 0303 0704 0803 ................ 0x000003b0 0b04 0801 0604 0300 0404 0801 0707 0a00 ................ 0x000003c0 0505 0906 07 ..... Some ASCII identifiers stand out in particular: - `TiNy` - `MeTa` - `TxTr` - `PNG` - `IHDR` - `IEND` - `LiNe` `PNG`, `IHDR` and `IEND` are PNG-related markers. The rest are unique to the mystery format. Looking at the other files the same markers appear again. It's possible to carve out the embedded PNG file by using `binwalk -D 'png image:png'`. Unsurprisingly enough it's a tilemap with every known and unknown character that appeared in the other PNG files. Each of the tiles has a dimension of 8x8px, for some reason they're arranged in a random order. If the format is anything like PNG, then the markers are surrounded by a combination of any of these in a yet to be determined order: - Content length (either little- or big-endian) - Content - Checksum / random garbage The `TiNy`, `MeTa`, `TxTr` and the first `LiNe` marker always appear at the offsets 0x00, 0x04, 0x1c and 0x325. The distance between the end of the `MeTa` and `TxTr` marker is 20 bytes, likewise the distance between `TxTr` and the first `LiNe` marker is 773 bytes. A number close to either is likely to appear either in front of the marker or afterwards. Considering that `MeTa` follows `TinY` immediately it's likelier to be after the marker, this hypothesis is confirmed by the four bytes after both markers being `\x00\x00\x00\x10` (big endian u32: 16) and `\x00\x00\x03\x01` (big endian u32: 769). The difference of four bytes is explained by the number measuring the distance between the line length indicator and the end of the content. Therefore it's possible to carve the contents with the following logic: read_bytes(4) # magic bytes while (not(eof())) { read_bytes(4) # marker u32 length = read_u32_be(4) read_bytes(length) # content } From the info gathered so far, the format is reminiscent of GameMaker asset files, as seen in games like Undertale and Deltarune. Let's focus on the metadata extracted from the four files: 0x0000000c 0000 0002 0008 0008 080c 0048 0002 002a ...........H...* 0x0000000c 0000 0002 0008 0008 080c 00a2 0004 0036 ...............6 0x0000000c 0000 0002 0008 0008 080c 006a 0002 003d ...........j...= 0x0000000c 0000 0002 0008 0008 080c 0052 0002 0034 ...........R...4 Everything except for the last six bytes is identical. The middle ones are almost identical, one is `\x00\x02`, the other three are `\x00\x04`. These are most likely the values 2 and 4, encoded as big endian u16. They correspond to the number of lines displayed and amount of `LiNe` markers in each file. Let's focus on these ones in `lines1.bin` next: 0x0000032d 0501 030a 0408 0609 0307 0005 000a 010b ................ 0x0000033d 0005 0207 0408 0607 0004 030b 070a 050b ................ 0x0000034d 0509 0509 0509 0408 0205 0509 0509 0509 ................ 0x0000035d 0408 0205 0509 0509 0509 0607 ............ [...] 0x00000371 0501 030a 0408 0609 0307 0005 000a 010b ................ 0x00000381 0005 0207 0408 0607 0205 0408 000a 0009 ................ 0x00000391 010b 070a 0107 0009 000a 0408 0507 010b ................ 0x000003a1 070a 0408 0006 0307 0703 0307 0408 030b ................ 0x000003b1 0408 0106 0403 0004 0408 0107 070a 0005 ................ 0x000003c1 0509 0607 .... Some more observations: - Each byte has a value between 0 and 10 - The length of each line's content is 60 and 84 - The length of each line in characters is 30 and 42 - Therefore each line's character is represented by two bytes - The palette is 8 columns and 12 rows The encoding of a character is likely to be related to the tilemap PNG. Each byte could be the row/column number. This can be confirmed by decoding the first few by hand: - Column 5, row 1: J - Column 3, row 10: C - Column 4, row 8: space Using that knowledge it's easy to write a solve script. Fortunately all embedded PNGs are the same, so it's possible to transcribe the tilemap into a nested array and use it as a look-up table. Running the script on the last BIN file prints the following: > Jock: "Oh my God! JC! A flag!" > JC Denton: "A flag! AOTW{wh4t_4_r0tt3n_fi13_f0rm4t}"