Exemplo n.º 1
0
    def __get_syscall_mapper(self, archtype: QL_ARCH):
        qlos_path = f'.os.{self.type.name.lower()}.map_syscall'
        qlos_func = 'get_syscall_mapper'

        func = ql_get_module_function(qlos_path, qlos_func)

        return func(archtype)
Exemplo n.º 2
0
 def ql_debugger(ql, remotedebugsrv, ip=None, port=None):
     path = ql.path
     try:
         if ip is None:
             ip = '127.0.0.1'
         if port is None:
             port = 9999
         port = int(port) 
         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         sock.bind((ip, port))
         ql.nprint("\ndebugger> Initializing loadbase 0x%x\n" % (ql.loader.loadbase))
         ql.nprint("debugger> Listening on %s:%u\n" % (ip, port))
         sock.listen(1)
         conn, addr = sock.accept()
     except:
         ql.nprint("debugger> Error: Address already in use\n")
         raise
     try:
         mappings = [(hex(ql.loader.entry_point), 0x10)]
         exit_point = ql.loader.entry_point + os.path.getsize(path)
         remotedebugsrv = debugger_convert_str(remotedebugsrv)
         remotedebugsrv = str(remotedebugsrv) + "server" 
         DEBUGSESSION = str.upper(remotedebugsrv) + "session"
         DEBUGSESSION = ql_get_module_function("qiling.debugger." + remotedebugsrv + "." + remotedebugsrv, DEBUGSESSION)
         ql.remotedebugsession = DEBUGSESSION(ql, conn, exit_point, mappings)
     except:
         ql.nprint("debugger> Error: Not able to initialize Debugging Server\n")
         raise
Exemplo n.º 3
0
    def ql_debugger(ql, remotedebugsrv, ip=None, port=None):
        path = ql.path
        if ip is None:
            ip = '127.0.0.1'
        if port is None:
            port = 9999

        port = int(port)
        
        if ql.shellcoder:
            load_address = ql.os.entry_point
            exit_point = load_address + len(ql.shellcoder)
        else:
            load_address = ql.loader.load_address
            exit_point = load_address + os.path.getsize(path)
            
        mappings = [(hex(load_address))]
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind((ip, port))
        ql.nprint("debugger> Initializing load_address 0x%x" % (load_address))
        ql.nprint("debugger> Listening on %s:%u" % (ip, port))
        sock.listen(1)
        conn, addr = sock.accept()
        remotedebugsrv = debugger_convert_str(remotedebugsrv)
        remotedebugsrv = str(remotedebugsrv) + "server" 
        DEBUGSESSION = str.upper(remotedebugsrv) + "session"
        DEBUGSESSION = ql_get_module_function("qiling.debugger." + remotedebugsrv + "." + remotedebugsrv, DEBUGSESSION)
        ql.remote_debug = DEBUGSESSION(ql, conn, exit_point, mappings)
Exemplo n.º 4
0
Arquivo: hw.py Projeto: xwings/qiling
    def create(self,
               label: str,
               struct: "QlPeripheral" = None,
               base: int = None) -> "QlPeripheral":
        """ Create the peripheral accroding the label and envs.

            struct: Structure of the peripheral. Use defualt ql structure if not provide.
            base: Base address. Use defualt address if not provide.
        """
        env_struct, env_base, kwargs = self.load_env(label.upper())

        struct = env_struct if struct is None else struct
        base = env_base if base is None else base

        try:

            entity = ql_get_module_function('qiling.hw',
                                            struct)(self.ql, label, **kwargs)
            setattr(self, label, entity)
            self.entity[label] = entity
            self.region[label] = [(lbound + base, rbound + base)
                                  for (lbound, rbound) in entity.region]

            return entity
        except QlErrorModuleFunctionNotFound:
            self.ql.log.warning(
                f'The {struct}({label}) has not been implemented')
Exemplo n.º 5
0
def _msg_sendv(ql: Qiling, coid, smsg, sparts, rmsg, rparts, *args, **kw):
    assert coid in ql.os.connections, "Connection Id must exist in connections mapping"
    conn = ql.os.connections[coid]
    if conn.pid == SYSMGR_PID and conn.chid == SYSMGR_CHID:
        sbody = get_message_body(ql, smsg, sparts)
        type_ = ql.unpack16(sbody[:2])

        msg_name = map_msgtype(ql, type_)
        _msg_handler = ql_get_module_function(f"qiling.os.qnx", "message")

        if msg_name in dir(_msg_handler):
            msg_hook = eval(msg_name)
            msg_name = msg_hook.__name__
        else:
            msg_hook = None
            msg_name = None

        if msg_hook:
            ret = msg_hook(ql, coid, smsg, sparts, rmsg, rparts, *args, **kw)
        else:
            ql.log.warning(
                f'_msg_sendv: no hook for message type {type_:#04x}')
            ret = -1
    else:
        ql.log.warn(
            f'syscall_msg_sendv(coid = {coid}): unhandled message for pid = {conn.pid}, chid = {conn.chid}'
        )
        ret = -1

    return ret
