Example #1
0
        def test_syscall_open(ql, open_pathname, open_flags, open_mode, *args):
            target = False
            pathname = ql_read_string(ql, open_pathname)

            if pathname == "test_syscall_open.txt":
                print("test => open(%s, 0x%x, 0%o)" %
                      (pathname, open_flags, open_mode))
                target = True

            syscall.ql_syscall_open(ql, open_pathname, open_flags, open_mode,
                                    *args)

            if target:
                real_path = ql_transform_to_real_path(ql, pathname)
                assert os.path.isfile(real_path) == True
                os.remove(real_path)
Example #2
0
        def test_syscall_open(ql, open_pathname, open_flags, open_mode, *args):
            target = False
            pathname = ql.mem.string(open_pathname)

            if pathname == "test_syscall_open.txt":
                print("test => open(%s, 0x%x, 0%o)" %
                      (pathname, open_flags, open_mode))
                target = True

            syscall.ql_syscall_open(ql, open_pathname, open_flags, open_mode,
                                    *args)

            if target:
                real_path = ql.os.transform_to_real_path(pathname)
                assert os.path.isfile(real_path) == True
                if ql.platform == QL_OS.WINDOWS:
                    return
                else:
                    os.remove(real_path)
Example #3
0
        def test_syscall_open(ql, open_pathname, open_flags, open_mode, *args):
            target = False
            pathname = ql.os.utils.read_cstring(open_pathname)

            if pathname == "test_syscall_open.txt":
                print("test => open(%s, 0x%x, 0%o)" % (pathname, open_flags, open_mode))
                target = True

            regreturn = syscall.ql_syscall_open(ql, open_pathname, open_flags, open_mode, *args)

            if target:
                real_path = ql.os.path.transform_to_real_path(pathname)
                assert os.path.isfile(real_path) == True
                if ql.host.os != QL_OS.WINDOWS:
                    os.remove(real_path)

            return regreturn
