def __resolve_loops(self, address, instrs):
        # Collect labels.
        idx_by_labels = {}
        instrs_no_labels = []
        curr = 0

        for i in instrs:
            if isinstance(i, ReilLabel):
                idx_by_labels[i.name] = curr
            else:
                instrs_no_labels.append(i)
                curr += 1

        instrs[:] = instrs_no_labels

        # Resolve instruction addresses and JCC targets.
        for index, instr in enumerate(instrs):
            instr.address = to_reil_address(address, index)

            if instr.mnemonic == ReilMnemonic.JCC:
                target = instr.operands[2]

                if isinstance(target, ReilLabel):
                    addr = to_reil_address(address, idx_by_labels[target.name])
                    size = self._arch_info.address_size + 8

                    instr.operands[2] = ReilImmediateOperand(addr, size)

        return instrs
Beispiel #2
0
    def __resolve_loops(self, address, instrs):
        # Collect labels.
        idx_by_labels = {}
        instrs_no_labels = []
        curr = 0

        for i in instrs:
            if isinstance(i, ReilLabel):
                idx_by_labels[i.name] = curr
            else:
                instrs_no_labels.append(i)
                curr += 1

        instrs[:] = instrs_no_labels

        # Resolve instruction addresses and JCC targets.
        for index, instr in enumerate(instrs):
            instr.address = to_reil_address(address, index)

            if instr.mnemonic == ReilMnemonic.JCC:
                target = instr.operands[2]

                if isinstance(target, ReilLabel):
                    addr = to_reil_address(address, idx_by_labels[target.name])
                    size = self._arch_info.address_size + 8

                    instr.operands[2] = ReilImmediateOperand(addr, size)

        return instrs
Beispiel #3
0
    def find_state(self, container, start=None, end=None, avoid=None, initial_state=None, final_state=None):
        """Execute instructions.
        """
        self.__set_cpu_state(initial_state)

        # Convert input native addresses to reil addresses.
        start = to_reil_address(start) if start else None
        end = to_reil_address(end) if end else None
        avoid = [to_reil_address(addr) for addr in avoid] if avoid else []

        # Load instruction pointer.
        ip = start if start else container[0].address

        execution_state = Queue()

        trace_current = []
        trace_final = []

        self.__fs_process_container(container, final_state, ip, end, avoid, initial_state, execution_state,
                                    trace_current, trace_final)

        # Only returns when all paths have been visited.
        assert execution_state.empty()

        return trace_final
Beispiel #4
0
    def __execute(self, asm_instr):
        # Process one assembler instruction. Translate it to REIL instruction and
        # process each one.
        instr_container = self.__translate(asm_instr)
        ip = to_reil_address(asm_instr.address)
        next_addr = None

        while ip:
            # Fetch instruction.
            try:
                reil_instr = instr_container.fetch(ip)
            except ReilContainerInvalidAddressError:
                next_addr, _ = split_address(ip)
                break

            if reil_instr.mnemonic == ReilMnemonic.UNKN:
                raise InstructionNotImplemented(asm_instr)

            # Execute instruction.
            next_ip = self.ir_emulator.single_step(reil_instr)

            # Update instruction pointer.
            ip = next_ip if next_ip else instr_container.get_next_address(ip)

        del instr_container

        # delete temporal registers
        regs = self.ir_emulator.registers.keys()

        for r in regs:
            if r.startswith("t"):
                del self.ir_emulator.registers[r]

        return next_addr if next_addr else asm_instr.address + asm_instr.size
Beispiel #5
0
    def __execute(self, asm_instr):
        # Process one assembler instruction. Translate it to REIL instruction and
        # process each one.
        instr_container = self.__translate(asm_instr)
        ip = to_reil_address(asm_instr.address)
        next_addr = None

        while ip:
            # Fetch instruction.
            try:
                reil_instr = instr_container.fetch(ip)
            except ReilContainerInvalidAddressError:
                next_addr, _ = split_address(ip)
                break

            if reil_instr.mnemonic == ReilMnemonic.UNKN:
                raise InstructionNotImplemented(asm_instr)

            # Execute instruction.
            next_ip = self.ir_emulator.single_step(reil_instr)

            # Update instruction pointer.
            ip = next_ip if next_ip else instr_container.get_next_address(ip)

        del instr_container

        # Execute post instruction handlers
        handler_fn_post, handler_param_post = self.__instr_handler_post
        handler_fn_post(self, asm_instr, handler_param_post)

        # delete temporal registers
        regs = self.ir_emulator.registers.keys()

        for r in regs:
            if r.startswith("t"):
                del self.ir_emulator.registers[r]

        return next_addr if next_addr else asm_instr.address + asm_instr.size