Exemplo n.º 6
0
def _msg_sendv(ql, coid, smsg, sparts, rmsg, rparts, *args, **kw):
    sbody = get_message_body(ql, smsg, sparts)
    type_ = ql.unpack16(sbody[:2])

    msg_name = map_msgtype(ql, type_)
    _msg_handler = ql_get_module_function(f"qiling.os.qnx", "message")

    if msg_name in dir(_msg_handler):
        msg_hook = eval(msg_name)
        msg_name = msg_hook.__name__
    else:
        msg_hook = None
        msg_name = None

    if msg_hook:
        ret = msg_hook(ql, coid, smsg, sparts, rmsg, rparts, *args, **kw)
    else:
        ql.log.warning(f'_msg_sendv: no hook for message type {type_:#04x}')
        ret = -1

    return ret
Exemplo n.º 7
0
    def load_syscall(self):
        # import syscall mapping function
        map_syscall = ql_syscall_mapping_function(self.ql.ostype)
        syscall = self.syscall
        syscall_name = map_syscall(self.ql, syscall)

        # get syscall on-enter hook (if any)
        hooks_dict = self.posix_syscall_hooks[QL_INTERCEPT.ENTER]
        onenter_hook = hooks_dict.get(syscall_name) or hooks_dict.get(syscall)

        # get syscall on-exit hook (if any)
        hooks_dict = self.posix_syscall_hooks[QL_INTERCEPT.EXIT]
        onexit_hook = hooks_dict.get(syscall_name) or hooks_dict.get(syscall)

        # get syscall replacement hook (if any)
        hooks_dict = self.posix_syscall_hooks[QL_INTERCEPT.CALL]
        syscall_hook = hooks_dict.get(syscall_name) or hooks_dict.get(syscall)

        if syscall_hook:
            syscall_name = syscall_hook.__name__
        else:
            _ostype_str = ostype_convert_str(self.ql.ostype)
            _posix_syscall = ql_get_module_function(f"qiling.os.posix",
                                                    "syscall")
            _os_syscall = ql_get_module_function(
                f"qiling.os.{_ostype_str.lower()}", "syscall")

            if syscall_name in dir(_posix_syscall) or syscall_name in dir(
                    _os_syscall):
                syscall_hook = eval(syscall_name)
                syscall_name = syscall_hook.__name__
            else:
                syscall_hook = None

        if syscall_hook:
            args = self.get_syscall_args()

            self.utils.syscalls.setdefault(syscall_name, []).append({
                "params": {
                    "param0": args[0],
                    "param1": args[1],
                    "param2": args[2],
                    "param3": args[3],
                    "param4": args[4],
                    "param5": args[5]
                },
                "result":
                None,
                "address":
                self.ql.reg.arch_pc,
                "return_address":
                None,
                "position":
                self.utils.syscalls_counter
            })

            self.utils.syscalls_counter += 1

            try:

                if onenter_hook is not None:
                    onenter_hook(self.ql, *self.get_syscall_args())

                syscall_basename = syscall_hook.__name__[len(SYSCALL_PREF):]
                args = []

                # ignore first arg, which is 'ql'
                arg_names = tuple(
                    signature(syscall_hook).parameters.values())[1:]
                arg_values = self.get_syscall_args()

                for name, value in zip(arg_names, arg_values):
                    name = str(name)

                    # ignore python special args
                    if name in ('*args', '**kw', '**kwargs'):
                        continue

                    # cut the first part of the arg if it is of form fstatat64_fd
                    if name.startswith(f'{syscall_basename}_'):
                        name = name.partition('_')[-1]

                    args.append(f'{name} = {value:#x}')

                faddr = f'{self.ql.reg.arch_pc:#0{self.ql.archbit // 4 + 2}x}: ' if self.ql.verbose >= QL_VERBOSE.DEBUG else ''
                fargs = ', '.join(args)

                log = f'{faddr}{syscall_basename}({fargs})'

                if self.ql.verbose >= QL_VERBOSE.DEBUG:
                    self.ql.log.debug(log)
                else:
                    self.ql.log.info(log)

                ret = syscall_hook(self.ql, *arg_values)

                if ret is not None and type(ret) is int:
                    # each name has a list of calls, we want the last one and we want to update the return value
                    self.utils.syscalls[syscall_name][-1]["result"] = ret
                    ret = self.set_syscall_return(ret)
                    self.ql.log.debug(
                        f'{syscall_basename}() = {QlOsPosix.getNameFromErrorCode(ret)}'
                    )

                if onexit_hook is not None:
                    onexit_hook(self.ql, *self.get_syscall_args())

            except KeyboardInterrupt:
                raise
            except Exception as e:
                self.ql.log.exception("")
                self.ql.log.info(f'Syscall ERROR: {syscall_name} DEBUG: {e}')
                raise e
        else:
            self.ql.log.warning(
                f'{self.ql.reg.arch_pc:#x}: syscall {syscall_name} number = {syscall:#x}({syscall:d}) not implemented'
            )

            if self.ql.debug_stop:
                raise QlErrorSyscallNotFound("Syscall Not Found")
