VexIR2Vec : An Architecture-Neutral Embedding Framework for Binary Similarity
标题: VexIR2V ec : An Architecture-Neutral Embedding Framework for Binary Similarity (S. VenkataKeerthy,2025)
作者: S. VenkataKeerthy, Soumya Banerjee, Sayan Dey, Yashas Andaluri, Raghul PS, Subrahmanyam Kalyanasundaram, Fernando Magno Quintão Pereira, Ramakrishna Upadrasta
期刊: ACM Transactions on Software Engineering and Methodology
摘要
二进制相似性涉及确定两个二进制程序是否表现出相似的功能,广泛应用于漏洞检测、恶意软件分析和版权检测。然而,编译器设置、目标架构和故意的代码混淆的变化显著增加了相似性度量的复杂性,因为它们有效地改变了底层二进制的语法、语义和结构。为了解决这些挑战,我们提出了VexIR2Vec,一种基于VEX-IR的强大、架构中立的方法,用于解决二进制相似性任务。VexIR2Vec由三个关键组件组成:一个peephole extractor、一个normalization engine(VexINE)和一个embedding model(VexNet)。构建程序嵌入的过程从通过随机游走从控制流图中提取基本块序列(或peephole),捕捉结构信息开始。然后,使用VexINE对这些生成的peephole进行规范化,VexINE应用编译器启发的变换来减少架构和编译器引起的变化。接着,使用表示学习技术生成peephole的嵌入,避免了词汇表外(OOV)问题。这些嵌入随后通过VexNet进行微调,VexNet是一个前馈型Siamese网络,将函数映射到高维空间,以便在应用独立的方式下进行差异比较。
论文在一个包含来自7个项目的2.7百万个函数和1.55万个二进制文件的数据集上,对VexIR2Vec与五个基准方法——BinDiff、DeepBinDiff、SAFE、BinFinder和操作码直方图——进行了评估。该数据集由针对x86和ARM架构的12个编译器编译的二进制文件组成。实验涵盖了四种典型的对抗性设置——跨优化、跨编译、跨架构和混淆——这些设置通常被恶意软件和漏洞所利用。在差异比较实验中,VexIR2Vec在这四种场景下分别超越最近的基准方法40%、18%、21%和60%。在搜索实验中,VexIR2Vec的平均精度达到0.76,比最近的基准方法高出46%。我们的框架具有高度可扩展性,作为一个轻量级的多线程并行库构建,且仅使用开源工具。VexIR2Vec比最接近的基准方法快约3.1到3.5倍,比其他工具快几个数量级。
作为一篇2025年的论文,其所使用的Baseline都比较旧。
引言
二进制相似性是确定两个二进制程序是否表现出相似功能的任务,通常它们源自相同的源代码。解决这个问题的方法在漏洞分析、恶意软件检测、抄袭识别、版权认证、档案匹配、代码提升和冗余消除等应用中具有重要作用。本文聚焦于二进制相似性问题的两种形式:差异比较和搜索。差异比较旨在识别两个二进制文件之间相似或不相似的区域(例如基本块、函数)。搜索则涉及从大量二进制函数中检索与查询代码相似的二进制函数。在对抗性环境中,这些任务变得具有挑战性,因为来自相同源代码编译的二进制文件由于以下几个因素而有所不同:(i)编译器选择(例如Clang、GCC、ICC);(ii)编译器版本(例如Clang 6.0.0与Clang 17.0.0);(iii)编译器优化(例如GCC -O0与GCC -O3);(iv)目标架构(例如x86、ARM);(v)使用混淆技术(例如控制流扁平化或死控制流)。这些编译配置的变化可能会显著改变二进制文件的语法、语义和结构,正如我们在第2.2节中讨论的那样。
在对抗性环境中,二进制相似性的最先进解决方案。二进制相似性工具采用各种表示方法来弥合原始二进制文件和更易分析的格式之间的差距。这些表示方法包括汇编语言、虚拟化字节码或抽象语法树(AST)。一旦转换完成,就会使用几种技术来识别代码相似性。这些方法本质上是启发式的,因为确定程序等价性的一般问题是不可判定的。常见的启发式方法包括图匹配技术、代码序列的哈希方法或机器学习(ML)。机器学习模型已经成为主流方法,因为它们能够学习代码中的复杂关系。基于机器学习的二进制相似性方法需要将代码转换为适合用作模型输入的数值向量。这些向量可以编码手工制作的特征或学习到的表示。基于特征的方法使用手动定义的程序特征,如操作码数量、循环和函数调用等,来表示二进制文件。相比之下,分布式表示通过表示学习技术学习得到。这种学习到的表示是一个具有选择维度的实值向量,通常称为嵌入。嵌入捕捉了代码中的复杂关系,而这些关系可能无法通过手工制作的特征轻松捕捉到。
以往工作的局限性。二进制相似性领域已经取得了很多进展:近期的研究表明,基于现代分类技术的机器学习方法可能优于长期存在的工业防病毒系统。然而,在现有的二进制相似性工具中,我们认为在适用性、有效性和可用性方面存在一些局限性:(1)架构特定性:许多依赖汇编代码进行二进制相似性分析的方法是针对特定架构定制的。因此,这些模型在针对新架构的二进制文件时难以推广,限制了它们在跨架构分析中的精确度。(2)结构上下文的丧失:现有方法通常无法捕捉二进制文件控制流图(CFG)中的形状和结构关系,原因在于它们依赖于指令级别的表示,或是图方法在处理包含数千个基本块的大型CFG时的局限性。这种上下文的丧失影响了基础方法的准确性和可推广性。(3)杂乱的中间表示(IR):虽然中间表示旨在保持架构中立,但在针对不同架构和编译设置编译的二进制文件之间往往存在显著差异。反汇编工具通过增加冗余的指令和内存/寄存器访问,进一步加剧了这一问题,从而使得中间表示变得杂乱,模糊了功能等价性。(4)特定应用:学习成对相似度分数的方法通常只适用于比较一对二进制文件,这限制了它们在大规模二进制库中进行搜索的适用性。(5)可扩展性:现代技术,尤其是那些利用大型语言模型(LLM)的方法,面临可扩展性挑战。这些方法在训练(例如在GPU集群上训练数周)和推理过程中通常需要大量的计算资源,限制了它们的可用性,使其在时间敏感或大规模应用中变得不切实际。
VexIR2Vec。为了应对这些局限性,我们提出了VexIR2Vec,一种将二进制函数表示为分布式多维向量的嵌入方法。VexIR2Vec结合了五个特性,按我们所知,这些特性的结合使用是创新的:(1)架构中立性:VexIR2Vec对二进制文件的嵌入是从VEX-IR中提取的,而VEX-IR是一种架构中立的中间表示。因此,VexIR2Vec可以比较针对不同目标编译的二进制文件,而无需专门化(第2.1节)。(2)基于路径的编码:VexIR2Vec通过分析通过随机游走从控制流图(CFG)中衍生的基本块序列或窥视,来编码函数的结构特性。这种方法强调频繁连接和嵌套的基本块(第4.1节)。(3)规范化变换:VexIR2Vec通过使用编译器优化启发的重写规则,对窥视进行规范化变换。这些变换通过移除无关的指令和其他语法细节,同时保留重要语义,从而清理了中间表示。我们在VEX-IR上实现了这些规范化,作为一个名为VEX-IR规范化引擎(VexINE)的库(第4.3节)。(4)应用独立性:VexIR2Vec可以适应不同的任务,如差异比较或搜索。为此,我们设计了VexNet,一个Siamese网络,通过微调词汇表,将函数表示为一个应用独立的嵌入空间中的点,在该空间中,相似的函数彼此接近,而不相似的函数则远离,从而增强了其适用性(第6节)。(5)可扩展嵌入:VexIR2Vec的词汇表是通过指令操作码和类型学习得到的,采用简单的前馈网络进行表示学习技术,避免了其他方法中常见的词汇表外(OOV)问题。这种学习方法使得VexIR2Vec具有高度的可扩展性(第5节)。
关键思想。VexIR2Vec设计的直觉是,通过将两个相似的函数分解为足够多的peephole,随后进行规范化处理,这些peephole中的许多可能会具有相似的语义,并且遮蔽最小化。虽然规范化减少了反汇编器引起的杂乱,但底层的训练过程负责处理识别功能相似性的关键任务,从而使模型能够处理更清洁的输入,进行更准确的分析。将这一直觉实现为一个实际工具能够在精度和可扩展性方面克服以往工作的局限性。
研究动机
VEX-IR
二进制相似性分析的过程可以选择性地将汇编代码提升到某种更高层次的程序表示,如抽象语法树(AST)或中间表示(IR)。一旦二进制文件转换为所需的表示形式,就可以使用不同的图匹配/哈希匹配技术或机器学习方法来解决潜在的二进制相似性问题。
本文中用于解决二进制相似性问题的程序表示是VEX-IR,这是Valgrind和angr使用的中间表示(IR)。VEX-IR源自汇编代码;然而,它抽象了许多架构特定的细节,如寄存器名称。指令不使用机器寄存器,而是引用变量名称,这些变量名称采用静态单赋值(SSA)形式。因此,每个变量名称只有一个定义位置。VEX-IR还有一个高层特征:它是类型化的。然而,VEX-IR也保留了一些机器特定的信息,如副作用、指针大小、指令标志和调用约定等。如我们在第2.3节中所解释的,我们选择使用VEX-IR,因为这种格式架构中立且开源,因此适用于跨架构的二进制相似性分析。图1展示了VEX-IR与本文介绍的不同二进制差异比较技术阶段的关系。
上图中(b)和(c)显示了两个VEX-IR程序。这两个程序实现了相同的三条操作序列。它们的不同之处在于它们是由不同的汇编代码生成的。图2(a)和(d)中的每一行代码表示一个指令,名称如t26代表变量。VEX-IR程序可以使用无限制的这些名称。事实上,静态单赋值特性确保每个变量都被新名称定义。相比之下,内存地址和寄存器不遵循这一特性。因此,如图2(a)中的寄存器r184可以被多次修改。同样,内存地址如M1或M2也是如此。
BCSD挑战
编译器和优化级别。众所周知,不同的编译器会为相同的源代码生成不同的汇编代码和二进制文件。这种差异是由多个因素引起的,包括编译器在不同编译阶段使用的底层优化和内部成本模型。此外,即使是由相同编译器从相同源代码生成的二进制文件,也可能存在显著差异,这取决于代码生成过程中使用的优化级别。这个观察结果促使了恶意软件多样化中的关键技术之一:使用不同的优化序列重新编译。因此,二进制差异比较技术能够抵抗编译器优化的能力是非常值得追求的,Ren等人表示:“由于编译器优化是导致二进制代码在语法上差异的最常见来源,测试其抵抗不同编译器优化设置所引起的变化,已成为大多数二进制差异比较方法的标准评估步骤。”
结构差异。程序的控制流图(CFG)决定了执行可以通过程序流动的可能路径。许多二进制差异比较工具依赖于CFG的结构特性来比较程序。这些工具首先为二进制文件中的每个函数构建一个控制流图,然后使用图同构算法或机器学习算法和模型来比较它们,识别相似或相同的子图。然而,这些算法依赖于结构特性,而这些特性可能会受到二进制代码生成方式的显著影响。特别是,像循环展开、函数内联和尾调用消除这样的优化会对程序的控制流图产生重大变化。
指令级差异。许多二进制差异比较工具通过对代码序列进行哈希处理来比较二进制代码片段。然而,正如前面提到的结构特性一样,构成函数的指令也会根据代码生成方式的不同而有所变化。这些差异源于编译器在执行指令选择和调度时使用的启发式方法。在这方面,编译器会根据架构的不同以不同方式重新排序指令,以最小化流水线停顿并提高执行效率。此外,在像x86这样的架构中,相同的操作通常可以通过多种方式表达。这些差异可能非常显著,正如示例2.3所示。
跨架构二进制相似性面临的挑战源于汇编代码的语法差异和由此产生的控制流图(CFG)结构差异。即使这些针对特定架构的汇编代码被提升到一个共同的中间表示(IR),匹配它们的问题仍然很困难,因为用不同汇编代码编写的可执行文件在转换为共同的IR后,很难产生相同的结构和指令。有许多因素可以解释这些差异:(1)为不同架构编译的二进制文件可能在内存布局上有所不同,包括数据结构的组织和函数在内存中的分配;(2)不同架构可能使用不同的字节顺序(大小端)来存储多字节数据;(3)系统调用和API函数在不同架构之间可能有所不同;(4)二进制文件可能会动态链接到不同版本的系统库;(5)不同架构的编译器可能会以不同的方式优化代码。
指令规范化
我们工作的目标是学习将二进制中的函数表示为嵌入,使得语义相似的函数映射到在多维欧几里得空间中彼此接近的向量上。为了实现这个目标,我们旨在从一种表示中提取程序嵌入,该表示具有以下特性:
形状敏感性:运行频率较高的指令应赋予更高的权重。换句话说,位于汇编代码中的交汇点(分支的后支配点)或控制流图(CFG)中循环部分的指令应对嵌入产生更大的影响。
可规范化:应尽可能丢弃冗余指令。在这方面,指令应该是可规范化的,这意味着在构建程序的向量表示之前,这些冗余应当被修剪掉。
流不敏感性:最近的研究发现,将二进制文件映射为向量的嵌入应该对流不敏感,以抵抗指令顺序变化带来的影响。
为了实现这三个目标,我们的方法基于基本块的序列,称之为窥视,其定义如下所示:
研究内容

