# Boxy - Reversing (200)
You're given a spec resembling Chinese for a proprietary image protocol. Study the attached example images to discover the flag in the captured transmission.
Download: [9WuDhiY44X1XvtCZNOFQyN4qANxnLlnu-boxy.tar.xz](https://s3.amazonaws.com/advent2018/9WuDhiY44X1XvtCZNOFQyN4qANxnLlnu-boxy.tar.xz) [(mirror)](./static/9WuDhiY44X1XvtCZNOFQyN4qANxnLlnu-boxy.tar.xz)
## Deciphering the Samples
This challenge provided several sample images along with binaries which were presumably used to create those files. There was also a text file with chinese characters, but that proved much less helpful. I started the challenge by looking at the examples and attempting to figure out how the binary bytes translated into the images.
**0x00.bin**
This image was simply a 256x256 all-white iamge. Looking at the binary, I created the following notes, and without much to go on I moved to the next example.
```01ff 02ff header?  255x2550300 ff00 all white?```
**0x01.bin**
This example had eight images of different colors. Looking at the binary, I could isolate the differences where each image was created and created these notes. This began to form some sense of "instructions" encoded as two-byte values. From this it seemed clear that `01` and `02` were for setting a size, `03` was for setting a color, and `ff` was for painting the current settings to an image.
```01ff 02ff set selected area 255x2550300 ff00 set white, paint ; white0301 ff00 set black, paint ; black0302 ff00 set red, paint ; red0303 ff00 set lime, paint ; lime0304 ff00 set yellow, paint ; yellow0305 ff00 set blue, paint ; blue0306 ff00 set magenta, paint ; magenta0307 ff00 set cyan, paint ; cyan```
**0x02.bin**
This example had four images. The first only had the upper-left square filled in, the second had upper-left and lower-right, the third upper-left and lower-right in white, upper-right in black, and the last image had a checkerboard with the lower-left also filled in black. My notes for this began to paint a better picture for what was going on. This example introduced `04` and `05` which I took to mean set the offset. Since each square was checkerboard-ed in the image, the values for each offset seem to match up with the corresponding images.
```0180 0280 set selected area 128x1280300 ff00 set white, paint0480 0580 set offset 128x128ff00      paint0301      set black0400 0580 set offset 0,128ff00      paint0480 0500 set offset 128,0ff00      paint
upper left quadrant whitebottom right quadrant whiteupper right blackbottom left black```
**0x03.bin**
The last example had five images. The first was all white as we've seen before, but the last four each painted a new rectangle. Again, my notes are below and showed that the binary added four new instructions `06`, `07`, `08`, and `09`. Based on context in the image and the fact that the painted rectangles weren't all in the same location, but the `04` and `05` set offset instructions weren't found, I took these to mean add or subtract from one of the image dimensions.
```01ff 02ff 0300 ff00 set selected area 255x255, set white, paint0108 0210 set selected area 8x16 (y by x)0458 0558 set offset 0x58,0x58 == 88,880302      set red0740      ???? add 0x40 to y?ff00      paint0303      set green0940      ???? add 0x40 to x?ff00      paint0304      set yellow0640      ???? sub 0x40 from y?ff00      paint0305      set blue0840      ???? sub 0x40 from x?ff00      paint
blue at 90,90yellow at 154,90greep at 152,152red at 90,153(red green yellow blue mini boxes)```
## Creating an Encoder
Using all of this, I wrote up a simple python script to ingest a binary file and produce a test image. This worked for all four examples.
```pythonfrom PIL import Image, ImageDrawimport binascii
img = Image.new('RGB', (256,256), color='white')draw = ImageDraw.Draw(img)
data = open('./boxy/examples/0x03.bin','rb').read()posx = 0posy = 0sizex = 0sizey = 0color = 'white'fillall = Falsefor i in range(0,len(data),2):	print('%02x%02x'%(data[i],data[i+1]), end=' ', flush=True)	if data[i] == 1:		sizey = data[i+1]		print('sizey',sizey)	elif data[i] == 2:		sizex = data[i+1]		print('sizex',sizex)	elif data[i] == 3:		if data[i+1] == 0:			color = 'white'		elif data[i+1] == 1:			color = 'black'		elif data[i+1] == 2:			color = 'red'		elif data[i+1] == 3:			color = 'lime'		elif data[i+1] == 4:			color = 'yellow'		elif data[i+1] == 5:			color = 'blue'		elif data[i+1] == 6:			color = 'magenta'		elif data[i+1] == 7:			color = 'cyan'		else:			print('unknown color', data[i+1])		print('color', color)	elif data[i] == 4:		posy = data[i+1]		print('posy ==',posy)	elif data[i] == 5:		posx = data[i+1]		print('posx ==',posx)	elif data[i] == 6:		posx -= data[i+1]		print('posx -',data[i+1],'=',posx)	elif data[i] == 7:		posx += data[i+1]		print('posx +',data[i+1],'=',posx)	elif data[i] == 8:		posy -= data[i+1]		print('posy -',data[i+1],'=',posy)	elif data[i] == 9:		posy += data[i+1]		print('posy +',data[i+1],'=',posy)	elif data[i] == 0xff:		print('rectangle',[posx,posy,posx+sizex-1,posy+sizey-1],color)		if posx == 0 and posy == 0 and sizex == 255 and sizey == 255:			if fillall:				continue			fillall = True		draw.rectangle([posy,posx,posy+sizey-1,posx+sizex-1],fill=color)	else:		print(data[i:i+2])
img.save('boxy/test.png')```
However, this didn't work off immediately for the `reverseme` binary. Using this program, I started disassembling the binary and found many instances of the instructions `01ff02ff030004000500` which for all intents and purposes clears the current image. Even if this were removed, the `reverseme` binary repeatedly set one offset to the same position `047e` thereby overwriting previous painted sections. After some tweaking, I finally decided to just modify the `reverseme` binary bytes so that it wouldn't clear the image and the overwriting command was replaced with one to skip to the next "line". This was done as follows and resulted in the image shown below.
```pythondata = open('./boxy/reverseme','rb').read()data = data.replace(binascii.unhexlify('01ff02ff030004000500'),b'')data = data.replace(binascii.unhexlify('047e'),binascii.unhexlify('0404'))data = data.replace(binascii.unhexlify('0508'),binascii.unhexlify('0708'))```
![boxy reverseme final](./images/reverseme.png)
In one last piece of the challenge, you may notice that each "line" here corresponds to sets of 5-6 dots and dashes. This is pretty readily recognizable as morse code with a trailing dot at the end of each. Decoding this morse code gives all integer values, each of which corresponds to an ASCII byte value for the flag:
```65 A79 O83 T87 W123 {111 o107 k95 _104 h105 i95 _115 s111 o95 _109 m121 y95 _110 n97 a109 m101 e95 _105 i115 s95 _98 b111 o120 x121 y125 }
AOTW{ok_hi_so_my_name_is_boxy}```