Exemplo n.º 8
0
    def load_syscall(self):
        # import syscall mapping function
        map_syscall = ql_syscall_mapping_function(self.ql.ostype)
        syscall_id = self.syscall
        syscall_name = map_syscall(self.ql, syscall_id)

        # get syscall on-enter hook (if any)
        hooks_dict = self.posix_syscall_hooks[QL_INTERCEPT.ENTER]
        onenter_hook = hooks_dict.get(syscall_name) or hooks_dict.get(syscall_id)

        # get syscall on-exit hook (if any)
        hooks_dict = self.posix_syscall_hooks[QL_INTERCEPT.EXIT]
        onexit_hook = hooks_dict.get(syscall_name) or hooks_dict.get(syscall_id)

        # get syscall replacement hook (if any)
        hooks_dict = self.posix_syscall_hooks[QL_INTERCEPT.CALL]
        syscall_hook = hooks_dict.get(syscall_name) or hooks_dict.get(syscall_id)

        if not syscall_hook:
            osname = ostype_convert_str(self.ql.ostype)
            os_syscalls = ql_get_module_function(f"qiling.os.{osname.lower()}", "syscall")
            posix_syscalls = ql_get_module_function(f"qiling.os.posix", "syscall")

            # look in os-specific and posix syscall hooks
            if syscall_name:
                self.ql.log.debug("syscall hooked 0x%x: %s()" % (self.ql.reg.arch_pc, syscall_name))
                syscall_hook = getattr(os_syscalls, syscall_name, None) or getattr(posix_syscalls, syscall_name, None)

        if syscall_hook:
            syscall_name = syscall_hook.__name__

            # extract the parameters list from hook signature
            param_names = tuple(signature(syscall_hook).parameters.values())

            # skip first arg (always 'ql') and filter out python special args (*args and **kwargs)
            param_names = [info.name for info in param_names[1:] if info.kind == Parameter.POSITIONAL_OR_KEYWORD]

            # read parameter values
            params = [self.__syscall_cc.getRawParam(i) for i in range(len(param_names))]

            try:
        		# if set, fire up the on-enter hook and let it override original args set
                if onenter_hook:
                    overrides = onenter_hook(self.ql, *params)

                    if overrides is not None:
                        _, params = overrides

        		# perform syscall
                retval = syscall_hook(self.ql, *params)

                # if set, fire up the on-exit hook and let it override the return value
                if onexit_hook:
                    override = onexit_hook(self.ql, *params, retval)

                    if override is not None:
                        retval = override

                # set return value
                if retval is not None:
                    self.__syscall_cc.setReturnValue(retval)

            except KeyboardInterrupt:
                raise

            except Exception as e:
                self.ql.log.exception(f'Syscall ERROR: {syscall_name} DEBUG: {e}')
                raise e

            # print out log entry
            syscall_basename = syscall_name[len(SYSCALL_PREF) if syscall_name.startswith(SYSCALL_PREF) else 0:] 

            args = []

            for name, value in zip(param_names, params):
                # cut the first part of the arg if it is of form fstatat64_fd
                if name.startswith(f'{syscall_basename}_'):
                    name = name.partition('_')[-1]

                args.append((name, f'{value:#x}'))

            sret = QlOsPosix.getNameFromErrorCode(retval)
            self.utils.print_function(self.ql.reg.arch_pc, syscall_basename, args, sret, False)

            # record syscall statistics
            self.utils.syscalls.setdefault(syscall_name, []).append({
                "params": dict(zip(param_names, params)),
                "result": retval,
                "address": self.ql.reg.arch_pc,
                "return_address": None,
                "position": self.utils.syscalls_counter
            })

            self.utils.syscalls_counter += 1
        else:
            self.ql.log.warning(f'{self.ql.reg.arch_pc:#x}: syscall {syscall_name} number = {syscall_id:#x}({syscall_id:d}) not implemented')

            if self.ql.debug_stop:
                raise QlErrorSyscallNotFound(f'Syscall not found: {syscall_name}')