Page 393 - 《软件学报》2025年第12期
P. 393
5774 软件学报 2025 年第 36 卷第 12 期
Holder 结构体类型的成员变量进行修改. 由于 mapping 中存储的是结构体地址, 因此修改 acc 会改变状态变量
Acc 中的数值. 由于第 14 行目标语句与第 13 行存在控制依赖, 且第 13 行与第 8 和 9 行赋值存在数据依赖, 因此
第 8 和 9 行的赋值语句需要被符号化执行, 以更准确地判断目标语句的可达性. 然而, 结构体在符号执行分析的过
程中所需要的测试资源较多, 需要对结构体中各个成员变量进行符号化表示, 导致分析结构体相关的赋值操作需
要花费较多的时间. 需要注意的是, 结合 RQ1 和 RQ2 的分析可知, 相较于非目标制导的 Mythril, 启用了目标依赖
语句分析的 Smart-Target 仍能在安全漏洞检测和复现场景中分别减少 60.76% 和 92.16% 的时间开销.
表 8 Smart-Target 执行的目标依赖语句数量统计
漏洞类型 直接赋值状态变量 结构体赋值状态变量
时间操作 8 0
权限控制 11 0
数值相关 73 0
重入 77 35
未检查低级调用 290 29
总计 459 64
1 struct Holder { //结构体声明,定义用户相关信息
2 uint256 unlockTime;
3 uint256 balance;
4 }
5 mapping(address => Holder) public Acc; //状态变量,记录用户相关信息
6 function Put(uint256 _unlockTime) public payable { //用户存储以太币的函数
7 var acc = Acc[msg.sender]; //从 mapping 中取出用户信息
8 acc.balance += msg.value; //记录用户发送的以太币金额
9 acc.unlockTime = _unlockTime > now ? _unlockTime : now; //记录解锁时间
10 }
11 function Collect(uint256 _am) public payable {
12 var acc = Acc[msg.sender];
13 if (acc.balance >= MinSum && acc.balance >= _am && now > acc.unlockTime) {
14 if (msg.sender.call.value(_am)()) { //重入漏洞
15 acc.balance -= _am;
16 }
17 }
18 }
图 9 通过结构体赋值状态变量的以太坊智能合约片段
综上所述, 我们对 RQ3 的回答是: 目标依赖语句能够有效提升 Smart-Target 的安全漏洞检测能力, 多检测到
22.02% 的安全漏洞; 在时间开销上, 当代码中存在较多结构体状态变量赋值操作时, 启用目标依赖语句分析会增
加较多的符号执行分析时间.
6 讨 论
6.1 泛化性分析
用于开展 Smart-Target 的实验评估需要数据集提供行级别的漏洞语句信息, 即漏洞语句所在的代码行. 而
Ren 等人 [21] 、So 等人 [41] 以及 Luo 等人 [45] 的数据集仅对漏洞位置进行了文件级别的标注, 无法直接用于评估
Smart-Target 的有效性和泛用性. 为了进一步评估本文所提方法的泛用性, 我们参考并简化了 Zhang 等人 [46] 的测
试框架, 在 Luo 等人 [45] 经过人工标注的 SCVHunter 数据集 (https://doi.org/10.6084/m9.figshare.24566893.v1) 基础
上, 使用 GPT-4o 分析智能合约源代码, 并根据 GPT-4o 的回答标注疑似漏洞语句.
具体来讲, SCVHunter 数据集中包含重入、区块信息依赖、嵌套调用以及事务状态依赖 4 种类型漏洞. 根据
Luo 等人对上述漏洞的定义和描述, 区块信息依赖和事务状态依赖漏洞与 SB Curated 数据集中弱随机性以及权限
控制漏洞的定义相似, 嵌套调用漏洞指在无限制循环中执行 CALL 指令, 导致 gas 不足引发异常, 进而影响合约正

