Esempio n. 1
0
def get_arch(binary):
    if binary.architecture == ARCH_X86:
        return X86ArchitectureInformation(binary.architecture_mode)
    elif binary.architecture == ARCH_ARM:
        return ArmArchitectureInformation(binary.architecture_mode)
    else:
        raise Exception("Architecture not supported.")
Esempio n. 2
0
    def __init__(self, architecture_mode):
        super(X86Translator, self).__init__()

        # Set *Architecture Mode*. The translation of each instruction
        # into the REIL language is based on this.
        self._arch_mode = architecture_mode

        # An instance of *ArchitectureInformation*.
        self._arch_info = X86ArchitectureInformation(architecture_mode)

        self._builder = ReilBuilder()

        self._registers = RegisterTranslator(self._arch_info)

        self._reg_acc_translator = X86OperandAccessTranslator(self._arch_info)

        self._flags = FlagTranslator(self._arch_info)

        self._flag_translator = X86FlagTranslator(self._flags)

        # Special registers.
        if self._arch_mode == ARCH_X86_MODE_32:
            self._sp = self._registers.esp
            self._bp = self._registers.ebp
            self._ip = self._registers.eip

        if self._arch_mode == ARCH_X86_MODE_64:
            self._sp = self._registers.rsp
            self._bp = self._registers.rbp
            self._ip = self._registers.rip

        # Word size.
        self._ws = ReilImmediateOperand(self._arch_info.address_size // 8,
                                        self._arch_info.address_size)
Esempio n. 3
0
    def setUp(self):
        self._arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32)

        self._emulator = ReilEmulator(self._arch_info)

        self._asm_parser = X86Parser(ARCH_X86_MODE_32)
        self._translator = X86Translator(ARCH_X86_MODE_32)
Esempio n. 4
0
    def __init__(self, ir_name_generator, architecture_mode):
        super(X86TranslationBuilder,
              self).__init__(ir_name_generator,
                             X86ArchitectureInformation(architecture_mode))

        self._regs_mapper = self._arch_info.alias_mapper

        self._regs_size = self._arch_info.registers_size
Esempio n. 5
0
    def test_se_1(self):
        binary = BinaryFile(get_full_path("/data/bin/check_serial_1"))

        arch_info = X86ArchitectureInformation(binary.architecture_mode)

        functions = [("check_serial", 0x0804841d, 0x08048452)]

        reil_container = ReilContainerBuilder(binary).build(functions)

        # Set up initial state
        initial_state = State(arch_info, mode="initial")

        # Set up stack
        esp = 0xffffceec

        initial_state.write_register("esp", esp)

        # Set up parameters
        user_password_addr = 0xdeadbeef
        user_password_len = 0x6

        initial_state.write_memory(esp + 0x4, 4,
                                   user_password_addr)  # password
        initial_state.write_memory(esp + 0x0, 4,
                                   0x41414141)  # fake return address

        # Each byte of the password should be an ascii char.
        for i in xrange(0, user_password_len):
            value = initial_state.query_memory(user_password_addr + i, 1)

            initial_state.add_constraint(value.uge(0x21))
            initial_state.add_constraint(value.ule(0x7e))

        sym_exec = ReilSymbolicEmulator(arch_info)

        paths = sym_exec.find_address(reil_container,
                                      start=0x0804841d,
                                      end=0x08048452,
                                      find=0x08048451,
                                      avoid=[0x0804843b],
                                      initial_state=initial_state)

        # There's only one way to reach 'find' address.
        self.assertEqual(len(paths), 1)

        final_state = State(arch_info, mode="final")

        user_password_expected = bytearray("AAAAAA")
        user_password = bytearray()

        se_res = SymExecResult(arch_info, initial_state, paths[0], final_state)

        for i in xrange(0, user_password_len):
            value = se_res.query_memory(user_password_addr + i, 1)
            user_password.append(value)

        self.assertEqual(user_password, user_password_expected)
Esempio n. 6
0
 def __init__(self, binary):
     self.__binary = binary
     self.__arch_mode = self.__binary.architecture_mode
     self.__arch = X86ArchitectureInformation(self.__arch_mode)
     self.__disassembler = X86Disassembler(self.__arch_mode)
     self.__translator = X86Translator(self.__arch_mode)
     self.__bb_builder = CFGRecoverer(
         RecursiveDescent(self.__disassembler, self.__binary.text_section,
                          self.__translator, self.__arch))
Esempio n. 7
0
    def test_se_6(self):
        binary = BinaryFile(get_full_path("/data/bin/check_serial_6"))

        arch_info = X86ArchitectureInformation(binary.architecture_mode)

        functions = [("expand", 0x0804849b, 0x080484dd)]

        reil_container = ReilContainerBuilder(binary).build(functions)

        # Set up initial state
        initial_state = State(arch_info, mode="initial")

        # Set up stack
        esp = 0xffffceec

        initial_state.write_register("esp", esp)

        # Set up parameters
        out_array_addr = 0xdeadbeef
        in_array_addr = 0xdeadbeef + 0x5

        initial_state.write_memory(esp + 0x04, 4, out_array_addr)  # out
        initial_state.write_memory(esp + 0x08, 4, in_array_addr)  # in
        initial_state.write_memory(esp + 0x0c, 4, 0xAAAAAAAA)
        initial_state.write_memory(esp + 0x10, 4, 0xBBBBBBBB)

        # Set the in array
        for i, b in enumerate(bytearray("\x02\x03\x05\x07")):
            initial_state.write_memory(in_array_addr + i, 1, b)

        #
        # Set up final state
        #
        final_state = State(arch_info, mode="final")

        # Set the B array
        for i, b in enumerate(bytearray("\xFC\xFB\xF5\xF7")):
            final_state.write_memory(out_array_addr + i, 1, b)

        start_addr = 0x0804849b
        end_addr = 0x080484dd

        sym_exec = ReilSymbolicEmulator(arch_info)

        paths = sym_exec.find_state(reil_container,
                                    start=start_addr,
                                    end=end_addr,
                                    initial_state=initial_state,
                                    final_state=final_state)

        # There's only one way to reach 'find' address.
        self.assertEqual(len(paths), 1)

        se_res = SymExecResult(arch_info, initial_state, paths[0], final_state)

        self.assertEqual(se_res.query_memory(esp + 0x4, 4), 0xdeadbeef)
        self.assertEqual(se_res.query_memory(esp + 0x8, 4), 0xdeadbef4)
    def setUp(self):
        self._address_size = 32
        self._parser = ReilParser()
        self._solver = SmtSolver()
        self._translator = SmtTranslator(self._solver, self._address_size)

        self._arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32)

        self._translator.set_arch_alias_mapper(self._arch_info.alias_mapper)
        self._translator.set_arch_registers_size(self._arch_info.registers_size)
Esempio n. 9
0
    def setUp(self):
        self.arch_mode = ARCH_X86_MODE_64

        self.arch_info = X86ArchitectureInformation(self.arch_mode)

        self.x86_parser = X86Parser(self.arch_mode)
        self.x86_translator = X86Translator(self.arch_mode)
        self.reil_emulator = ReilEmulator(self.arch_info)

        self.context_filename = "failing_context.data"
Esempio n. 10
0
    def __init__(self, architecture_mode):
        global arch_info, modifier_size

        arch_info = X86ArchitectureInformation(architecture_mode)

        self._cache = {}

        modifier_size["far ptr"] = arch_info.architecture_size
        modifier_size["far"] = arch_info.architecture_size
        modifier_size["ptr"] = arch_info.architecture_size
Esempio n. 11
0
    def __init__(self, architecture_mode):
        super(X86Disassembler, self).__init__()

        arch_mode_map = {
            ARCH_X86_MODE_32: CS_MODE_32,
            ARCH_X86_MODE_64: CS_MODE_64
        }

        self._arch_mode = architecture_mode
        self._arch_info = X86ArchitectureInformation(architecture_mode)

        self._parser = X86Parser(architecture_mode)
        self._disassembler = Cs(CS_ARCH_X86, arch_mode_map[architecture_mode])
Esempio n. 12
0
    def test_emulate_x86_64(self):
        binary = BinaryFile(get_full_path("./samples/bin/loop-simple.x86_64"))
        arch_mode = ARCH_X86_MODE_64
        arch_info = X86ArchitectureInformation(arch_mode)
        ir_emulator = ReilEmulator(arch_info)
        disassembler = X86Disassembler(ARCH_X86_MODE_64)
        ir_translator = X86Translator(ARCH_X86_MODE_64)

        emu = Emulator(arch_info, ir_emulator, ir_translator, disassembler)

        emu.load_binary(binary)

        emu.emulate(0x4004d6, 0x400507, {}, None, False)