上图展示了我们设计的管道概述,旨在将程序的二进制表示转换为固定大小的向量。我们的方法包括三个主要阶段:首先,将函数分解为一组规范化的窥视(第4节);接着,预训练词汇表,将这些窥视嵌入为向量(第5节);最后,微调生成的向量,以应对下游任务,如二进制差异比较和搜索(第6节)。
第一阶段:从二进制到规范化窥视。在第一阶段,我们从使用不同编译器配置生成的二进制文件中提取VEX-IR。然后,将函数分解为一组从相应控制流图(CFG)中派生的窥视,具体内容见第4.1节。生成的IR(VEX-IR)通过VexINE进行规范化。该引擎应用了受传统编译器优化启发的变换,有效地规范化了每个窥视的VEX-IR表示。在调用这些处理之前,我们对输入的IR进行规范化,以抽象掉解决二进制相似性问题不必要的细节。第4.2节和第4.3节详细阐述了规范化引擎、相关的规范化过程以及它在清理和简化IR中的作用。
第二阶段:从窥视到嵌入。在第二阶段,我们深入探讨预训练过程,其中我们在没有监督的情况下,从一组二进制文件中学习VEX-IR的词汇表。这个词汇表有助于将IR中的实体,如操作码、类型和参数,映射到n维向量表示。学习词汇的过程是在离线方式下进行的,并且只进行一次。随后,我们使用学习到的词汇表为窥视和函数推导出n维表示。
第三阶段:微调嵌入以应对下游任务。在第三阶段,我们训练VexNet,一个简单的前馈型Siamese网络,具有全局注意力机制,学习将生成的函数实体级嵌入结合起来,以解决二进制相似性问题。模型的目标是将函数表示在欧几里得空间中,将相似的函数聚集在一起,同时将不相似的函数分开。训练完成后,模型生成的表示可以应用于各种下游任务,如二进制差异比较和搜索。