我正在尝试在
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
之间的区别的方式是sys_stat
用于获取有关文件和目录的信息,sys_statfs
用于获取有关文件系统的信息。
但是在这种情况下,无论我在
stat
命令行(文件系统或特定文件或目录)中经历什么,__x64_sys_statfs
都会被调用!
当我想读取此系统调用返回的内容时,问题就开始了,我应该期待
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 终端命令显示的数据。
sys_stat
、sys_statfs
、sys_newstat
和 sys_statx
有什么区别?谢谢
当您使用命令行 stat 实用程序时,是否使用取决于该实用程序的版本:
这些都返回有关命名对象的大致相同的信息(statx 使用不同的结构),但编程输入略有不同,而命令行工具不会公开这些信息。
在许多情况下,它将是 lstat,或者标记为 NOFOLLOW 的其他调用之一,因为 stat 命令想要报告它看到了链接。确定指定的资源不是链接后,就无需再次调用 stat,但如果它是链接,则可能需要再次调用 stat。
ltrace 和 strace 是有用的工具,可以查看应用程序实际进行了哪些库和系统调用。
通常,库调用是系统调用的薄包装器,但对于 stat 系列函数来说,库入口点的名称中有一个 x,以及一个额外的参数,指定应用程序所使用的 stat 结构的版本期望。动态库实现可以选择将系统调用结果转换为结构的早期版本,或者如果版本无法识别,则使调用失败而不进行系统调用。然而,我认为这个版本控制功能从来没有真正在愤怒中被使用过。通常,库调用名称会在名称后附加 64,以支持在过渡期间使用 64 位接口的 32 位程序,这些程序现在重新编译为 64 位程序。