def fetch(self, address): base_addr, index = split_address(address) if base_addr != to_asm_address(self.address): raise ReilSequenceInvalidAddressError() return self.get(index)
def get_next_address(self, address): base_addr, index = split_address(address) if base_addr != to_asm_address(self.address): raise ReilSequenceInvalidAddressError() addr = address if index < len(self.__sequence) - 1: addr += 1 else: raise ReilSequenceInvalidAddressError() return addr
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
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