十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

pwndbg kfile 命令完全指南:在内核调试中查看任务文件描述符表

pwndbg kfile 命令完全指南:在内核调试中查看任务文件描述符表 pwndbg kfile 命令完全指南在内核调试中查看任务文件描述符表【免费下载链接】pwndbgExploit Development and Reverse Engineering with GDB LLDB Made Easy项目地址: https://gitcode.com/GitHub_Trending/pw/pwndbg导读kfile是 pwndbg 提供的内核调试命令之一用于在 Linux 内核调试会话中展示内核任务kernel task可访问的文件描述符fd信息包括每个 fd 对应的struct file对象地址、文件操作函数表f_op、打开模式标志、private_data私有数据以及解析后的完整文件路径。阅读完本文你将掌握kfile的全部参数用法、输出字段含义、底层实现原理以及如何配合ktask/kcurrent在 QEMU 内核调试环境中快速定位目标任务的打开文件。命令概览与使用前提kfile命令的完整用法如下usage: kfile [-h] [--fd [FD]] [pid]其官方帮助描述为Displays information about fds accessible by a kernel task.即显示内核任务可访问的 fd 信息。该命令属于 pwndbg 的KERNEL命令类别见 kcurrent.py 中的CommandCategory.KERNEL与kstack、knamespace、ksighand、kseccomp、kcurrent等命令同属内核任务分析工具族。运行前置条件与大多数 pwndbg 内核命令一样kfile依赖以下四个装饰器限定的调试环境见 kcurrent.py装饰器含义OnlyWhenQemuKernel仅在通过 QEMU 调试 Linux 内核时可用即当前调试会话是内核而非普通用户态进程OnlyWhenPagingEnabled要求内核分页paging机制已启用命令才能正确进行虚拟地址解析OnlyWithKernelSymbols要求加载了内核符号信息以便定位task_struct等结构WarnOnKernelConfigRandstruct若内核启用了CONFIG_RANDSTRUCT随机化结构布局会给出警告此时字段偏移可能不可靠因此使用kfile的典型场景是通过 QEMU 启动一个带调试符号的 Linux 内核例如gdb vmlinux后连接qemu-system-*并保证分页开启。参数详解kfile接受两个参数一个可选的位置参数pid和一个可选的--fd选项。参数类型默认行为说明pidint可选使用当前内核任务指定要查询文件描述符表的内核任务的 PID省略时使用kcurrent设置的任务或调试器当前所处任务--fd [FD]int可选显示全部 fd只显示指定文件描述符编号的信息用于精确过滤输出参数解析逻辑位于 kcurrent.pyparser argparse.ArgumentParser( descriptionDisplays information about fds accessible by a kernel task. ) parser.add_argument(pid, nargs?, typeint, help) parser.add_argument(--fd, nargs?, typeint, help)注意nargs?表示两个参数都可省略若省略pid命令会自动回退到「当前任务」。pid 的解析规则kfile内部通过select_kthread_from_pid()选定目标线程kcurrent.py其优先级为pid 为空优先使用kcurrent --set pid设置的当前内核任务见下文「与 kcurrent 的协同」若未设置则取调试器当前所处任务pwndbg.aglib.kernel.current_task()并要求该地址属于内核地址空间is_kernel否则提示current task not foundpid 不为空遍历ktask枚举到的所有任务及其线程按 PID 精确匹配若找不到输出警告ktask with pid {pid} not found并返回。这一解析机制与kstack、knamespace、ksighand、kseccomp完全共享属于内核任务族命令的统一入口。输出字段解读kfile输出采用缩进分层的格式使用IndentContextManager实现首先打印任务摘要随后逐行列出每个 fd。以测试代码中的断言[fileno 001]为特征格式典型输出如下task 0xffff88800a1a0000: [pid 1234] [user task] [bash] - [fileno 000] file 0xffff88800a3b0000: ops 0xffffffff8205a3e0 private: 0x0, flags: R, path: /dev/pts/0 - [fileno 001] file 0xffff88800a3b0120: ops 0xffffffff8205a3e0 private: 0x0, flags: RW, path: /dev/pts/0各字段含义如下对应 kcurrent.py 的实现输出片段含义源码来源task 地址任务摘要由Kthread对象打印包含任务地址、PID、是否用户任务及进程名ktask.Kthread[fileno NNN]文件描述符编号三位补零显示f{i:03}file 地址struct file对象在内核中的地址int(file)ops 地址f_op文件操作函数表struct file_operations *的地址int(file[f_op])private: 地址struct file的private_data字段值常为驱动私有数据或空指针int(file[private_data])flags: R/W/X由f_mode位标志解出的访问模式fmode_flags见下文path: 路径解析出的文件完整路径可能为伪文件/匿名对象get_filepath()f_mode 标志位的解析f_mode通过位标志类BitFlags解码kcurrent.pyfmode_flags BitFlags([(R, 0), (W, 1), (X, 5)])即第 0 位为只读R、第 1 位为可写W、第 5 位为可执行X。输出时通过ctx_color.format_flags按位着色显示例如只读文件显示R读写显示RW。这对应 Linux 内核FMODE_READ、FMODE_WRITE、FMODE_EXEC的概念注意其具体位值来自内核定义此处为 pwndbg 为展示需要建立的映射。底层实现原理文件描述符表如何被枚举kfile的数据来源是内核task_struct的files字段struct files_struct *。核心枚举逻辑位于 ktask.py 的Kthread.files()方法pwndbg.lib.cache.cache_until(stop) def files(self) - tuple[tuple[int, pwndbg.dbg_mod.Value], ...]: fdt self.thread[files][fdt] fds fdt[fd] files [] for i in range(int(fdt[max_fds])): file fds[i] addr int(file) if addr 0: continue files.append((i, file)) return tuple(files)实现要点从thread[files]取得struct files_struct再取其fdt文件描述符表遍历0 .. max_fds范围内的fd数组跳过空槽位地址为 0 表示该 fd 未打开返回值是(fd 编号, struct file 指针)的元组并通过cache_until(stop)缓存直到调试器停止事件如断点命中、单步才失效避免重复读内存kfile在遍历时若传入了--fd则只保留i fd的条目kcurrent.py。路径解析get_filepath 如何还原完整文件路径kfile输出的path字段由 ktask.py 的get_filepath()生成这是整个命令最核心的解析逻辑其工作流程如下将struct file转为类型化指针空指针返回空字符串取file[f_path][dentry]目录项与file[f_path][mnt]挂载点从挂载点偏移得到struct mount自底向上回溯沿dentry[d_parent]逐级向上收集d_name目录项名直到抵达挂载根mnt_root或自身父目录等于自身跨挂载点若到达当前挂载根且不是最顶层挂载则跳到mount[mnt_parent]的mnt_mountpoint实现跨文件系统边界的路径拼接将收集到的路径段逆序组合os.path.join(*path[::-1])并附上f_inode的i_ino信息特殊文件类型归类依据路径名UNIX/NETLINK/TCP/TCPv6/UDP/UDPv6/PACKET 显示为[类型] socket:[inode]非/开头的匿名路径显示为anon:[路径]空路径显示为pipe:[inode]。因此kfile不仅能显示普通文件的绝对路径还能区分 socket、匿名 inode 与管道等特殊打开对象这在分析内核 exploit 时尤为关键——例如攻击者通过memfd_create创建的匿名文件会显示为anon:[memfd:xxx]伪造的 socket 也会被明确标注。与 kcurrent、ktask 的协同使用kfile是内核任务族命令的一员实际调试中通常与以下命令配合ktask枚举当前内核中的所有任务及其线程从中挑选感兴趣的 PID再交给kfile pid查询其打开的文件kcurrent [--set pid]设置或查看 pwndbg 当前关注的内核任务。--set选项的帮助信息明确列出其影响范围kcurrent.pysets the kernel task used for supported pwndbg commands (kfile, kstack, knamespace, ksighand, kseccomp, pagewalk, vmmap)即设置后不带 pid 直接执行kfile就会以该任务为目标该设置只影响这些命令的解析行为不改变调试器内部内存状态。典型工作流(gdb) ktask # 枚举所有内核任务记下目标用户进程的 PID (gdb) kcurrent --set 1234 # 将 1234 设为当前任务 (gdb) kfile # 直接查看该任务的全部打开文件 (gdb) kfile --fd 3 # 只看 fd 3如 socket 或目标文件测试验证仓库的内核命令测试 test_commands_kernel.py 中test_command_ktask对kfile的验证路径如下res gdb.execute(ktask, to_stringTrue) # 枚举任务解析出某个 user task 的 PID res gdb.execute(kcurrent, to_stringTrue) # 查看当前任务 res gdb.execute(fkcurrent --set {userpid}, to_stringTrue) if not found not in res and user task in res: res gdb.execute(kfile, to_stringTrue) assert [fileno 001] in res # 断言输出包含 fd 编号行该测试证实kfile需要在kcurrent --set pid指向用户任务后才能稳定输出输出格式中必然包含[fileno NNN]样式的 fd 编号行测试运行于 QEMU 系统模式tests/library/qemu_system与命令的OnlyWhenQemuKernel前置条件一致。这意味着你在真实调试中若遇到kfile无输出可优先检查是否处于 QEMU 内核调试会话、是否用kcurrent --set指定了用户任务、以及该任务的 fd 表是否为空。总结kfile是 pwndbg 内核调试工具链中查看任务文件描述符的专用命令具备以下能力无参数列出当前任务的全部打开文件或通过--fd精确过滤单个描述符通过pid参数查询任意枚举到的内核任务输出每个 fd 的struct file地址、f_op操作表、f_mode访问模式、private_data与解析后的路径底层基于files_struct-fdt遍历与 dentry 回溯路径解析能识别 socket、匿名文件与管道等特殊对象。配合ktask枚举任务与kcurrent --set切换目标任务你可以在内核漏洞利用与逆向分析中快速还原一个进程的文件访问视图——这对于判断目标是否打开特定文件、定位匿名映射对象或识别网络连接的底层 socket 都非常实用。源码参考命令实现、fd 枚举、路径解析、集成测试。【免费下载链接】pwndbgExploit Development and Reverse Engineering with GDB LLDB Made Easy项目地址: https://gitcode.com/GitHub_Trending/pw/pwndbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表