Page 132 - 《软件学报》2026年第7期
P. 132

徐美秋 等: CAnalyzer: 面向  C/C++源代码的软件成分分析技术                                         2817


                                                              |A∩ B|
                                                      J(A,B) =                                        (1)
                                                              |A∪ B|
                    在聚类后的家族中, 如果        TPL X  复用了  TPL S, 则  TPL X  既包含一些公共函数, 也保留了独有的标志函数. 因
                 此, TPL X  的标志函数比例较高. 而      TPL S  由于被多个  TPL  复用, 包含了更多的公共函数, 标志函数比例较低. 由
                 此可见, 通常被复用的       TPL  标志函数比例较低. 基于这一假设, 我们将公共函数归属于标志函数比例较低的                        TPL
                 S. 为了量化  TPL  中标志函数的比例, 我们引入两个指标: FILF (function inverse library frequency) 和  DI (distinctness
                 index). FILF  是衡量一个函数在多个    TPL  中普遍性的统计量. 它基于逆文档频率 (IDF) 的概念, 其中, N            代表该类
                 中  TPL  总数, df(f) 代表函数  f 出现的频率. FILF  值越高, 表示该函数在少数几个        TPL  中出现, 因此具有更高的独
                 特性, 可视为标志函数.

                                                              (      )
                                                                 N
                                                   FILF( f) = log                                     (2)
                                                              1+df(f)
                    DI 是衡量一个    TPL  在特定家族中标志函数比例的量化指标. 它通过对               TPL  中所有函数的    FILF  值求和, 再除
                 以     TPL  中函数的总数计算得出. DI 值越高, 表示该     TPL  对公共函数的依赖越小, 标志函数比例越高.
                                                            Totals
                                                            ∑
                                                               FILF( f i )
                                                             i=1
                                                   DI(TPL) =                                          (3)
                                                              Totals
                    在同一“家族”内, 根据每个        TPL  的  DI 值升序排序, 较低的   DI 值通常对应更少的标志函数和更高的复用性.
                 因此, 基于被复用库中标志函数比例较低的原则, 我们将公共函数优先归属于                        DI 值较低的   TPL. 从排序列表中的
                 第  1  个  TPL  开始, 标记其所有函数为该    TPL  的标志函数. 如果下一个      TPL  中存在已被其他     TPL  标记的公共函数,
                 则将这些函数剔除. 该过程持续到遍历完所有              TPL  为止.
                  3.2   目标代码成分识别

                    为了更好地适应软件库粒度复用检测场景, 我们利用                  Ctags [30] 和  TLSH [31] 算法将目标代码表示为特征集合, 并
                 设计了一套多层次、多阈值的评估体系, 用于将目标代码特征与特征库中的                         TPL  进行相似性匹配. 仅当特定       TPL
                 同时满足三重阈值时, 才能确认其是目标代码的有效成分.
                    (1) 函数级评估. 设定函数级阈值        α, 通过计算目标代码中与特定         TPL  匹配的函数数量     (MFuncs) 占该  TPL  每
                 个版本平均函数数量       (AFuncs) 的比例, 初步筛选目标代码潜在复用的           TPL.

                                                        MFuncs
                                                               ⩾ α                                    (4)
                                                        AFuncs
                    (2) 文件级评估. 设定文件级阈值        β, 用于判断目标代码与特定        TPL  文件中匹配函数数量      (MFuncsFile) 占该文
                 件总函数数量     (TFuncsFile) 的比例是否达到预设阈值. 若该比例超过          β, 则认为目标代码实际复用了该文件.

                                                       MFuncsFile
                                                                ⩾ β                                   (5)
                                                       TFuncsFile
                    (3) 库级评估. 设定库级阈值      θ, 根据目标代码实际复用的        TPL  文件数量  (RFiles) 占该  TPL  总文件数量  (TFiles)
                 的比例, 综合评估目标代码对该         TPL  的整体复用程度. 若该比例超过         θ, 则最终确认目标代码复用了该         TPL.

                                                         RFiles
                                                              ⩾ θ                                     (6)
                                                         TFiles
                  3.3   TPL  依赖检测
                  3.3.1    TPL  成分模块划分
                    分析目标代码中的       TPL  依赖关系时, 我们关注的是       TPL  在引入后作为目标代码一部分的实际表现, 而非其原
                 生环境中的依赖关系. 为重新分析           TPL  之间的关联, 我们需要基于       SCA  结果将目标代码分解为不同的          TPL  模块.
                 如图  7(a) 所示, 成分识别已明确目标代码中引入的           TPL  及其与特定文件的复用关系. 接下来, 我们分析与              TPL  相
                 关的复用文件, 判定哪些文件属于特定            TPL, 并将其归入相应的       TPL  模块. 为此, 提出了   4  项标准, 用于判定文件
                 是否应归属于特定       TPL  模块.
   127   128   129   130   131   132   133   134   135   136   137