def dbg_hook_code(self, uc, address, size, user_data): """ Unicorn instructions hook """ try: self.current_address = address hit_soft_bp = False should_print_instruction = self.trace_instructions > 0 if self.soft_bp: self.hook_mem_access = True self.soft_bp = False hit_soft_bp = True if address != self.last_bp and \ (address in self.core_module.get_breakpoints_list() or self.has_soft_bp): if self.skip_bp_count > 0: self.skip_bp_count -= 1 else: self.breakpoint_count += 1 should_print_instruction = False uc.emu_stop() self.last_bp = address print(utils.titlify('breakpoint')) print('[' + utils.white_bold(str(self.breakpoint_count)) + ']' + ' hit ' + utils.red_bold('breakpoint') + ' at: ' + utils.green_bold(hex(address))) self._print_context(uc, address) elif address == self.last_bp: self.last_bp = 0 self.has_soft_bp = hit_soft_bp if self.current_address + size == self.exit_point: should_print_instruction = False self._print_context(uc, address) print( utils.white_bold("emulation") + " finished with " + utils.green_bold("success")) if should_print_instruction: self.asm_module.internal_disassemble( uc.mem_read(address, size), address) except KeyboardInterrupt as ex: # If stuck in an endless loop, we can exit here :). TODO: does that mean ctrl+c never works for targets? print(utils.titlify('paused')) self._print_context(uc, address) uc.emu_stop()
def start(self): """ main start function, here we handle the command get loop and unicorn istance creation :return: """ if not self.emu_instance: self.initialize() utils.clear_terminal() print(utils.get_banner()) print('\n\n\t' + utils.white_bold('Contribute ') + 'https://github.com/iGio90/uDdbg\n') print('\t' + 'Type ' + utils.white_bold_underline('help') + ' to begin.\n') main_apix = colored(MENU_APPENDIX + " ", 'red', attrs=['bold', 'dark']) print() while True: print(main_apix, end='', flush=True) text = prompt('', history=self.history, auto_suggest=AutoSuggestFromHistory()) # only grant the use of empty command to replicate the last command while in cli. No executors if len(text) == 0 and self.last_command is not None: self.functions_instance.parse_command(self.last_command) continue self.last_command = text # send command to the parser self.functions_instance.parse_command(text)
def resume_emulation(self, address=0x0, skip_bp=0): if address > 0x0: self.current_address = address self.skip_bp_count = skip_bp if self.exit_point > 0x0: print(utils.white_bold("emulation") + " started at " + utils.green_bold(hex(self.current_address))) if len(self.entry_context) == 0: # store the initial memory context for the restart self.entry_context = { 'memory': {}, 'regs': {} } map_list = self.get_module('mappings_module').get_mappings() for map in map_list: map_address = int(map[1], 16) map_len = map[2] self.entry_context['memory'][map_address] = bytes(self.emu_instance.mem_read(map_address, map_len)) # registers const = utils.get_arch_consts(self.arch) regs = [k for k, v in const.__dict__.items() if not k.startswith("__") and k.index("_REG_") > 0] for r in regs: self.entry_context['regs'][r] = \ self.emu_instance.reg_read(getattr(const, r)) start_addr = self.current_address if self.is_thumb: start_addr = start_addr | 1 self.emu_instance.emu_start(start_addr, self.exit_point) else: print('please use \'set exit_point *offset\' to define an exit point')
def internal_disassemble(self, buf, off, current_off=0): cs = self.core_instance.get_cs_instance() for i in cs.disasm(bytes(buf), off): if i.address == current_off: a = utils.red_bold(hex(i.address)) else: a = utils.green_bold(hex(i.address)) print(a + "\t%s\t%s" % ((utils.white_bold(str(i.mnemonic).upper()), str(i.op_str).upper().replace('X', 'x'))))
def dbg_hook_code(self, uc, address, size, user_data): """ Unicorn instructions hook """ self.current_address = address hit_soft_bp = False should_print_instruction = self.trace_instructions > 0 if self.soft_bp: self.hook_mem_access = True self.soft_bp = False hit_soft_bp = True if address != self.last_bp and \ (address in self.core_module.get_breakpoints_list() or self.has_soft_bp): if self.skip_bp_count > 0: self.skip_bp_count -= 1 else: self.breakpoint_count += 1 should_print_instruction = False uc.emu_stop() self.last_bp = address print(utils.titlify('breakpoint')) print('[' + utils.white_bold(str(self.breakpoint_count)) + ']' + ' hit ' + utils.red_bold('breakpoint') + ' at: ' + utils.green_bold(hex(address))) self._print_context(uc) elif address == self.last_bp: self.last_bp = 0 self.has_soft_bp = hit_soft_bp if self.current_address + size == self.exit_point: should_print_instruction = False self._print_context(uc) print( utils.white_bold("emulation") + " finished with " + utils.green_bold("success")) if should_print_instruction: self.asm_module.internal_disassemble(uc.mem_read(address, size), address)
def _print_context(self, uc, pc): self.register_module.registers('mem_invalid') print(utils.titlify('disasm')) self.asm_module.internal_disassemble(uc.mem_read(pc - 0x16, 0x32), pc - 0x16, pc) if self.mem_access_result is not None: val = utils.red_bold("\t0x%x" % self.mem_access_result[1]) ad = utils.green_bold("\t> 0x%x" % self.mem_access_result[0]) print(utils.titlify("memory access")) print(utils.white_bold("WRITE") + val + ad) self.hook_mem_access = None self.mem_access_result = None
def start(self, arch=None, mode=None): """ main start function, here we handle the command get loop and unicorn istance creation :param arch: unicorn arch int costant :param mode: unicorn mode int costant :return: """ # if no arch or mode are sets in param, prompt for them if not arch: arch = utils.prompt_arch() if not mode: mode = utils.prompt_mode() self.arch = getattr(unicorn_const, arch) self.mode = getattr(unicorn_const, mode) self.emu_instance = Uc(self.arch, self.mode) if self.mode == UC_MODE_THUMB: self.is_thumb = True # add hooks self.emu_instance.hook_add(UC_HOOK_CODE, self.dbg_hook_code) self.emu_instance.hook_add(UC_HOOK_MEM_WRITE, self.dbg_hook_mem_access) self.emu_instance.hook_add(UC_HOOK_MEM_INVALID, self.dbg_hook_mem_invalid) utils.clear_terminal() print(utils.get_banner()) print('\n\n\t' + utils.white_bold('Contribute ') + 'https://github.com/iGio90/uDdbg\n') print('\t' + 'Type ' + utils.white_bold_underline('help') + ' to begin.\n') main_apix = colored(MENU_APPENDIX + " ", 'red', attrs=['bold', 'dark']) print() while True: print(main_apix, end='', flush=True) text = prompt('', history=self.history, auto_suggest=AutoSuggestFromHistory()) # only grant the use of empty command to replicate the last command while in cli. No executors if len(text) == 0 and self.last_command is not None: self.functions_instance.parse_command(self.last_command) continue self.last_command = text # send command to the parser self.functions_instance.parse_command(text)
def resume_emulation(self, address=None, skip_bp=0): if address is not None: self.current_address = address self.skip_bp_count = skip_bp if self.exit_point is not None: print( utils.white_bold("emulation") + " started at " + utils.green_bold(hex(self.current_address))) if len(self.entry_context) == 0: # store the initial memory context for the restart self.entry_context = {'memory': {}, 'regs': {}} map_list = self.get_module('mappings_module').get_mappings() for map in map_list: map_address = int(map[1], 16) map_len = map[2] self.entry_context['memory'][map_address] = bytes( self.emu_instance.mem_read(map_address, map_len)) # registers const = utils.get_arch_consts(self.arch) regs = [ k for k, v in const.__dict__.items() if not k.startswith("__") and "_REG_" in k and not "INVALID" in k ] for r in regs: try: self.entry_context['regs'][ r] = self.emu_instance.reg_read(getattr(const, r)) except Exception as ex: pass # print("Ignoring reg: {} ({})".format(r, ex)) -> Ignored UC_X86_REG_MSR start_addr = self.current_address if self.is_thumb: start_addr = start_addr | 1 self.emu_instance.emu_start(start_addr, self.exit_point) else: print( 'please use \'set exit_point *offset\' to define an exit point' )