Beispiel #1
0
 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
Beispiel #2
0
 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"))
Beispiel #3
0
    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()
Beispiel #4
0
 def list(self, func_name, *args):
     print(utils.titlify('mappings'))
     h = [
         utils.white_bold_underline('path'),
         utils.white_bold_underline('address'),
         utils.white_bold_underline('length')
     ]
     print('')
     print(tabulate(self.mappings, h, tablefmt="simple"))
     print('')
Beispiel #5
0
 def dbg_hook_mem_invalid(self, uc: Uc, access, address, size, value, userdata):
     """
     Unicorn mem invalid hook
     """
     if size < 2:
         size = self.last_mem_invalid_size
     self.last_mem_invalid_size = size
     self.register_module.registers('mem_invalid')
     print(utils.titlify('disasm'))
     start = max(0, self.pc - 0x16)
     self.asm_module.internal_disassemble(uc.mem_read(start, 0x32), start, address)
Beispiel #6
0
 def registers(self, func_name, *args):
     print(utils.titlify('registers'))
     arch = self.core_instance.unicorndbg_instance.arch
     mode = self.core_instance.unicorndbg_instance.mode
     regtable = getRegStringTable(getArchString(arch, mode))
     r = []
     for regcode in regtable:
         r.append(self.reg(regtable[regcode], regcode))
     h = [
         utils.white_bold_underline('register'),
         utils.white_bold_underline('hex'),
         utils.white_bold_underline('decimal')
     ]
     print(tabulate(r, h, tablefmt="simple"))
Beispiel #7
0
    def find(self, func_name, *args):
        where = utils.u_eval(self.core_instance, args[0])

        what = bytes.fromhex(args[1])
        match = re.compile(what)

        result = []
        map_start = 0
        start = 0
        size = 0
        mappings = self.core_instance.get_module(
            'mappings_module').get_mappings()

        if isinstance(where, str):
            for map in mappings:
                if map[0] == where:
                    start = int(map[1], 16)
                    map_start = start
                    size = map[2]
        else:
            for map in mappings:
                if int(map[1], 16) <= where < (int(map[1], 16) + map[2]):
                    map_start = int(map[1], 16)
                    start = where
                    size = map[2]

        b = self.core_instance.get_emu_instance().mem_read(
            start, size - (map_start - start))
        for match_obj in match.finditer(b):
            offset = match_obj.start() + map_start
            result.append([hex(offset)])

        print(utils.titlify('find'))
        if len(result) == 0:
            print('Nothing found.')
        else:
            h = [utils.white_bold_underline('offset')]
            print('')
            print(tabulate(result, h, tablefmt="simple"))
            print('')
Beispiel #8
0
    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)))
