def get_register(name): if name.startswith('$'): name = name[1:] uc_reg = unigdb.arch.CURRENT_ARCH.all_registers.get('$' + name) if not uc_reg: message.error('Register "%s" not found' % name) return None return unigdb.arch.UC.reg_read(uc_reg)
def set_register(name, value: int): if name.startswith('$'): name = name[1:] uc_reg = unigdb.arch.CURRENT_ARCH.all_registers.get('$' + name) if not uc_reg: message.error('Register "%s" not found' % name) else: unigdb.arch.UC.reg_write(uc_reg, value)
def write_short(addr, data): if isinstance(data, int): value = data elif number_matcher(data): value = eval(data) else: message.error('{!} Error => Invalid number: %s' % data) return None write(addr, pack('H', value))
def do_load(self, args: argparse.Namespace): args.offset = parse_and_eval(args.offset) if not os.path.exists(args.file): message.error('File not found: %s' % args.file) if args.mode == 'binary': data = open(args.file, 'rb').read() else: data = binascii.unhexlify(open(args.file).read()) unigdb.memory.write(args.offset, data) if args.code == 'code': self.cls.do_set('$pc %#08x' % args.offset)
def do_run(self, arg): reg_pc = unigdb.regs.get_register('$pc') unigdb.arch.UC.hook_add(UC_HOOK_CODE, self.cls.hook_code) unigdb.arch.UC.hook_add(UC_HOOK_BLOCK, self.cls.hook_block) unigdb.arch.UC.hook_add(UC_HOOK_INTR, self.cls.hook_intr) # emulate machine code in infinite time try: setBreakpoint(reg_pc, temporary=True) unigdb.proc.alive = True unigdb.arch.UC.emu_start(begin=reg_pc, until=reg_pc + 0x10000) except UcError as e: message.error('{!} Error => %s' % e)
def write(addr, data): """write(addr, data) Writes data into the memory of the process being debugged. Arguments: addr(int): Address to write data(str,bytes,bytearray): Data to write """ if isinstance(data, str): data = data.encode() try: unigdb.arch.UC.mem_write(addr, data) except AttributeError: message.error('{!} Error => Unicorn engine not initialized')
def context_stack(self): self.context_title("stack") show_raw = self.get_setting("show_stack_raw") nb_lines = self.get_setting("nb_lines_stack") try: sp = int(unigdb.arch.CURRENT_ARCH.sp) if show_raw is True: mem = unigdb.memory.read(sp, 0x10 * nb_lines) for _, line in enumerate(unigdb.hexdump.hexdump(mem, address=sp)): print(line) else: for offset in range(nb_lines): print(unigdb.chain.format(sp + (offset * unigdb.arch.ptrsize))) # gdb.execute("dereference {:#x} l{:d}".format(sp, nb_lines)) except Exception: message.error("Cannot read memory from $SP (corrupted stack pointer?)") return None
def set_setting(self, argc, argv): if "." not in argv[0]: message.error("Invalid command format") return None loaded_commands = [ x[0] for x in unigdb.config.__unigdb__.loaded_commands ] + ["self"] plugin_name = argv[0].split(".", 1)[0] if plugin_name not in loaded_commands: message.error("Unknown plugin '{:s}'".format(plugin_name)) return None _value, _doc = unigdb.config.get(argv[0], get_all=True) if _value is None: message.error("Failed to get '{:s}' config setting".format( argv[0], )) return None _type = type(_value) if isinstance(_value, bool): _newval = True if argv[1] == 'True' else False else: _newval = _type(argv[1]) unigdb.config.set(argv[0], _newval, _doc) unigdb.events.reset_all_caches() return None
def do_theme(self, args: argparse.Namespace): if not args.key: for setting in sorted(self.settings): value = self.get_setting(setting) value = Color.colorify(value, value) print("{:40s}: {:s}".format(setting, value)) return None setting = args.key if not self.has_setting(setting): message.error("Invalid key") return None if not args.value: value = self.get_setting(setting) value = Color.colorify(value, value) print("{:40s}: {:s}".format(setting, value)) return None val = [x for x in args.value.split() if x in Color.colors] self.add_setting(setting, " ".join(val)) return None
def do_context(self, args: argparse.Namespace): if not self.get_setting("enable") or context_hidden: return None if len(args.subcommand) > 0: current_layout = args.subcommand else: current_layout = self.get_setting("layout").strip().split() if not current_layout: return None self.tty_rows, self.tty_columns = unigdb.ui.get_window_size() redirect = self.get_setting("redirect") if redirect and os.access(redirect, os.W_OK): unigdb.ui.enable_redirect_output(to_file=redirect) if self.get_setting("clear_screen") and len(args.subcommand) == 0: clear_screen(redirect) for section in current_layout: if section[0] == "-": continue try: self.layout_mapping[section]() except Exception as e: # a MemoryError will happen when $pc is corrupted (invalid address) message.error(str(e)) self.context_title("") if redirect and os.access(redirect, os.W_OK): unigdb.ui.disable_redirect_output() return None
def __load_extra_plugins(self): nb_added = -1 try: nb_inital = len(self.loaded_commands) directories = unigdb.config.get("self.extra_plugins_dir") if directories: for directory in directories.split(";"): directory = os.path.realpath(os.path.expanduser(directory)) if os.path.isdir(directory): sys.path.append(directory) for fname in os.listdir(directory): if not fname.endswith(".py"): continue fpath = "{:s}/{:s}".format(directory, fname) if os.path.isfile(fpath): gdb.execute("source {:s}".format(fpath)) nb_added = len(self.loaded_commands) - nb_inital if nb_added > 0: message.success("{:s} extra commands added from '{:s}'".format( Color.colorify(nb_added, "bold green"), Color.colorify(directory, "bold blue"))) except gdb.error as e: message.error("failed: {}".format(str(e))) return nb_added
def invoke(self, args, from_tty): self.dont_repeat() argv = gdb.string_to_argv(args) argc = len(argv) if not (0 <= argc <= 2): message.error("Invalid number of arguments") return None if argc == 0: print(message.titlify("UNIGDB configuration settings")) self.print_settings() return None if argc == 1: prefix = argv[0] names = list( filter(lambda x: x.startswith(prefix), unigdb.config.__config__.keys())) if names: if len(names) == 1: print( message.titlify( "UNIGDB configuration setting: {:s}".format( names[0]))) self.print_setting(names[0], verbose=True) else: print( message.titlify( "UNIGDB configuration settings matching '{:s}'". format(argv[0]))) for name in names: self.print_setting(name) return None self.set_setting(argc, argv) return None
def wrapper(*a, **kw): if module.init: return func(*a, **kw) else: message.error('{!} Error => Unicorn engine not initialized')