Page 212 - 《软件学报》2026年第3期
P. 212
田朝 等: CoDefense: 面向对抗性攻击的多粒度代码归一化防御方法 1175
i+=b;}以及在第 11 行插入死代码 if (false) {a+=n;}生成了对抗性样本, 该对抗性样本成功地误导代码模型的预测
结果.
对于基于代码结构转换的对抗性攻击方法, 它们首先设计一系列等价的代码结构转换规则, 然后通过搜索策
略确定代码转换位置和转换规则 [16] . 等价代码结构转换不会产生语法错误, 也不会影响代码语义, 通过迭代攻击
过程最终生成攻击成功的对抗性样本. 以图 1 中的 AdvCode-3 为例, 对抗性攻击方法通过把原始代码的第 3 行和
第 4 行的 for 循环语句转换为等价的 while 循环语句, 并将第 3 行的 i+=1 和第 4 行的 j+=1 分别转换为 i=i+1 和
j=j+1 得到了对抗性样本, 其成功地误导了代码模型的预测结果.
原始代码
多粒度对抗性攻击
AdvCode-1 AdvCode-2 AdvCode-3
变量名替换 死代码插入 代码结构转换
图 1 一个简化的动机示例
通过上述例子, 可以发现对抗性样本涉及了 3 种粒度的对抗性攻击方法 (即变量名替换 [18] 、死代码插入 [20]
和代码结构转换 [16] ), 不同粒度的对抗性样本有着显著的区别. 目前, 最常见的对抗性训练方法通常只针对特定粒
度生成对抗性样本 [19,21] , 然后通过数据增强的方式将其添加到原始训练集中, 对模型进行对抗性训练. 然而, 这种
方法无法覆盖所有粒度的对抗性样本, 因此不能有效地防御不同粒度的对抗性攻击. 这促使我们设计一种能够针
对 3 种粒度的对抗性攻击进行有效防御的方法. 此外, 基于代码转换规则生成对抗性样本时, 攻击空间非常巨大.
以基于变量名替换的对抗性攻击为例, 所有有效的变量名都可以作为候选变量名, 导致潜在的对抗性样本数量极
其庞大. 这意味着即使是具有相同粒度的对抗性攻击方法, 不同的攻击策略也会产生不同的对抗性样本. 这种多样
性使得对抗性训练无法全面涵盖所有潜在的攻击, 面对未知或未覆盖的同粒度对抗性样本时仍然脆弱 [19] . 这促使
我们设计一种对抗性防御方法, 能够有效防御不同策略的所有对抗性攻击.
基于上述发现, 设计了一种多粒度代码归一化策略, 能够将训练阶段的原始训练集和推理过程的原始代码输
入进行归一化预处理, 以避免潜在的对抗性样本直接输入到代码模型, 进而从根本上提高代码模型的对抗性防御
能力. 接下来, 本文将详细介绍该方法.
3.2 概 述
在本文中, 我们提出了一种对抗性防御方法 (称为 CoDefense), 其能够更有效地防御多粒度、不同策略的对抗
性攻击, 并显著提升时间效率. 图 2 展示了 CoDefense 的方法流程图. 代码归一化策略由 3 个主要部分组成: 变量
名归一化、死代码消除和代码结构归一化. 不同于已有的对抗性训练策略, CoDefense 的核心思想是通过多粒度
代码归一化, 将 (训练阶段的) 原始训练集和 (推理阶段的) 原始代码输入进行预处理, 以避免潜在的对抗性样本直
接输入到代码模型, 因此能够有效防御不同粒度和策略的对抗性攻击. 具体来说, CoDefense 的部署包括两个阶段:

