我想确定两个可执行文件中的两个函数是否是从相同的(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
您对函数属性有什么建议吗?或者一个不同的想法也可以实现我的目标?还是已经实现了类似的东西而我完全错过了它?