Example #4
0
def ql_qnx_msg_io_connect(ql: Qiling, coid, smsg, sparts, rmsg, rparts, *args,
                          **kw):
    # first iov_t
    iov_base = ql.unpack32(ql.mem.read(smsg, 4))
    iov_len = ql.unpack32(ql.mem.read(smsg + 4, 4))
    assert iov_len == 40, "io_connect: wrong size for first first iov_t"
    # struct _io_connect in lib/c/public/sys/iomsg.h
    (type, subtype, file_type, reply_max, entry_max, key, handle, ioflag, mode,
     sflag, access, zero, path_len, eflag, extra_type,
     extra_len) = unpack("<HHIHHIIIIHHHHBBH", ql.mem.read(iov_base, iov_len))
    # second iov_t
    iov_base = ql.unpack32(ql.mem.read(smsg + 8, 4))
    iov_len = ql.unpack32(ql.mem.read(smsg + 12, 4))
    path = ql.mem.read(iov_base, iov_len).decode("utf-8").rstrip('\x00')
    real_path = ql.os.path.transform_to_real_path(path)
    # check parameters
    assert (type, reply_max, entry_max, key, handle, zero, eflag,
            extra_type) == (0x100, 0xa18, 0x10, 0, 0, 0, 0,
                            0), "io_connect message is wrong"

    if not subtype in io_connect_subtypes:
        raise NotImplementedError(
            f'msg_io_connect subtype {subtype} not implemented')

    if not file_type in file_types:
        raise NotImplementedError(
            f'msg_io_connect file_type {file_type} not implemented')

    if not sflag in file_sharing_modes:
        raise NotImplementedError(
            f'msg_io_connect sharing flag {sflag} not implemented')

    if access != 0 and not access in file_access:
        raise NotImplementedError(
            f'msg_io_connect access {access} not implemented')

    ioflag_lo = ioflag & IO_FLAG_MASK
    ioflag_hi = ioflag & (~IO_FLAG_MASK)
    real_mode = mode & (~S_IFMT)
    # ql.log.debug(f'msg_io_connect(subtype = {subtype}, file_type = {file_type}, ioflag = 0x{ioflag:x}, mode = 0x{mode:x}, sflag = 0x{sflag:x}, access = {access}, extra_len = {extra_len})')
    ql.log.debug(
        f'msg_io_connect(subtype = {io_connect_subtypes[subtype]}, file_type = {file_types[file_type]}, ioflag = {_constant_mapping(ioflag_lo, io_connect_ioflag) + _constant_mapping(ioflag_hi, file_open_flags)}, mode = 0x{real_mode:x}, type = {_constant_mapping((mode & S_IFMT), file_stats)}, sflag = {file_sharing_modes[sflag]})'
    )
    # convert _IO_FLAG_? to O_? flag and then to O_? flags of host system
    ioflag -= 1
    #ioflag = ql_open_flag_mapping(ql, ioflag)
    # handle subtype
    if subtype == 0 or subtype == 1:  # == _IO_CONNECT_COMBINE or _IO_CONNECT_COMBINE_CLOSE
        # third iov_t if required for alignment
        if sparts > 2:
            iov_base = ql.unpack32(ql.mem.read(smsg + 16, 4))
            iov_len = ql.unpack32(ql.mem.read(smsg + 20, 4))
        # forth iov_t
        if sparts > 3:
            iov_base = ql.unpack32(ql.mem.read(smsg + 24, 4))
            iov_len = ql.unpack32(ql.mem.read(smsg + 28, 4))
        # struct _io_* in lib/c/public/sys/iomsg.h
        iov_msg = ql.mem.read(iov_base, iov_len)
        (x_type, x_combine_len) = unpack("<HH", iov_msg[:4])
        # ql.log.debug(f'msg_io_connect(_IO_CONNECT_COMBINE): extra iov_t(type = 0x{x_type:x}, combine_len = 0x{x_combine_len:x})')
        if x_type == 0x104:  # == _IO_STAT
            # struct _io_stat in lib/c/public/sys/iomsg.h
            (x_type, x_combine_len, x_zero) = unpack("<HHI", iov_msg)
            ql.log.debug(
                f'msg_io_connect(_IO_CONNECT_COMBINE + _IO_STAT, path = {path})'
            )
            if not os.path.exists(real_path):
                return -1
            # reply iov_t no. 2
            iov_base = ql.unpack32(ql.mem.read(rmsg + 8, 4))
            iov_len = ql.unpack32(ql.mem.read(rmsg + 12, 4))
            #ql.os.fd[coid] = ql.os.fs_mapper.open_ql_file(path, ioflag, real_mode)
            ql.os.connections[coid].fd = ql_syscall_open(
                ql, ql.unpack32(ql.mem.read(smsg + 8, 4)), ioflag, real_mode)
            ql_syscall_fstat(ql, ql.os.connections[coid].fd, iov_base)
        elif x_type == 0x108:  # == _IO_PATHCONF
            # struct _io_pathconf in lib/c/public/sys/iomsg.h
            (x_type, x_combine_len, x_name, x_zero) = unpack("<HHhH", iov_msg)
            if not x_name in pathconf_names:
                raise NotImplementedError("unknown path_conf name")
            ql.log.debug(
                f'msg_io_connect(_IO_CONNECT_COMBINE + _IO_PATHCONF, name = {pathconf_names[x_name]}, path = {path})'
            )
            if x_name == 5:  # == _PC_NAME_MAX
                return 1024
        else:
            # TODO: Can we throw this exception here?
            # raise NotImplementedError(f'msg_io_connect(_IO_CONNECT_COMBINE) for type 0x{x_type:x} not implemented')
            ql.log.warn(
                f'msg_io_connect(_IO_CONNECT_COMBINE) for type 0x{x_type:x} not implemented'
            )
    elif subtype == 2:  # == _IO_CONNECT_OPEN
        ql.log.debug(
            f'open(path = {path}, openflags = 0x{ioflag:x}, openmode = 0x{real_mode:x})'
        )
        ql.os.connections[coid].fd = ql_syscall_open(
            ql, ql.unpack32(ql.mem.read(smsg + 8, 4)), ioflag, real_mode)
        #ql.os.fd[coid] = ql.os.fs_mapper.open_ql_file(path, ioflag, real_mode)
    elif subtype == 5:  # == _IO_CONNECT_MKNOD
        ql.log.debug(f'mkdir(path = {real_path}, mode = 0x{real_mode:x})')
        os.mkdir(real_path, real_mode)
    else:
        raise NotImplementedError(
            f'msg_io_connect for {io_connect_subtypes[subtype]} not implemented'
        )
    # reply iov_t no. 1
    iov_base = ql.unpack32(ql.mem.read(rmsg, 4))
    iov_len = ql.unpack32(ql.mem.read(rmsg + 4, 4))
    assert iov_len == 20, "msg_io_connect() reply iov_t 1 wrong size"
    if os.path.isdir(real_path):
        eflag = io_connect_eflag['_IO_CONNECT_EFLAG_DIR']
    elif path.endswith('..'):
        eflag = io_connect_eflag['_IO_CONNECT_EFLAG_DOTDOT']
    elif path.endswith('.'):
        eflag = io_connect_eflag['_IO_CONNECT_EFLAG_DOT']
    else:
        eflag = 0
    if os.path.islink(real_path):
        umask = file_stats['_S_IFLNK']
    elif os.path.isdir(real_path):
        umask = file_stats['_S_IFDIR']
    elif os.path.isfile(real_path):
        umask = file_stats['_S_IFREG']
    else:
        ql.log.warn(
            "msg_io_connect(): type of {real_path} not handled properly?")
        umask = 0
    # struct _io_connect_link_reply in lib/c/public/sys/iomsg.h
    ql.mem.write(iov_base,
                 pack("<IIBBHIHH", 0, file_type, eflag, 0, 0, umask, 0, 0))
    return 0
Example #5
0
def hook_open(ql: Qiling, filename_pointer: int, flags: int, mode) -> None:
    log.info("Got filename pointer: {}".format(filename_pointer))
    filename = ql.mem.string(filename_pointer)
    log.info("Open file: {}, flags: {:b}, mode: {:b}".format(
        filename, flags, mode))
    syscall.ql_syscall_open(ql, filename, flags, mode)