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)
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)
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
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
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)