Skip to content

Instantly share code, notes, and snippets.

@fr0zn
Created September 7, 2019 10:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fr0zn/9f0167161069d65128ec4f31c187b432 to your computer and use it in GitHub Desktop.
Save fr0zn/9f0167161069d65128ec4f31c187b432 to your computer and use it in GitHub Desktop.
r = open('level2','rb').read()
b = bytearray(r)
mem = bytearray([0] * 0x100000)
mem[0:len(b)] = b[0:len(b)]
pc = 0
stack = []
# def split_n(line,n=4):
# return [line[i:i+n] for i in range(0, len(line), n)]
def tohex(val, nbits=32):
return hex((val + (1 << nbits)) % (1 << nbits))
def print_pc(_str):
print "{:08x} {}".format(pc, _str)
def parse_instruction(b):
global pc
if mem[pc] == 0:
print_pc("NOP")
pc += 1
elif mem[pc] == 0x10:
val = int(str(mem[pc+1:pc+1+4]).encode('hex'), 16)
print_pc("PUSH " + hex(val))
stack.append(val)
pc += 5
elif mem[pc] == 0x20:
addr = stack.pop()
value = stack.pop()
print_pc("STORE @ {} -> {}".format(hex(addr), hex(value)))
mem[addr] = value & 0xff
mem[addr+1] = (value >> 8) & 0xff
mem[addr+2] = (value >> 16) & 0xff
mem[addr+3] = (value >> 24) & 0xff
pc += 1
elif mem[pc] == 0x21:
addr = stack.pop()
# dst = stack.pop()
# val = 0
val = mem[addr]
val += mem[addr+1] << 8
val += mem[addr+2] << 16
val += mem[addr+3] << 24
print_pc("PUSH [{}] -> {}".format(hex(addr), hex(val)))
stack.append(val)
pc += 1
elif mem[pc] == 0x30:
n1 = stack.pop()
n2 = stack.pop()
stack.append(n1 + n2)
print_pc("ADD {} + {} -> {}".format(hex(n1), hex(n2), hex(n1+n2)))
pc += 1
elif mem[pc] == 0x31:
n1 = stack.pop()
n2 = stack.pop()
stack.append(n1 ^ n2)
print_pc("XOR {} ^ {} -> {}".format(tohex(n1), tohex(n2), tohex(n1 ^ n2)))
pc += 1
elif mem[pc] == 0x32:
n1 = stack.pop()
n2 = stack.pop()
if n1 == n2:
r = 0
elif n1 <= n2:
r = -1
else:
r = 1
stack.append(r)
print_pc("CMP {} and {} -> {}".format(tohex(n1), tohex(n2), r ))
pc += 1
elif mem[pc] == 0x33:
n1 = stack.pop()
n2 = stack.pop()
stack.append(n1 * n2)
print_pc("MULTIPLY {} * {}".format(n1, n2))
pc += 1
elif mem[pc] == 0x38:
n1 = stack.pop()
stack.append(~n1)
print_pc("NEGATE {} -> {}".format(hex(n1), tohex(~n1)))
pc += 1
elif mem[pc] == 0x41:
addr = stack.pop()
print_pc("JMP @ {}".format(hex(addr)))
pc = addr
elif mem[pc] == 0x42:
addr = stack.pop()
result = stack.pop()
print_pc("JMP Z CONDITIONAL {} to addr {}".format(result, hex(addr)))
if result != 0:
pc += 1
else:
pc = addr
elif mem[pc] == 0x44:
addr = stack.pop()
result = stack.pop()
print_pc("JMP BIGGER CONDITIONAL {} to addr {}".format(result, hex(addr)))
if result == 1:
pc = addr
else:
pc += 1
elif mem[pc] == 0x45:
addr = stack.pop()
result = stack.pop()
print_pc("JMP NZ CONDITIONAL {} to addr {}".format(result, hex(addr)))
if result != 0:
pc = addr
else:
pc += 1
elif mem[pc] == 0x50:
# one of the ops only 2 possible in level1
op = stack.pop()
if op == 0:
n = stack.pop()
n2 = stack.pop()
print_pc("READING @ {} ({} bytes) ".format(hex(n2), n))
r = raw_input("READING {} bytes: ".format(n))
mem[n2:n2+n] = r[:n]
elif op == 1:
count = stack.pop()
addr = stack.pop()
print_pc("PRINTING from @ {} ({} bytes)".format(hex(addr), count))
print_pc(mem[addr:addr+count])
else:
print_pc("UNK OP")
pc += 1
else:
print_pc("UNK " + hex(mem[pc]))
import sys
sys.exit()
pc += 1
count = 0
end = 10000
# while pc <= len(b):
# while pc <= 0x500: #and mem[0x1000] != 1:
while count <= end and mem[0x80000] != 1:
parse_instruction(b)
count += 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment