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

phg*_*phg 6 linux system-calls strace

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

SYS_345(0xe, 0xbff94188, 0x2, 0x4000, 0xb6526000) = 2
Run Code Online (Sandbox Code Playgroud)

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

编辑用例是一个过时的strace二进制文件,位于外部框上,其内核源代码检索起来可能很乏味。

Ste*_*itt 7

据我所知,没有保证的方法来确定从正在运行的内核中的系统调用号到系统调用名的映射。找到与系统调用号对应的调用总是涉及挖掘源代码......

需要执行此类映射的软件开发人员倾向于维护自己的系统调用列表;这是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
Run Code Online (Sandbox Code Playgroud)

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

syscalls[288] = "accept4";
syscalls[43] = "accept";
syscalls[21] = "access";
syscalls[163] = "acct";
syscalls[248] = "add_key";
Run Code Online (Sandbox Code Playgroud)

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

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