Beispiel #9
0
    def exec_command(self, command, args):
        """
        the core method of commands exec, it tries to fetch the requested command,
        bind to the right context and call the associated function

        TODO:
        :param command: requested command
        :param args: arguments array
        :return:
        """

        # save the found command and sub_command array
        complete_command_array = [command]
        try:
            if command == '':
                return

            if command in self.commands_map:

                # if we found the command but has the "ref" property,
                # so we need to reference to another object. Ex. short command q --references--> quit
                if 'ref' in self.commands_map[command]:
                    com = self.commands_map[self.commands_map[command]['ref']]
                else:
                    com = self.commands_map[command]

                # if we have no arguments no sub_command exist, else save the first argument
                last_function = False
                if len(args) > 0:
                    possible_sub_command = args[0]
                else:
                    possible_sub_command = None

                # now iterate while we have a valid sub_command,
                # when we don't find a valid sub_command exit and the new command will be the sub_command
                # save the sub_command parent
                prev_command = com
                while last_function is False:
                    # if the sub command is a ref, catch the right command
                    if 'ref' in com:
                        com = prev_command['sub_commands'][com['ref']]
                    if 'sub_commands' in com and possible_sub_command:
                        if possible_sub_command in com['sub_commands']:
                            prev_command = com
                            com = com['sub_commands'][possible_sub_command]
                            # pop the found sub_command so we can iterate on the remanings arguments
                            complete_command_array.append(args.pop(0))
                            command = possible_sub_command
                            # if there are arguments left
                            if len(args) > 0:
                                # take the first args (the next sub_command)
                                possible_sub_command = args[0]
                            else:
                                last_function = True
                        else:
                            last_function = True
                    else:
                        last_function = True

                # if the sub_command is a reference to another associated sub_command
                if 'ref' in com:
                    com = prev_command['sub_commands'][com['ref']]

                # if we have a function field just fetch the context and the function name,
                # bind them and call the function passing the arguments
                if 'function' in com:
                    if 'args' in com['function']:
                        args_check, args_error = utils.check_args(com['function']['args'], args)
                        if args_check is False:
                            raise Exception(args_error)

                    context = self.context_map[com["function"]["context"]]
                    funct = com["function"]["f"]
                    call_method = getattr(context, funct)
                    # we pass the command name (could be useful for the called function)
                    # and possible arguments to the function
                    call_method(command, *args)
                else:
                    # if we have no method implementation of the command
                    # print the help of the command
                    # passing all the arguments list to help function (including the command) in a unique array
                    self.exec_command('help', complete_command_array)

            else:
                print("command '" + command + "' not found")
        except Exception as e:
            if isinstance(e, UcError):
                print(utils.titlify('uc error'))
                print(str(e))
            else:
                print(utils.error_format('exec_command', str(e)))
                self.exec_command('help', complete_command_array)
Beispiel #10
0
    def help(self, func_name, *args):
        """
        print the help and command usage of the requested command (and sub_command too)

        help command_to_get_help [sub_command_to_get_help1 sub_command_to_get_help2]

        :param func_name:
        :param args:
        :return:
        """

        # we need at least 1 command to get the help
        if args:
            try:
                # h will keep the command dictionary iteration
                # c will keep the deep of the sub_command iteration
                h = None
                c = 0
                prev_h = None

                # iterate for every command and sub_command in args
                for arg in args:
                    c += 1
                    # keep a reference (useful for errors) of command\sub_command name
                    command = arg

                    # if we already fetched the first main command
                    if h:
                        # if we have a sub_command save the reference so we can iterate into it
                        if "sub_commands" in h:
                            if len(h["sub_commands"]) is not 0:
                                # save the parent command
                                prev_h = h
                                h = h["sub_commands"][arg]
                            else:
                                raise Exception
                        else:
                            raise Exception
                    # if is the first fetch of the main command just search it on the commands_map dict
                    # and save the reference. We will start the command root from here
                    else:
                        # if the requested command is a "ref" to another command, just keep the right reference
                        if "ref" in self.core_instance.commands_map[arg]:
                            h = self.core_instance.commands_map[
                                self.core_instance.commands_map[arg]["ref"]]
                        else:
                            h = self.core_instance.commands_map[arg]
                        # keep a reference to parent command
                        prev_h = h

                if c > 0:
                    # if the sub_command is a reference to another associated sub_command
                    if "ref" in h:
                        h = prev_h['sub_commands'][h['ref']]

                    # print help and usage passing h, the command object reference
                    print(utils.titlify(command))
                    print(h["help"])
                    self.print_usage(h)
                    # if there are sub_commands print a list of them
                    if "sub_commands" in h:
                        self.print_command_list(h["sub_commands"])

            except Exception as e:
                print(utils.error_format(func_name, str(e)))
                print("no help for command '" + command + "'" + ' found')

        # if we have no args (so no commands) just print the commands list
        else:
            self.print_command_list(self.core_instance.commands_map)
Beispiel #11
0
    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()
