Page 214 - 《软件学报》2026年第3期
P. 214

田朝 等: CoDefense: 面向对抗性攻击的多粒度代码归一化防御方法                                           1177


                 的同时, 并未对模型的原始性能及代码嵌入分布造成太大负面影响. 在此步骤中, CoDefense 通过对给定代码实施
                 变量名归一化处理, 为后续的代码归一化处理奠定了基础.
                  3.3.2    死代码消除
                    根据现有研究, Brown      等人  [32] 将死代码称为  Lava Flow, 解释为在动态变化的代码中未使用的代码片段.
                 Mantyla 等人  [33] 将死代码定义为曾经使用过但目前不再使用的代码片段. Wake              [34] 将死代码定义为未使用的变量、
                 参数、方法或类等. Martin    [35] 将死代码定义为从未执行的代码片段, 例如含有不可能发生条件的                    if 语句的主体或
                 从未调用的方法等. 尽管先前的研究提供的定义略有不同, 但死代码是不必要的, 消除冗余的死代码不会影响代码
                 的运行结果. 本文中, 我们引用软件工程对“死代码”的定义来指代未使用或无法访问的代码片段                             [36] .
                    如表  1  所示, 我们总结了最近几年主要会议和期刊的对抗性攻击方法中常见的死代码插入规则                             [20,30,37–46] , 并
                 据此设计了    6  类死代码消除规则      (共计  19  条规则). 具体来说, 我们系统地考虑了所有常见的代码结构, 即循环结
                 构  (规则  1)、分支结构   (规则  2) 和顺序结构   (规则  3–6). 表  1  中详细解释了这  6  类死代码消除规则, 并附有示例说
                 明. 对于每类规则, 它可能包括若干条具体规则, 例如             Loop d 包含  while 和  for 语句的多种情况. 总的来说, CoDefense
                                                             1
                 针对  6  类变换制定了    19  条具体规则. 请注意, 并非所有死代码消除规则都适用于所有编程语言, 例如, Statement d3
                 中的空语句“;;;;”不被 Python 支持. 限于篇幅, 我们将所有具体规则的详细信息放在本文的项目主页上. 基于这些
                 死代码消除规则, CoDefense     利用正则匹配消除给定代码中的死代码片段, 并将其作为后续代码归一化过程的
                 输入.

                                            表 1 CoDefense 的死代码消除规则的描述

                         ID      死代码消除规则                   描述                         例子
                                                                           while (false) {Body2;}
                          1          Loop d1    消除无法访问或主体为空的循环语句
                                                                           while (condition){}
                                                                           if (0) {Body2;}
                          2         Branch d2   消除无法访问或主体为空的分支语句
                                                                           if (condition) {} else{}
                                                                           ;;;;
                          3        Statement d3          消除空语句
                                                                           {{}{}}{};
                          4         Assert d4           消除恒真断言             assertTrue(true);
                                                                           assertTrue(1>0);
                                                                           System.out.print("");
                          5          Print d5      消除无意义输出或打印语句
                                                                           System.out.println("0000");
                                                                           int a;
                          6         Unused d6          未使用的变量或类            boolean b;
                                                                           注: a和b在之后的代码中未被使用

                  3.3.3    代码结构归一化
                    CoDefense 通过对代码输入应用保留语义的代码结构转换, 进一步进行代码结构归一化处理. 受到基于代码
                 结构转换的对抗性攻击研究和代码重构研究的启发                  [15,28,38,46–57] , 我们在  CoDefense 中设计了  13  类代码结构归一化
                 规则  (共计  51  条规则). 具体来说, 我们系统地考虑了所有常见的代码结构, 即循环结构                  (规则  1)、分支结构    (规则
                 2–4) 和顺序结构   (规则  5–13). 表  2  中详细解释了这  13  个类别, 并附有示例说明. 对于每一类转换规则, 可能包括
                 若干条具体规则. 例如, Branch s 包含了||的转换和&&的转换. 总的来说, CoDefense 针对            13  类转换制定了   51  条具
                                         4
                 体规则. 同样, 并非所有代码结构归一化规则都适用于所有编程语言. 例如, 规则                     In/Decrement s1 中的++的转换和−−
                                                                                         0
                 的转换不适用于      Python. 此外, 在规则  Constant s 中, 新定义的变量不能与代码中已有的变量名相同, 且应该按照
                                                      9
                 变量名归一化的方式进行命名, 否则可能会导致语法错误或改变原始语义. 限于篇幅, 我们将所有具体规则的实现
                 放在本项目开源主页上.
                    接下来说明如何引导这些代码结构转换规则来进行代码结构归一化. 由于每个规则涉及两种或多种代码结
                 构, 需要设计一种评价指标来自动衡量转换前后的代码质量, 以引导代码结构归一化的过程. 受到代码重构相关工
                 作的启发   [58–60] , 本文选择代码质量指标作为评价指标, 其被广泛用于识别设计缺陷                 (例如代码异味) 以及作为重构
   209   210   211   212   213   214   215   216   217   218   219