def list(self, func_name, *args): h = [ utils.green_bold('address'), utils.green_bold('length'), utils.green_bold('status') ] print(tabulate(self.patches, h, tablefmt="simple"))
def del_exec(self, func_name, *args): try: id = int(args[0]) if id not in self.executors_id_map: print('executor not found') else: v = self.executors_id_map[id] self.executors_id_map.pop(id) self.executors_map.pop(v) print(utils.green_bold(str(id)) + ": removed") except Exception as e: print(utils.green_bold('usage: ') + 'exec delete *executor_id')
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 reg(self, name: str, uc_const: int): """ Create an entry for a new reg, reading the contents from unicorn. """ uc = self.emu_instance val = uc.reg_read(uc_const) return [utils.green_bold(name), hex(val), val]
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 run_exec(self, func_name, *args): try: id = int(args[0]) if id not in self.executors_id_map: print('executor not found') else: cmd_arr = self.executors_map[self.executors_id_map[id]]['cmd_list'] self.core_instance.batch_execute(cmd_arr) except Exception as e: print(utils.green_bold('usage: ') + 'exec run *executor_id')
def resume_emulation(self, address=None, skip_bp=0): # 从这个地方开始? if address is not None: self.current_address = address # 跳过bp 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' )
def restore(self): self.current_address = self.entry_point for addr in self.entry_context['memory']: m = self.entry_context['memory'][addr] self.emu_instance.mem_write(addr, m) print('restored ' + str(len(self.entry_context['memory'])) + ' memory regions.') const = utils.get_arch_consts(self.arch) for r in self.entry_context['regs']: self.emu_instance.reg_write(getattr(const, r), self.entry_context['regs'][r]) print('restored ' + str(len(self.entry_context['regs'])) + ' registers.') print('emulator at ' + utils.green_bold(hex(self.current_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 save_exec(self, func_name, *args): try: id = int(args[0]) if id not in self.executors_id_map: print('executor not found') else: key = self.executors_id_map[id] cmd_arr = self.executors_map[key]['cmd_list'] if not os.path.exists('executors'): os.mkdir('executors') file_path = 'executors/' + key if os.path.isfile(file_path): print('a file with the same name already exist in executors. aborting.') return f = open(file_path, 'w') for item in cmd_arr: f.write("%s\n" % item) print('saved ' + utils.green_bold(str(len(cmd_arr)) + ' commands') + ' into ' + utils.green_bold(file_path)) except Exception as e: print(utils.green_bold('usage: ') + 'exec save *executor_id')
def exec(self, func_name, *args): print(utils.titlify('help')) print(utils.green_bold('usage: ') + self.command_map['executors']['usage']) r = [] for key, value in self.executors_map.items(): id = value['id'] cmd_count = str(len(value['cmd_list'])) r.append([str(id), key, cmd_count]) h = [utils.white_bold_underline('id'), utils.white_bold_underline('name'), utils.white_bold_underline('commands')] print(utils.titlify('executors')) print(tabulate(r, h, tablefmt="simple"))
def configs(self, func_name, *args): r = [] for key in self.configs_map: val = self.configs_map[key] if isinstance(val, int): val = hex(val) r.append([utils.green_bold(key), val]) h = [utils.white_bold_underline('config'), utils.white_bold_underline('value')] print('') print(tabulate(r, h, tablefmt="simple")) print('')
def read(self, func_name, *args): reg = str(args[0]).upper() value = self.read_register(reg) if value is None: raise Exception('register not found') r = [[utils.green_bold(reg), hex(value), str(value)]] h = [ utils.white_bold_underline('register'), utils.white_bold_underline('hex'), utils.white_bold_underline('decimal') ] print('') print(tabulate(r, h, tablefmt="simple")) print('')
def batch_execute(self, commands_arr): """ batch execute a list of commands :param commands_arr: array with commands :return: """ try: l = len(commands_arr) if l > 0: for com in commands_arr: self.parse_command(com) print('executed ' + utils.green_bold(str(l) + ' commands') + '.') else: raise Exception except Exception as e: print(MENU_APIX + " " + colored("FAILED", 'red', attrs=['underline', 'bold']) + " " + colored( "batch execution of " + str(len(commands_arr)) + " commands", 'white', attrs=['underline', 'bold']))
def new_exec(self, func_name, *args): key = input('executor name: ') id = len(self.executors_id_map) print('creating executor ' + utils.green_bold(str(id)) + '. add 1 command per line. type "end" to save') cmd_arr = [] while True: p = input('') if p == 'end': break else: if p: cmd_arr.append(p) if len(cmd_arr) > 0: executor = {'id': id, 'cmd_list': cmd_arr} self.executors_map[key] = executor self.executors_id_map[id] = key
def print_command_list(self, com_obj): """ print the command list of the com_obj reference passed (could be root or even a sub_command reference) :param com_obj: command object reference :return: """ try: com_array = [] for com in com_obj: # if a short reference is present print (short) # if the command is a ref, ignore it if "ref" not in com_obj[com]: com_array.append(com) # sort the list of commands and print it com_array.sort() command_table_arr = [] for com in com_array: com_t = [utils.green_bold(com)] have_shorts = "short" in com_obj[com] if have_shorts: com_t.append(com_obj[com]["short"]) else: com_t.append('') com_t.append(self.print_usage(com_obj[com], only_get=True)) command_table_arr.append(com_t) print(utils.titlify('help')) print( tabulate(command_table_arr, [ utils.white_bold_underline('command'), utils.white_bold_underline('short'), utils.white_bold_underline('usage') ], tablefmt="simple")) except Exception as e: print(utils.error_format('print_command_list', str(e)))
def print_usage(self, command, only_get=False): """ utils function to check (if exist) and print the command usage :param command: command of which to print usage description :param only_get: if True he will not print the usage but only returns it :return: """ if isinstance(command, dict): com = command else: com = self.core_instance.commands_map[command] try: if "usage" in com: if only_get is False: print(utils.green_bold("usage: ") + com["usage"]) return com["usage"] else: return None except Exception as e: return None
def disassemble(self, func_name, *args): p = bytes.fromhex(args[0]) off = 0x00 if len(args) == 1: self.internal_disassemble(p, off) else: try: arch = getattr(capstone.__all__, 'CS_ARCH_' + str(args[0]).upper()) except Exception as e: raise Exception('arch not found') mode = self.core_instance.get_cs_mode() if len(args) > 2: try: arch = getattr(capstone.__all__, 'CS_MODE_' + str(args[0]).upper()) except Exception as e: raise Exception('mode not found') cs = capstone.Cs(arch, mode) for i in cs.disasm(p, off): a = hex(i.address) print( utils.green_bold(a) + "\t%s\t%s" % (i.mnemonic, i.op_str))
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: # 内存访问hook self.hook_mem_access = True # 软断点 self.soft_bp = False # 命中软断点置位 hit_soft_bp = True # 地址不是上一个断点 and (地址在断点列表中 or 有软断点) 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()