Beispiel #6
0
    def emulate(self, start_addr, end_addr, hooks, max_instrs, print_asm):
        # Switch arch mode accordingly for ARM base on the start address.
        if isinstance(self.arch_info, ArmArchitectureInformation):
            if start_addr & 0x1 == 0x1:
                start_addr = start_addr & ~0x1
                end_addr = end_addr & ~0x1

                self._arch_mode = ARCH_ARM_MODE_THUMB
            else:
                self._arch_mode = ARCH_ARM_MODE_ARM

        execution_cache = ExecutionCache()

        next_addr = start_addr
        instr_count = 0
        asm_instr = None

        while next_addr != end_addr:
            if max_instrs and instr_count > max_instrs:
                break

            # Process hooks.
            if next_addr in hooks:
                logger.debug("Hooking @ {:#x}".format(next_addr))

                fn, param, skip, offset = hooks[next_addr]

                fn(self.ir_emulator, param)

                # Compute next address after hook.
                if skip:
                    if isinstance(self.arch_info, X86ArchitectureInformation):
                        # Pop return address from the stack.
                        next_addr = self.ir_emulator.read_memory(
                            self.ir_emulator.registers[self.sp], self.ws)
                        self.ir_emulator.registers[self.sp] += self.ws

                    if isinstance(self.arch_info, ArmArchitectureInformation):
                        # Load return address from the link register.
                        next_addr = self.ir_emulator.registers["r14"]

                logger.debug("Continuing @ {:#x}".format(next_addr))

            try:
                # Retrieve next instruction from the execution cache.
                asm_instr, reil_container = execution_cache.retrieve(next_addr)
            except InvalidAddressError:
                # Fetch the instruction.
                encoding = self.__fetch_instr(next_addr)

                # Decode it.
                asm_instr = self.disassembler.disassemble(
                    encoding, next_addr, architecture_mode=self._arch_mode)

                # Translate it.
                reil_container = self.__build_reil_container(asm_instr)

                # Add it to the execution cache.
                execution_cache.add(next_addr, asm_instr, reil_container)

            # Update the instruction pointer.
            self.__update_ip(asm_instr)

            # Execute instruction.
            if print_asm:
                print("{:#x} {}".format(asm_instr.address, asm_instr))

            target_addr = self.__process_reil_container(
                reil_container, to_reil_address(next_addr))

            # Get next address to execute.
            next_addr = to_asm_address(
                target_addr
            ) if target_addr else asm_instr.address + asm_instr.size

            # Count instruction.
            instr_count += 1
Beispiel #7
0
    def emulate(self, start_addr, end_addr, hooks, max_instrs, print_asm):
        # Switch arch mode accordingly for ARM base on the start address.
        if isinstance(self.arch_info, ArmArchitectureInformation):
            if start_addr & 0x1 == 0x1:
                start_addr = start_addr & ~0x1
                end_addr = end_addr & ~0x1

                self._arch_mode = ARCH_ARM_MODE_THUMB
            else:
                self._arch_mode = ARCH_ARM_MODE_ARM

        execution_cache = ExecutionCache()

        next_addr = start_addr
        instr_count = 0
        asm_instr = None

        while next_addr != end_addr:
            if max_instrs and instr_count > max_instrs:
                break

            # Process hooks.
            if next_addr in hooks:
                logger.debug("Hooking @ {:#x}".format(next_addr))

                fn, param, skip, offset = hooks[next_addr]

                fn(self.ir_emulator, param)

                # Compute next address after hook.
                if skip:
                    if isinstance(self.arch_info, X86ArchitectureInformation):
                        # Pop return address from the stack.
                        next_addr = self.ir_emulator.read_memory(self.ir_emulator.registers[self.sp], self.ws)
                        self.ir_emulator.registers[self.sp] += self.ws

                    if isinstance(self.arch_info, ArmArchitectureInformation):
                        # Load return address from the link register.
                        next_addr = self.ir_emulator.registers["r14"]

                logger.debug("Continuing @ {:#x}".format(next_addr))

            try:
                # Retrieve next instruction from the execution cache.
                asm_instr, reil_container = execution_cache.retrieve(next_addr)
            except InvalidAddressError:
                # Fetch the instruction.
                encoding = self.__fetch_instr(next_addr)

                # Decode it.
                asm_instr = self.disassembler.disassemble(encoding, next_addr,
                                                          architecture_mode=self._arch_mode)

                # Translate it.
                reil_container = self.__build_reil_container(asm_instr)

                # Add it to the execution cache.
                execution_cache.add(next_addr, asm_instr, reil_container)

            # Update the instruction pointer.
            self.__update_ip(asm_instr)

            # Execute instruction.
            if print_asm:
                print("{:#x} {}".format(asm_instr.address, asm_instr))

            target_addr = self.__process_reil_container(reil_container, to_reil_address(next_addr))

            # Execute post instruction handlers
            handler_fn_post, handler_param_post = self.__instr_handler_post
            handler_fn_post(self, asm_instr, handler_param_post)

            # Get next address to execute.
            next_addr = to_asm_address(target_addr) if target_addr else asm_instr.address + asm_instr.size

            # Count instruction.
            instr_count += 1