如何通过静态分析从二进制文件中收集系统调用?

Posted

技术标签:

【中文标题】如何通过静态分析从二进制文件中收集系统调用?【英文标题】:How to collect system calls from a binary with static analysis? 【发布时间】:2018-06-01 08:08:14 【问题描述】:

我想通过静态分析获取给定二进制文件 (x86_64) 中使用的系统调用列表。我尝试了 strace,但它不能保证它是一个完整的列表,因为在执行期间可能不会调用某些系统调用。

【问题讨论】:

外部链接表不够吗? 我真的不知道外部链接表是什么,但我一定会调查的。谢谢! 符号表(AKA 链接表或依赖表)是您的程序使用的另一个二进制模块中的符号列表。当操作系统加载您的可执行文件时,它还通过加载其他模块并连接它们来解决这些依赖关系。它的工作方式各不相同,但所有 COFF/PE 文件都包含此表。 我明白了,它可能只包含在二进制文件中调用的函数,但我正在寻找的是特定的系统调用。但是获取函数列表也有帮助,因为我可以分析这些函数并找到被调用的系统调用。我想知道是否有更好更快的方法来实现这一目标。 删除执行期间未调用的系统调用需要解决停机问题。 【参考方案1】:

对于 C/C++,您可以尝试CppDepend 来检测与外部库和系统调用的所有依赖关系。但是,您必须分析源代码而不是二进制文件。

【讨论】:

【参考方案2】:

在静态分析中,假设二进制文件没有被混淆,有几个工具可以提供对二进制文件的深入了解。最常用的是IDA。在单独分析二进制文件时,几个编译选项在挑战静态分析技术方面发挥着重要作用,即动态与静态链接、剥离二进制文件、优化选项等。

查找系统调用的一种方法是使用IDAPython API 创建一个脚本,以便根据此处X86 Assembly/Interfacing with Linux 和此处Linux Syscall Reference 的描述查找系统调用。 IDAPython 提供了一个“足够好”的 API 来查看每个基本块中的指令来推断正在调用的系统调用。

【讨论】:

【参考方案3】:

使用 NDepend 工具,您可以通过代码查询来做到这一点,但仅限于 .NET 程序集:

from x in ThirdParty.CodeElements
select new  x, callers = 
  x.IsMethod ? x.AsMethod.MethodsCallingMe.Cast<ICodeElement>() : 
  x.IsType   ? x.AsType.TypesUsingMe.Cast<ICodeElement>() : new ICodeElement[0] 

【讨论】:

其实,我关注的是像 C 或 C++ 这样的编译程序。【参考方案4】:

我认为较早的答案是解决此问题的最简单方法。一种选择是使用支持二进制文件并导航控制流图的静态分析工具。如果在死代码中调用它们,这可能允许您排除某些函数,但它也会复杂得多。 GrammaTech CodeSonar 是一个支持二进制文件的商业工具,或许可以在这里提供帮助。

【讨论】:

以上是关于如何通过静态分析从二进制文件中收集系统调用?的主要内容,如果未能解决你的问题,请参考以下文章

C - 从二进制文件中读取位

使用 c++ 时从二进制文件中读取 int 不正确

从二进制文件读取时将大端转换为小端

如何从二进制文件中获取应用程序的版本号?

PHP如何将从二进制文件中读取的字节转换为数字

从二进制文件读/写包含数组的结构体