def reset_app(): global machine machine = Machine() orc = orc_parser.parse("chall2.exe") segment = orc.segments[1] base = segment.base.int_value() offset = segment.offset.int_value() data = orc.data for i in range(segment.size.int_value()): machine.memory.write_byte(Word.from_int(base + i), data[offset + i]) machine.registers[Register.pc] = Word.from_int(base)
def run(self, machine): current = machine.registers[Register.pc].int_value() offset = machine.registers[self.value_register].int_value() return MachineUpdate( registers={ Register.pc: Word.from_int(current + offset + self.size), })
def __init__(self): self.memory = Memory() self.registers = [ Word(Byte(0b0), Byte(0b0), Byte(0b0), Byte(0b0)) for _ in Register ] self.registers[Register.sp] = Word.from_int(self.memory.size - 1 - 4) self.stdout = [] self.stdin = [] self.flags = set()
def run(self, machine): if (Flag.SF in machine.flags) == (Flag.OF in machine.flags): return MachineUpdate() current = machine.registers[Register.pc].int_value() offset = self.value_word.int_value() updated_pc = Word.from_int(current + offset + self.size) return MachineUpdate(registers={ Register.pc: updated_pc, })
def run(self, machine): if Flag.ZF not in machine.flags: return MachineUpdate() current = machine.registers[Register.pc].int_value() offset = machine.registers[self.value_register].int_value() updated_pc = Word.from_int(current + offset + self.size) return MachineUpdate(registers={ Register.pc: updated_pc, })
def subtract_word(word1, word2): flags = set() int_result = word1.int_value() - word2.int_value() if int_result == 0: flags.add(Flag.ZF) sign_bit = 1 << 27 if int_result & sign_bit: flags.add(Flag.SF) return Word.from_int(int_result), flags
def add_word(word1, word2): flags = set() int_sum = word1.int_value() + word2.int_value() if int_sum == 0: flags.add(Flag.ZF) sign_bit = 1 << 27 overflow_bit = 1 << 28 if int_sum & sign_bit: flags.add(Flag.SF) if int_sum & overflow_bit: flags.add(Flag.CF) if not ((word1.int_value() & sign_bit) ^ (word2.int_value() & sign_bit)): flags.add(Flag.OF) return Word.from_int(int_sum), flags
def render_emulator(): instruction = machine.next_instruction() if not instruction: instruction_view = "--" else: instruction_view = instruction.human() available_actions = set() if instruction: available_actions.add("step") instruction_views = [] for address, instruction in machine.glob_instructions(): instruction_views.append( DisassembledInstructionView( address == machine.registers[Register.pc].int_value(), Word.from_int(address).hex_str(human=True), instruction.debug_str(), instruction_helper.bytes_str(instruction), instruction.human() ) ) disassembled_view = DisassembledView(instruction_views) registers_view = [ RegisterView(register.name, machine.registers[register.value].hex_str()) for register in Register ] memory = machine.memory columns = 4 memory_view = MemoryView(columns, [ MemoryRowView( Word.from_int(row * columns * 4).hex_str(human=True), [ memory.read_word((row * columns + column) * 4).hex_str() for column in range(columns) if (row * columns + column) * 4 < memory.size ] ) for row in range(math.ceil(memory.size / (columns * 4))) ]) stack_pointer = machine.registers[Register.sp].int_value() stack_view = StackView(1, [ StackRowView( row == 0, Word.from_int(stack_pointer + row * 4).hex_str(human=True), [ memory.read_word(stack_pointer + row * 4).hex_str(human=True) ] ) for row in range(((memory.size - 1) - stack_pointer) // 4) ]) flags_view = [ FlagView(flag.name, flag.value in machine.flags) for flag in Flag ] stdout_view = "".join([ chr(char.int_value) for char in machine.stdout ]) return render_template( "emulator.html", instruction=instruction_view, registers=registers_view, flags=flags_view, disassembled=disassembled_view, stack=stack_view, memory=memory_view, stdout=stdout_view, available_actions=available_actions )
def run(filename, break_, input_): orc = orc_parser.parse(filename) machine = emulator.Machine() if input_: machine.stdin = list(input_) for segment in orc.segments: for i in range(segment.size.int_value()): memory_location = Word.from_int(segment.base.int_value() + i) data_location = segment.offset.int_value() + i data_value = orc.data[data_location] machine.memory.write_byte(memory_location, data_value) machine.registers[Register.pc] = orc.entry_point instruction = machine.next_instruction() while instruction: print(machine.registers[Register.pc].hex_str(human=True), instruction.human()) if machine.registers[Register.pc].int_value() == break_: command = input("> ").strip() while command: if command == "debug": breakpoint() elif command == "continue": break elif command == "step": machine.run(instruction) instruction = machine.next_instruction() if instruction: print(instruction.human()) elif command == "registers": for register in Register: print( f"{register.name}: {machine.registers[register].hex_str()}" ) elif command.startswith("print"): _, variable = command.split(" ") if variable.startswith("0x"): address_hex = variable address = hex_parser.int_from_by7e_hex(address_hex) word = machine.memory.read_word(address) else: register_name = variable register = Register[register_name] word = machine.registers[register] print(word) elif command.startswith("memory"): _, address_hex = command.split(" ") address = hex_parser.int_from_by7e_hex(address_hex) for section in range(4): section_address = address + section * 4 word = machine.memory.read_word(section_address) formatted_address = Word.from_int( section_address).hex_str(human=True) print(formatted_address, word.hex_str()) elif command.startswith("disassemble"): _, address_hex = command.split(" ") address = hex_parser.int_from_by7e_hex(address_hex) for fake_address, fake_instruction in machine.glob_instructions( address): formatted_address = Word.from_int( fake_address).hex_str(human=True) print(formatted_address, fake_instruction.human()) elif command == "web": import app app.routes.override_app(machine) app.app.run() elif command == "help": print(help_str) else: print("Unknown command:", command) command = input("> ").strip() machine.run(instruction) instruction = machine.next_instruction() # print("".join([ str(char) for char in machine.stdout ])) print("".join([chr(char.int_value) for char in machine.stdout]))
def test_one_plus_one(): word, flags = add_word(Word.from_int(1), Word.from_int(1)) assert (word.int_value() == 2) assert (not flags)
def test_set_zero_flag(): word, flags = add_word(Word.from_int(0), Word.from_int(0)) assert (word.int_value() == 0) assert (flags == set([Flag.ZF]))
def test_three_minus_one(): word, flags = subtract_word(Word.from_int(3), Word.from_int(1)) assert (word.int_value() == 2) assert (not flags)
def test_signed_flag(): # result = -2 -> (2 == 0b0000010) # 2's complement -> 0b1111101 + 0b1 -> 0b1111110 word, flags = subtract_word(Word.from_int(1), Word.from_int(3)) assert (word == Word(Byte(0b1111110), Byte(0x7f), Byte(0x7f), Byte(0x7f))) assert (flags == set([Flag.SF]))
def test_one_minus_one_sets_zero_flag(): word, flags = subtract_word(Word.from_int(1), Word.from_int(1)) assert (word.int_value() == 0) assert (flags == set([Flag.ZF]))