H2二进制程序函数相似性比较
-
简称BCSD
-
应用:相似漏洞检测,漏洞去重,软件抄袭检测,恶意软件检测
-
本质:寻找变量中的不变量
- 完全相等
- 逻辑相似
- 功能等价
我们可以将相似性检测的方案总结为以下步骤:
- 定义用于计算相似度的不变量
- 提取不变量
- 根据提取到的不变量计算相似度
逻辑相似
定义:相同的源代码产生相似的二进制代码
程序逻辑的表征:指令序列 & 程序结构
- 指令序列
- 由程序中指令组成的序列,通常逻辑相似的程序会有相似的指令序列
- 如何提取指令序列?
- 单条指令
- 滑动窗口提取指令信息
- 函数切片
- 有数据流关系的指令切片,每次处理单元为包含多条指令的切片
- 切片中的指令序列存在数据流依赖,上下文信息更加明确
- 程序结构
- 表征程序逻辑跳转、数据传递的数据结构
- 逻辑相似的程序其控制流、数据流通常相似
- 反映程序的逻辑:
- CFG(Control Flow Graph):控制流图
- DFG(Data Flow Graph):数据流图
- 如何提取程序结构?
- 使用二进制分析工具,例如IDA Pro、Ghidra、Ninja等可以直接构建CFG
- 数据流图可以基于以上工具开发脚本,以静态/动态方式构建数据流图
如何比较程序结构的相似性?
- 图同构
- 若两个函数的CFG同构,则认为这两个函数相似
- 图同构问题为NP完全问题,在实际应用时需要进行额外处理
- 舍弃结果精确程度,使用贪心等时间复杂度可接受的算法
- 限制图的节点数量,对多个子图进行匹配,反推完整图相似度
- 执行路径相似度
- 将图匹配转换为序列匹配
- 执行路径如何提取?图上搜索 / 动态执行
- 图嵌入
- 使用AI训练CFG转换为特征向量的神经网络
- 使用简单的特征向量计算相似度
功能相同
定义:程序逻辑看似完全不同,功能完全等价
之前方案有什么问题?
- 认为 程序逻辑相似 == 功能相似
- 但存在 程序逻辑相似,功能不等价;逻辑不相似,功能等价
- 本质上缺少对程序功能的理解
如何表示程序功能(程序语义)?
-
API/System Call建模
- **主要观察:**API/Syscall的语义不会随程序变化而变化
- 缺点:不能用于判断功能是否等价
-
输入/输出匹配
- **主要观察:**语义相同的程序在有相同的输入时输出页相同
- 缺点:很难测试所有的输入,只能判断两个程序片段大概率相似
-
符号表达式
- **主要观察:**语义相同的代码片段其符号表达式等价
- 符号表达式为一个等式,其左边为输出变量,右边为输入变量以及逻辑操作
- 假设w0符号变量为W0,运行指令后,w0为W0’ = (W0 << 1) | (W0 >> 1)
- 如何使用符号表达式表征语义?
- 以基本块为单位提取符号表达式
- 在函数粒度提取函数返回值的符号表达式
- 以执行路径为单位,提取使用了函数参数的符号表达式
- 对于提取得到的符号表达式,使用符号表达式验证器计算表达式是否等价,或使用语义哈希和图距离计算的方法计算符号表达式句法相似性
- 缺点:计算复杂度较高,难以直接应用到较大程序中
小结
推荐阅读文章:
- Neural Network-based Graph Embedding for Cross-Platform Binary Code Similarity Detection CCS’17 (图嵌入、AI)
- BinSequence: Fast, Accurate and Scalable Binary Code Reuse Detection ASIA CCS’17 (LCS、图匹配)