Esempio n. 13
0
    def __init__(self, binary, symbols):
        self.__binary = binary
        self.__arch_mode = self.__binary.architecture_mode
        self.__arch = X86ArchitectureInformation(self.__arch_mode)
        self.__disassembler = X86Disassembler(self.__arch_mode)
        self.__translator = X86Translator(self.__arch_mode)
        self.__bb_builder = CFGRecoverer(
            RecursiveDescent(self.__disassembler, self.__binary.text_section,
                             self.__translator, self.__arch))

        self.__container = {}
        self.__symbols = symbols

        self.__symbols_by_addr = {}

        for name, start, end in symbols:
            self.__symbols_by_addr[start] = (name, end)
Esempio n. 14
0
    def setUp(self):
        self._arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32)

        self._smt_solver = SmtSolver()

        self._smt_translator = SmtTranslator(self._smt_solver,
                                             self._arch_info.address_size)
        self._smt_translator.set_arch_alias_mapper(
            self._arch_info.alias_mapper)
        self._smt_translator.set_arch_registers_size(
            self._arch_info.registers_size)

        self._x86_parser = X86Parser(ARCH_X86_MODE_32)

        self._x86_translator = X86Translator(ARCH_X86_MODE_32)

        self._code_analyzer = CodeAnalyzer(self._smt_solver,
                                           self._smt_translator,
                                           self._arch_info)
Esempio n. 15
0
    def __init__(self, architecture_mode):

        super(X86Translator, self).__init__()

        # Set *Architecture Mode*. The translation of each instruction
        # into the REIL language is based on this.
        self._arch_mode = architecture_mode

        # An instance of *ArchitectureInformation*.
        self._arch_info = X86ArchitectureInformation(architecture_mode)

        # An instance of a *VariableNamer*. This is used so all the
        # temporary REIL registers are unique.
        self._ir_name_generator = VariableNamer("t", separator="")

        self._builder = ReilBuilder()

        self._flags = {
            "af": ReilRegisterOperand("af", 1),
            "cf": ReilRegisterOperand("cf", 1),
            "df": ReilRegisterOperand("df", 1),
            "of": ReilRegisterOperand("of", 1),
            "pf": ReilRegisterOperand("pf", 1),
            "sf": ReilRegisterOperand("sf", 1),
            "zf": ReilRegisterOperand("zf", 1),
        }

        if self._arch_mode == ARCH_X86_MODE_32:
            self._sp = ReilRegisterOperand("esp", 32)
            self._bp = ReilRegisterOperand("ebp", 32)
            self._ip = ReilRegisterOperand("eip", 32)

            self._ws = ReilImmediateOperand(4, 32)  # word size
        elif self._arch_mode == ARCH_X86_MODE_64:
            self._sp = ReilRegisterOperand("rsp", 64)
            self._bp = ReilRegisterOperand("rbp", 64)
            self._ip = ReilRegisterOperand("rip", 64)

            self._ws = ReilImmediateOperand(8, 64)  # word size
Esempio n. 16
0
def main():
    # Process program arguments.
    parser = init_parser()
    args = parser.parse_args()

    # Open binary.
    binary = BinaryFile(args.binary)

    # Check binary arch and mode.
    if binary.architecture != ARCH_X86 or \
            binary.architecture_mode not in [ARCH_X86_MODE_32, ARCH_X86_MODE_64]:
        print("[!] Architecture not supported.")
        sys.exit(1)

    # Load architecture information for the binary.
    arch_info = X86ArchitectureInformation(binary.architecture_mode)

    # Extract entrypoint (in case a starting address was not provided.)
    start_address = int(args.start_address,
                        16) if args.start_address else binary.entry_point

    # Prepare options.
    options = DotDict({})
    options.abort = args.abort
    options.color = args.color
    options.verbose = args.verbose

    print("[+] Loading trace...")
    asm_trace = parse_trace(args.trace,
                            X86Parser(arch_info.architecture_mode),
                            start_address=start_address)

    print("[+] Replaying trace...")
    analyzer = AsmReplayAnalyzer(arch_info, asm_trace, start_address, options)

    analyzer.run()
Esempio n. 17
0
def solve():
    #
    # Load binary
    #
    binary = BinaryFile("bin/very_success")

    arch_info = X86ArchitectureInformation(binary.architecture_mode)

    # Create a REIL container for the function of interest
    functions = [("sub_401084", 0x00401084, 0x004010de)]

    reil_container = ReilContainerBuilder(binary).build(functions)

    #
    # Set up initial state
    #
    initial_state = State(arch_info, mode="initial")

    # Set up stack
    esp = 0xffffceec

    initial_state.write_register("esp", esp)

    # Set up parameters
    user_password_addr = 0x00402159
    user_password_len = 0x25
    ref_key_addr = 0x004010e4

    initial_state.write_memory(esp + 0xc, 4, user_password_len)
    initial_state.write_memory(esp + 0x8, 4, user_password_addr)
    initial_state.write_memory(esp + 0x4, 4, ref_key_addr)
    initial_state.write_memory(esp + 0x0, 4, 0x41414141)  # return address

    # Set memory
    for i in xrange(user_password_len):
        initial_state.write_memory(ref_key_addr + i, 1,
                                   ord(binary.text_section[ref_key_addr + i]))

    #
    # Run concolic execution
    #
    sym_exec = ReilSymbolicEmulator(arch_info)

    paths = sym_exec.find_address(reil_container,
                                  start=0x00401084,
                                  end=0x004010de,
                                  find=0x004010d5,
                                  avoid=[0x004010d7],
                                  initial_state=initial_state)

    # There's only one way to reach 'find' address.
    assert len(paths) == 1

    #
    # Query input buffer and print content
    #
    final_state = State(arch_info, mode="final")

    se_res = SymExecResult(arch_info, initial_state, paths[0], final_state)

    user_password = bytearray()

    for i in xrange(user_password_len):
        user_password.append(se_res.query_memory(user_password_addr + i, 1))

    print("User password: {}".format(user_password))

    assert user_password == bytearray("*****@*****.**")
Esempio n. 18
0
 def setUp(self):
     self._arch_mode = ARCH_X86_MODE_32
     self._arch_info = X86ArchitectureInformation(self._arch_mode)
     self._disassembler = X86Disassembler(ARCH_X86_MODE_32)
     self._translator = X86Translator(ARCH_X86_MODE_32)
Esempio n. 19
0
def solve():
    #
    # Load Binary
    #
    binary = BinaryFile("bin/toyproject.exe")

    arch_info = X86ArchitectureInformation(binary.architecture_mode)

    # Identify functions of interest
    functions = [("sub_4010ec", 0x004010ec, 0x004010ec + 0x3a)]

    # Create a REIL container
    reil_container_builder = ReilContainerBuilder(binary)

    reil_container = reil_container_builder.build(functions)

    #
    # Set up initial state
    #
    initial_state = State(arch_info, mode="initial")

    # Set up stack
    esp = 0x00001500

    initial_state.write_register("esp", esp)

    # Set up parameters
    out_array_addr = esp - 0x25
    in_array_addr = 0x4093a8

    initial_state.write_memory(esp + 0x0, 4, 0x41414141)  # fake return address

    # TODO: Find a way to mark 'x' and 'y' as symbolic variables.
    # initial_state.write_memory(esp + 0x4, 4, x) # Mark as Symbolic
    # initial_state.write_memory(esp + 0x8, 4, y) # Mark as Symbolic

    # Set the A array
    in_array_expected = bytearray(__get_in_array())

    for i in range(len(in_array_expected)):
        initial_state.write_memory(in_array_addr + i, 1, in_array_expected[i])

    #
    # Set up final state
    #
    final_state = State(arch_info, mode="final")

    # Set the B array
    out_array_expected = bytearray(__get_out_array(), encoding='ascii')

    for i in range(32):
        # Avoid trivial solution
        initial_state.write_memory(out_array_addr + i, 1, 0)

        # Assert final (desired) state
        final_state.write_memory(out_array_addr + i, 1, out_array_expected[i])

    #
    # Run concolic execution
    #
    sym_exec = ReilSymbolicEmulator(arch_info)

    paths = sym_exec.find_state(reil_container,
                                start=0x004010ec,
                                end=0x0040111d,
                                initial_state=initial_state,
                                final_state=final_state)

    # There's only one way to reach the final state.
    # assert len(paths) == 1

    print("[+] Number of paths: {}".format(len(paths)))

    # for index, path in enumerate(paths):
    #     __save_path(path, index)

    #
    # Query input buffer and print content
    #
    print("A (in)  : {:s}".format(" ".join(
        ["{:02x}".format(b) for b in in_array_expected])))
    print("B (out) : {:s}".format(" ".join(
        ["{:02x}".format(b) for b in out_array_expected])))

    if len(paths) > 0:
        se_res = SymExecResult(arch_info, initial_state, paths[0], final_state)

        print("x: {0:#010x} ({0:d})".format(se_res.query_memory(esp + 0x4, 4)))
        print("y: {0:#010x} ({0:d})".format(se_res.query_memory(esp + 0x8, 4)))
    else:
        print("[-] State Not Found!")