系统调用号 → 运行时的名称映射

系统调用号 → 运行时的名称映射

有没有办法解决观察到的系统调用的数量:

SYS_345(0xe, 0xbff94188, 0x2, 0x4000, 0xb6526000) = 2

到正在运行的内核中的符号名称而不在源代码中查找它?

编辑用例已经过时斯特雷斯外部机器上的二进制文件,其内核源代码的检索可能很繁琐。

答案1

据我所知,没有一种有保证的方法可以确定正在运行的内核中从系统调用号到系统调用名称的映射。查找与系统调用号相对应的调用总是需要挖掘源代码......

需要执行此类映射的软件开发人员倾向于维护自己的系统调用列表;这是使用的方法strace。这确实意味着与任何给定内核相比,此类程序的任何给定版本都可能过时,尽管实际上系统调用的添加速度足够慢,这不是什么大问题。

即使在内核源代码中查找值也很复杂,因为根据架构的不同,映射以不同的方式存储。即使在映射“简单”的架构上,例如 x86 及其系统调用表,查找给定号码的呼叫可能涉及在不同位置进行多次查找。

只要系统具有 GCC 和系统头文件,找到系统映射的一种快速、可靠的方法就是使用后者。例如,

awk 'BEGIN { print "#include <sys/syscall.h>" } /p_syscall_meta/ { syscall = substr($NF, 19); printf "syscalls[SYS_%s] = \"%s\";\n", syscall, syscall }' /proc/kallsyms |
sort -u | gcc -E -P - | less

从 中提取 Linux 系统调用列表/proc/kallsyms,构建一段 C 代码(或者更确切地说,C 预处理器代码)并将其输入预处理器,生成类似的内容

syscalls[288] = "accept4";
syscalls[43] = "accept";
syscalls[21] = "access";
syscalls[163] = "acct";
syscalls[248] = "add_key";

等等。如有必要,您可以使用 GCC 标志来调整架构以匹配内核(例如 -m32查看 i386 系统调用号,或-mx32x86-32 号)。

在您的情况下,345 是 i386 上系统调用的编号sendmmsg,与 x86-64 或 x86-32 上的任何内容都不对应。它于 2011 年推出,大约在 2.6.39 时间范围内,因此任何使用长期存在的 2.6.32 作为其内核和相关程序基础的系统都不会知道它(因此您可能会在strace类似的年份中看到它) ,以及更新的内核)。

相关内容