Page 85 - 《软件学报》2025年第7期
P. 85

3006                                                       软件学报  2025  年第  36  卷第  7  期


                 1.2   函数内联
                    函数内联技术是现代编译器优化策略中的重要组成部分, 其主要目标在于消除函数调用的开销, 同时为后续
                 的优化操作创造有利条件. 该技术的核心在于将函数调用点处的代码替换为被调用函数的代码体, 从而在运行时
                 避免了函数调用的间接跳转和参数传递等开销. 然而, 内联操作亦非毫无代价, 它可能导致目标代码体积增大, 进
                 而增加存储空间, 同时延长编译时间, 增加了编译过程的复杂性. 因此, 如何在提高运行效率与控制资源消耗之间
                 找到最佳平衡点, 成为了内联策略设计的关键所在                [13−19] .
                    在内联策略的制定与实施方面, GCC           和  LLVM  两大主流编译器展现出了不同的设计理念. GCC              采用了基于
                 优先级的内联机制, 通过对每个函数调用点的内联收益进行评估, 结合预设的成本阈值, 动态决定内联操作的执行
                 与否. 这一策略不仅考虑了内联带来的即时性能提升, 同时也兼顾了代码体积和编译时间的控制. 另一方面, GCC
                 针对小函数及单次调用函数等特殊情况, 提供了专门的内联优化选项, 进一步增强了其适应性与灵活性.
                    相对而言, LLVM    则采取了一种基于预测的内联方案. 通过分析函数的调用频率, LLVM                      将函数区分为热点
                 与冷点两类, 对热点函数采取积极的内联策略, 以期获得最大化的性能收益. 对于每个调用点, LLVM                            都会细致计
                 算内联的预期收益与成本, 只有当预期收益大于预期成本时, LLVM                   才会执行内联操作.

                 1.3   函数内联场景下的二进制相似性检测工作
                    函数内联技术的引入, 为二进制代码相似性分析带来了前所未有的挑战. 以往的研究, 诸如                                Bingo [20] 和
                 Asm2Vec [21] , 虽致力于解决函数内联环境下的二进制代码对比问题, 但其焦点主要集中在二进制到二进制的相似
                 度检测, 未能深入探讨函数内联对二进制到源代码相似性检测的影响. 这些研究虽然在一定程度上提升了二进制
                 代码层面的匹配精度, 却无法直接解决源代码级别的匹配挑战.
                    本文的前序工作      [12] 系统地评估了函数内联对二进制函数相似性分析的深远影响. 通过构建包含内联操作的
                 数据集, 揭示了在函数内联存在的情况下, 传统匹配方法面临的性能瓶颈. 其结果显示, 多数现有技术在检测内联
                 函数时, 匹配准确率显著下降, 性能损失高达             30%–40%. 然而, 本文的前序工作并未提出有效的解决方案, 这一难
                 题仍悬而未决, 成为当前二进制到源代码相似性检测领域亟待突破的关键点.
                    鉴于函数内联技术对二进制到源代码相似性检测带来的挑战, 本研究致力于探索一种全新的解决方案, 旨在
                 克服函数内联对匹配准确率的影响. 本文深入分析了函数内联的规律, 探究了其对二进制函数结构的改变, 以此为
                 基础, 设计了一系列针对性的解决方法.

                 2   “一对多”匹配问题

                    本节首先对“一对多”匹配问题给出定义, 然后以实例来分析函数内联场景下的二进制到源代码相似性匹配问
                 题, 最后介绍   O2NMatcher 针对上述问题所设计的方法流程.

                 2.1   问题定义
                    本文定义在函数内联场景下的二进制到源代码函数匹配目标如下: 给定一个发生内联的查询二进制函数                                   q  和
                 一组目标源代码函数集合         T, 函数内联下的二进制到源代码相似性检测旨在检索出源代码函数                      t, 其中源代码函数
                 t 通过内联其他源代码函数编译生成了二进制函数                q.
                    在普通场景下的代码搜索中, 对于提交查询的二进制函数, 仅需要检索到与二进制函数功能相同的源代码函
                 数即可. 然而, 在内联场景下的代码搜索中, 寻找被内联的源代码函数对于二进制到源代码相似性检测同样重要,
                 本文所提出的     O2NMatcher 方法也可寻找其他被内联的源函数.
                    本文将研究的查询函数范围定位在由              GCC  和  Clang  编译的  C/C++代码所生成的二进制函数, 目标函数则是
                 由上述   C/C++代码组成的源代码仓库. 二进制到源代码函数匹配的目标即为对于查询的二进制函数, 找到其对应
                 的源代码仓库中的源代码函数.

                 2.2   案例分析
                    图  2  展示了函数内联场景下“一对多”匹配问题的一个例子. 函数                dtls1_get_record  是项目  OpenSSL 1.0.1j 中的
   80   81   82   83   84   85   86   87   88   89   90