Example #1
0
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)
Example #2
0
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)
Example #3
0
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))
Example #4
0
 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)
Example #5
0
 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)
Example #6
0
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')
Example #7
0
    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
Example #8
0
    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
Example #9
0
    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
Example #10
0
    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
Example #11
0
 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
Example #12
0
    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
Example #13
0
 def wrapper(*a, **kw):
     if module.init:
         return func(*a, **kw)
     else:
         message.error('{!} Error => Unicorn engine not initialized')