使用LD_PRELOAD拦截文件系统调用时,如何确认直接stat系统调用?
确认直接调用stat系统调用的方法及应用实现方式
怎么确认是直接系统调用?
- 用
strace -e raw=stat跟踪进程:如果输出里显示的是系统调用的数字编号(比如x86_64架构下stat的系统调用号是4),而不是stat或__xstat这类函数名,就说明是直接发起的系统调用。因为libc的包装函数会被strace识别并标注函数名,直接触发的系统调用则会显示原始的调用编号。 - 反汇编应用二进制:用
objdump -d <你的应用程序>或者gdb调试,定位到调用stat的代码位置。如果看到的是syscall(x86_64)或int 0x80(x86)这类直接触发系统调用的指令,而非call stat或call __xstat,那就是绕开libc直接调用内核。 - 检查动态符号表:执行
nm -D <你的应用程序>,如果没有stat或__xstat的未定义符号(带U标记),说明应用根本没链接libc的stat包装函数,大概率是自己直接调用系统调用。
应用怎么做到直接调用stat系统调用?
- 手动写汇编指令:开发者可以在代码里嵌入汇编,直接用
syscall(或对应架构的系统调用触发指令)传入stat的系统调用号和参数。比如x86_64下,把路径指针放到rdi寄存器,stat结构体指针放到rsi,rax寄存器设为4(stat的系统调用号),然后执行syscall指令。 - 用
syscall()函数直接触发:有些程序会调用内核提供的syscall入口函数(不是libc的包装),或者自己实现类似逻辑,直接传递系统调用号和参数,绕开libc的stat包装层。 - 静态链接+自定义系统调用逻辑:如果应用是静态链接,但没使用libc的stat包装,而是自己实现了触发系统调用的代码,也会出现这种情况。
- 特殊环境下的自定义libc:比如嵌入式场景里,可能用的是精简的自定义libc,直接暴露系统调用接口,或者编译时特意跳过了libc的包装函数。
内容的提问来源于stack exchange,提问作者Prabhu
相关产品推荐
相关产品推荐

