ql_syscall_getdents 使用的是 linux_dirent结构
struct linux_dirent {
long d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name[];
/*
char pad; // Zero padding byte
char d_type; // File type (only since Linux 2.6.4;
// offset is (d_reclen - 1))
*/
};
但是 ql_syscall_getdents64 使用的是 linux_dirent64 结构体
struct linux_dirent64 {
u64 d_ino;
s64 d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[0];
};
所以系统ql_syscall_getdents64 需要将原来的 name 和 type 换位置
def ql_syscall_getdents64(ql, fd, dirp, count, *args, **kw):
def _type_mapping(ent):
methods_constants_d = {'is_fifo': 0x1, 'is_char_device': 0x2, 'is_dir': 0x4, 'is_block_device': 0x6,
'is_file': 0x8, 'is_symlink': 0xa, 'is_socket': 0xc}
ent_p = pathlib.Path(ent.path) if isinstance(ent, os.DirEntry) else ent
for method, constant in methods_constants_d.items():
if getattr(ent_p, method, None)():
t = constant
break
else:
t = 0x0 # DT_UNKNOWN
return bytes([t])
if ql.os.fd[fd].tell() == 0:
n = ql.archbit // 8
total_size = 0
results = os.scandir(ql.os.fd[fd].name)
_ent_count = 0
for result in itertools.chain((pathlib.Path('.'), pathlib.Path('..')), results): # chain speical directories with the results
d_ino = result.inode() if isinstance(result, os.DirEntry) else result.stat().st_ino
d_off = 0x0
d_name = (result.name if isinstance(result, os.DirEntry) else result._str).encode() + b'\x00'
d_type = _type_mapping(result)
d_reclen = len(d_name) + n*2 + 3
#print (d_name)
ql.mem.write(dirp, ql.pack(d_ino))
ql.mem.write(dirp+n, ql.pack(d_off))
ql.mem.write(dirp+n*2, ql.pack16(d_reclen))
ql.mem.write(dirp+n*2+2, d_type)
ql.mem.write(dirp+n*2+2+1, d_name)
dirp += d_reclen
total_size += d_reclen
_ent_count += 1
regreturn = total_size
ql.os.fd[fd].lseek(0, os.SEEK_END) # mark as end of file for dir_fd
else:
_ent_count = 0
regreturn = 0
ql.log.debug("getdents(%d, /* %d entries */, 0x%x) = %d" % (fd, _ent_count, count, regreturn))
return regreturn
测试结果
修复前:

修复后:

ql_syscall_getdents 使用的是 linux_dirent结构
但是 ql_syscall_getdents64 使用的是 linux_dirent64 结构体
所以系统ql_syscall_getdents64 需要将原来的 name 和 type 换位置
测试结果

修复前:
修复后:
