# Emulation, 50 points

## Description

Hey! We have found this old cartridge under a desk in the library of Lapland. It appears to be for a system called "Emu 2.0", made back in 1978. These systems don't get produced anymore, and we can't seem to find anyone that owns one.

Thankfully we have the documentation for it, so maybe we can use it to write an emulator and see what this ROM does?

Author: Milkdrop

Files : rom, documentation.pdf

## Solution

This challenge was pretty straightforward; we were given a ROM file along with a short 3-page specification, and we had to code an emulator to run the ROM which would print out the flag.

There's nothing much to detail further, so here's my implementation of the emulator in Python.

`import sys​def emulate(filename):    rom = open(filename, 'rb').read()    assert len(rom) == 0xf00​    A = 0    PC = 0x100    mem =  * 0x100 + [x for x in rom]    blocked = [False] * 0x1000​    while 0 <= PC < 0xfff:        op = mem[PC:PC + 2]​        # Arithmetic        if op == 0x00:            A = (A + op) & 0xff        elif op == 0x01:            A = op        elif op == 0x02:            A ^= op        elif op == 0x03:            A |= op        elif op == 0x04:            A &= op        elif op >> 4 == 0x08:            A = mem[((op & 0x0f) << 8) | op]        elif op >> 4 == 0x0d:            if not blocked[((op & 0x0f) << 8) | op]:                mem[((op & 0x0f) << 8) | op] ^= A        elif op >> 4 == 0x0f:            if not blocked[((op & 0x0f) << 8) | op]:                mem[((op & 0x0f) << 8) | op] = A​        # I/O                elif op == 0x13 and op == 0x37:            sys.stdout.write(chr(A))            sys.stdout.flush()​        # Control Flow        elif op >> 4 == 0x02:            PC = ((op & 0x0f) << 8) | op            continue        elif op >> 4 == 0x03:            if A == 0x00:                PC = ((op & 0x0f) << 8) | op                continue        elif op >> 4 == 0x04:            if A == 0x01:                PC = ((op & 0x0f) << 8) | op                continue        elif op >> 4 == 0x05:            if A == 0xff:                PC = ((op & 0x0f) << 8) | op                continue        elif op == 0x60:            if A == op:                A = 0x00            elif A > op:                A = 0xff            else:                A = 0x01        elif op >> 4 == 0x07:            c = mem[((op & 0x0f) << 8) | op]            if A == c:                A = 0x00            elif A > c:                A = 0xff            else:                A = 0x01        elif op == 0xbe and op == 0xef:            PC = 0x100            A = 0x42            continue​        # Security        elif op >> 4 == 0x09:            blocked[((op & 0x0f) << 8) | op] = True        elif op >> 4 == 0x0a:            blocked[((op & 0x0f) << 8) | op] = False        elif op >> 4 == 0x0c:            if not blocked[((op & 0x0f) << 8) | op]:                mem[((op & 0x0f) << 8) | op] ^= 0x42​        # Misc        elif op == 0xee and op == 0xee:            pass​        else:            A = (A - 1) & 0xff​        PC += 2​if __name__ == '__main__':    if len(sys.argv) != 2:        print('[-] Usage: %s <romfile>' % sys.argv)        sys.exit(1)    sys.exit(emulate(sys.argv))`

Let's run it on the file.

`╭─face0xff@aniesu-chan /den/ctf/xmas  ╰─\$ python rom.py rom                                                                                                                                                                                      1 ↵X-MAS{S4nt4_U5e5_An_Emu_2.0_M4ch1n3}`

We can notice the program actually never ends because it is stuck in an infinite loop. Indeed, at PC=0x408, the instruction is `24 08` which means "jump to 0x408".

Enjoy