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