예제 #1
0
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)
예제 #2
0
    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),
            })
예제 #3
0
 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()
예제 #4
0
    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,
        })
예제 #5
0
    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,
        })
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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
    )
예제 #9
0
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]))
예제 #10
0
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)
예제 #11
0
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]))
예제 #12
0
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)
예제 #13
0
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]))
예제 #14
0
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]))