Beispiel #12
0
    def exec_command(self, command, args):
        # 执行命令
        """
        the core method of commands exec, it tries to fetch the requested command,
            执行命令核心方法,提取请求的命令
        bind to the right context and call the associated function
            绑定到正确的上下文中,调用相应的函数

        TODO:
        :param command: requested command
        :param args: arguments array
        :return:
        """

        # save the found command and sub_command array
        # complete_command_array 保存找到的命令和子命令的数组
        complete_command_array = [command]
        try:
            # 如果是空命令直接返回
            if command == '':
                return

            # 如果命令位于 commands_map
            if command in self.commands_map:

                # if we found the command but has the "ref" property,
                # 如果找到了命令但是有 ref(指向)属性
                # so we need to reference to another object. Ex. short command q --references--> quit
                # 需要引用另一个实例,比如命令简称
                if 'ref' in self.commands_map[command]:
                    # 新com指向ref指向的命令
                    com = self.commands_map[self.commands_map[command]['ref']]
                else:
                    # 否则命令就是它自己内部保存的命令
                    com = self.commands_map[command]

                # if we have no arguments no sub_command exist, else save the first argument

                last_function = False
                if len(args) > 0:
                    # 没有子命令,子命令就是 第一个选项 args[0],可能的子命令?
                    possible_sub_command = args[0]
                else:
                    possible_sub_command = None

                # now iterate while we have a valid sub_command,
                # 当有子命令的时候遍历
                # when we don't find a valid sub_command exit and the new command will be the sub_command
                # 当没有找到有效的子命令,退出,新的命令是sub_command
                # save the sub_command parent
                # 保存子命令的母命令
                prev_command = com

                while last_function is False:
                    # if the sub command is a ref, catch the right command
                    # 如果子命令中有引用,com保存它正确命令
                    if 'ref' in com:
                        com = prev_command['sub_commands'][com['ref']]
                    if 'sub_commands' in com and possible_sub_command:
                        # 如果possible_sub_command存在,com中有sub_commands项
                        if possible_sub_command in com['sub_commands']:

                            prev_command = com
                            # com用它里边的子命令possible_sub_command答题
                            com = com['sub_commands'][possible_sub_command]
                            # pop the found sub_command so we can iterate on the remanings arguments
                            # 完成命令数组加入 args.pop(0)
                            complete_command_array.append(args.pop(0))
                            # 命令是possible_sub_command
                            command = possible_sub_command
                            # if there are arguments left
                            if len(args) > 0:
                                # take the first args (the next sub_command)
                                possible_sub_command = args[0]
                            else:
                                last_function = True
                        else:
                            last_function = True
                    else:
                        last_function = True

                # if the sub_command is a reference to another associated sub_command
                # 如果 sub_command是另一个相关子命令的引用
                if 'ref' in com:
                    com = prev_command['sub_commands'][com['ref']]

                # if we have a function field just fetch the context and the function name,
                # 如果有函数域,提取它和函数名字
                # bind them and call the function passing the arguments
                # 绑定他们,调用函数,传递参数

                if 'function' in com:
                    if 'args' in com['function']:
                        # 检查参数
                        args_check, args_error = utils.check_args(
                            com['function']['args'], args)
                        if args_check is False:
                            # 检查失败
                            raise Exception(args_error)

                    # 函数上下文,根据context_map
                    context = self.context_map[com["function"]["context"]]
                    # 函数
                    funct = com["function"]["f"]
                    # 调用方法,直接getattr
                    call_method = getattr(context, funct)
                    # we pass the command name (could be useful for the called function)
                    # and possible arguments to the function
                    # 直接调用这个函数
                    call_method(command, *args)
                else:
                    # if we have no method implementation of the command
                    # print the help of the command
                    # passing all the arguments list to help function (including the command) in a unique array
                    # 如果没有实现这个函数,打印帮助信息
                    self.exec_command('help', complete_command_array)

            else:
                # 没有找到这个命令
                print("command '" + command + "' not found")
        except Exception as e:
            if isinstance(e, UcError):
                print(utils.titlify('uc error'))
                print(str(e))
            else:
                print(utils.error_format('exec_command', str(e)))
                self.exec_command('help', complete_command_array)