You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

stat系列系统调用混淆及kprobe挂载相关技术问询

问题描述

我尝试为stat系统调用设置kprobe以捕获相关信息,但查看/proc/kallsyms时发现大量相似名称的符号,难以确定正确的挂载目标。我的需求是找到对应stat filename或stat dir输出数据的系统调用。

我首先尝试挂载__x64_sys_stat,但处理函数未被触发;随后尝试__do_sys_stat、__x64_sys_newstat,同样无响应。/proc/kallsyms相关输出如下:

user@xubun2204:~$ cat /proc/kallsyms | grep newstat
0000000000000000 t __do_sys_newstat
0000000000000000 T __x64_sys_newstat
0000000000000000 T __ia32_sys_newstat
0000000000000000 t __do_compat_sys_newstat
0000000000000000 T __ia32_compat_sys_newstat
0000000000000000 T __x64_compat_sys_newstat
0000000000000000 d event_exit__newstat
0000000000000000 d event_enter__newstat
0000000000000000 d __syscall_meta__newstat
0000000000000000 d args__newstat
0000000000000000 d types__newstat
0000000000000000 d __event_exit__newstat
0000000000000000 d __event_enter__newstat
0000000000000000 d __p_syscall_meta__newstat
0000000000000000 d _eil_addr___x64_compat_sys_newstat
0000000000000000 d _eil_addr___ia32_compat_sys_newstat
0000000000000000 d _eil_addr___ia32_sys_newstat
0000000000000000 d _eil_addr___x64_sys_newstat
user@xubun2204:~$ cat /proc/kallsyms | grep do_stat
0000000000000000 T proc_do_static_key
0000000000000000 T do_statx
0000000000000000 t do_statfs_native
0000000000000000 t do_statfs64
user@xubun2204:~$ cat /proc/kallsyms | grep sys_stat
0000000000000000 t __do_sys_stat
0000000000000000 T __x64_sys_stat
0000000000000000 T __ia32_sys_stat
0000000000000000 T __x64_sys_statx
0000000000000000 T __ia32_sys_statx
0000000000000000 t __do_sys_statfs
0000000000000000 T __x64_sys_statfs
0000000000000000 T __ia32_sys_statfs
0000000000000000 t __do_sys_statfs64
0000000000000000 T __x64_sys_statfs64
0000000000000000 T __ia32_sys_statfs64
0000000000000000 t __do_compat_sys_statfs
0000000000000000 T __ia32_compat_sys_statfs
0000000000000000 T __x64_compat_sys_statfs
0000000000000000 T kcompat_sys_statfs64
0000000000000000 T __ia32_compat_sys_statfs64
0000000000000000 T __x64_compat_sys_statfs64
0000000000000000 d _eil_addr___ia32_sys_statx
0000000000000000 d _eil_addr___x64_sys_statx
0000000000000000 d _eil_addr___ia32_sys_stat
0000000000000000 d _eil_addr___x64_sys_stat
0000000000000000 d _eil_addr___x64_compat_sys_statfs64
0000000000000000 d _eil_addr___ia32_compat_sys_statfs64
0000000000000000 d _eil_addr___x64_compat_sys_statfs
0000000000000000 d _eil_addr___ia32_compat_sys_statfs
0000000000000000 d _eil_addr___ia32_sys_statfs64
0000000000000000 d _eil_addr___x64_sys_statfs64
0000000000000000 d _eil_addr___ia32_sys_statfs
0000000000000000 d _eil_addr___x64_sys_statfs

之后我尝试__x64_sys_statfs,处理函数成功被触发!我原本理解sys_stat用于获取文件/目录信息,sys_statfs用于获取文件系统信息,但无论我对stat命令传入文件、目录还是文件系统路径,__x64_sys_statfs都会被调用。现在我疑惑该syscall返回的是struct kstat还是struct statfs?

以下是我成功触发kretprobe处理函数的代码:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/statfs.h>
#include <linux/slab.h>
#include <linux/fs.h>

static struct kretprobe my_kretprobe;

static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
    printk("entry_handler\n");
    return 0;
}

static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
    printk("ret_handler\n");
    return 0;
}

static int __init my_module_init(void)
{
    int ret;

    my_kretprobe.kp.symbol_name = "__x64_sys_statfs";
    my_kretprobe.entry_handler = entry_handler;
    my_kretprobe.handler = ret_handler;
    my_kretprobe.maxactive = 20;

    ret = register_kretprobe(&my_kretprobe);
    if (ret < 0) {
        printk(KERN_INFO "register_kretprobe failed, returned %d\n", ret);
        return ret;
    }

    printk(KERN_INFO "Kretprobe registered for __x64_sys_statfs\n");
    return 0;
}

static void __exit my_module_exit(void)
{
    unregister_kretprobe(&my_kretprobe);
    printk(KERN_INFO "Kretprobe unregistered\n");
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("jelal");
MODULE_DESCRIPTION("simple kret lkm");

以及Makefile:

obj-m += statdata.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

我的实验目标是从内核中获取stat命令展示的数据,现存在以下疑问:

  1. sys_stat、sys_statfs、sys_newstat和sys_statx之间有何区别?
  2. 如何确定应挂载探针的正确系统调用?
  3. sys_stat未被调用的原因是什么?

解答

1. sys_stat、sys_statfs、sys_newstat和sys_statx的区别

  • sys_stat:早期的系统调用,对应旧版struct stat结构,字段长度和布局受32位/64位架构限制,属于被淘汰的旧接口,仅用于兼容老旧程序。
  • sys_newstat:sys_stat的过渡改进版,解决了32位系统中struct stat字段溢出问题,但仍为架构相关接口,现在已被新接口替代。
  • sys_statfs:专门用于获取文件系统层面的信息,比如总容量、可用空间、块大小等,返回struct statfs结构。stat命令会触发它,是因为默认会输出挂载点等文件系统相关信息。
  • sys_statx:Linux 4.11+引入的新一代统一接口,支持扩展属性、高精度时间戳,兼容32/64位架构,是当前用户态工具(包括stat命令)实际调用的核心系统调用。

2. 确定正确系统调用的方法

  • 直接跟踪用户态调用:用strace stat filename查看stat命令实际触发的系统调用,这是最精准的方式,会发现现代系统中stat实际调用的是statx。
  • 分析内核符号:关注带statx的符号(比如__x64_sys_statx)以及内核内部处理函数do_statx,这些是当前stat命令的实际依赖点。
  • 验证探针触发:先通过strace确认目标syscall,再挂载对应的kprobe,避免盲目尝试旧接口。

3. sys_stat未被调用的原因

现代Linux发行版中的stat命令(基于GNU coreutils)已默认使用statx系统调用,不再直接调用旧的sys_stat或sys_newstat。这些旧接口仅为兼容几十年前的程序保留,新工具不会主动使用,所以挂载__x64_sys_stat时不会被触发。


内容的提问来源于stack exchange,提问作者Jelal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 16:45:55