我想确定两个可执行文件中的两个函数是否是从相同的 (C) 源代码编译而来的,即使它们是由不同的编译器版本或使用不同的编译选项编译的,我也想这样做。目前,我正在考虑实现某种汇编程序级函数指纹识别。函数的指纹应该具有以下属性:
- 在不同情况下从同一来源编译的两个函数很可能具有相同的指纹(或相似的指纹),
- 从不同的 C 源代码编译的两个函数可能具有不同的指纹,
- (奖励)如果两个源函数相似,则指纹也相似(对于相似的某些合理定义)。
我现在正在寻找的是一组编译函数的属性,这些属性单独满足 (1.) 并希望也满足 (2.)。
假设
当然这通常是不可能的,但在大多数情况下可能存在一些可行的方法。以下是一些可以使其更容易的假设:
- linux ELF 二进制文件(虽然没有可用的调试信息),
- 没有以任何方式混淆,
- 由 gcc 编译,
- 在 x86 linux 上(可以在其他架构上实现的方法会很好)。
想法
不幸的是,我几乎没有组装经验。以下是上述属性的一些想法:
- 函数中包含的指令类型(即浮点指令、内存屏障)
- 从函数访问内存(它是否从/向堆读取/写入?堆栈?)
- 调用的库函数(它们的名称应该在 ELF 中可用;而且它们的顺序通常不应更改)
- 控制流图的形状(我猜这将高度依赖于编译器)
现有工作
我只能找到无关紧要的相关工作:
- 可以在编译代码中识别加密算法的自动化方法:http://www.emma.rub.de/research/publications/automated-identification-cryptographic-primitives/
- IDA反汇编器中的快速库识别与识别技术;标识具体的指令序列,但仍包含一些可能有用的想法:http://www.hex-rays.com/idapro/flirt.htm
您对函数属性有什么建议吗?或者一个不同的想法也可以实现我的目标?或者是否已经实现了类似的东西,但我完全错过了?
最佳答案
FLIRT 使用字节级模式匹配,因此它会随着指令编码的任何变化而崩溃(例如,不同的寄存器分配/重新排序的指令)。
对于图匹配,请参阅 BinDiff。虽然它是闭源的,但 Halvar 在 his blog 上描述了一些方法。 .他们甚至以 BinCrowd plugin 的形式开源了一些他们用来生成指纹的算法。 .
关于c - 汇编级函数指纹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7283702/