Slither 调用图漏了边:核对printer输出、重载函数与分析范围
链小知 · 进阶 · 核验 · 依官方文档整理
从本人已有call-graph DOT/JSON找caller、callee与覆盖边界,区分静态图、控制流图和真实执行。
开始前准备
- 准备同一源码commit的原--print参数/日志、已有callgraph DOT或printer JSON及编译范围;不运行工具或安装图形程序。
- 按Slither0.11.6固定call_graph.py定位格式;旧Wiki输出文件名只作历史例,不保证当前版本相同。
1. 确认是call-graph并绑定本次编译范围
核原--print包含call-graph,DOT文件来自同一项目/commit/Slither版本。cfg是单函数控制流图,inheritance-graph是继承图,不能只看到箭头就称跨函数调用。
固定0.11.6 printer模式不运行detectors;缺漏洞列表不意味着没发现漏洞。记录编译单元/目标/依赖是否取得,日志显示No contract was analyzed或产物来源不明时停在输出待核。
检查结果:图种类、版本与编译范围明确,未将导图称为安全扫描。
2. 找到全体图与具体合约图的真正来源
0.11.6源代码通常写all_contracts.call-graph.dot或带目标前缀的全体文件,还为contracts_derived写具体ContractName.call-graph.dot。核原输出日志的文件名,不从旧Wiki的file.sol.dot示例推定本轮命名。
0.11.6固定源码把file element的文件字典放在name中,按name.filename/name.content核对DOT正文;不要直接套Wiki或其它版本的type_specific_fields外壳。先看原版本和实际对象,它不是detector的check/impact。只有文件名、无文件或content时标未取得图,不重新写文件或执行Graphviz补假结果。
检查结果:全体/合约图与原日志或file element匹配,缺正文明确。
3. 按节点签名区分重载与顶层函数
查看DOT节点ID和label:0.11.6函数节点用contract.id+full_name,签名包含参数以区别同名重载;顶层函数有toplevel_前缀和full_name,[Solidity]为另一组。
同名foo不同参数或不同contract.id不能合并。全体图以canonical_name去重,具体derived图范围更小;把节点与原源码合约/签名配对,没有对应文件就保留目标未知。
检查结果:每个待核节点有合约/完整签名和图范围,同名节点未混合。
4. 从caller箭头追到callee并回看源码
DOT _edge(from_node,to_node)表达caller→callee。沿已有内部调用或high-level调用看被调用函数,回到同commit源码的调用点核参数/条件;只读图和文件,不执行调用。
调用图显示静态调用关系,没有交易次数、金额、真实账户或成功状态。路径连接不等运行时必然可达,图中有外部调用也不等资金一定已经离开。
检查结果:箭头方向与实际调用点配对,关系没有被写成真实执行回执。
5. 把缺边分为图范围与调用类别
源码处理internal_calls及high_level_calls,external_contract不在当前all_contracts就跳过;顶层函数还跳过高层contract处理。低层call/delegatecall或动态目标不能从本图缺边证明不存在。
先比全体图与单derived图、已编译依赖/源码快照,再回看原调用表达式。没有源码或编译范围时列待核,不凭一张截图宣称没有代理委托、外部资产操作或重入机会。
检查结果:漏边解释绑定具体图范围/调用类型,未知外部目标与低层调用保留。
6. 形成静态关系表与后续核验缺口
输出caller完整签名、callee身份、内部/高层/低层或未识别类别、源码位置、图是否有边和缺证原因。现有callgraph只供理解代码,完整安全评估仍需独立核权限、数据依赖及运行条件。
不同Slither/compiler版本、未编译文件或printer选择变化会影响图;本篇不安装xdot/Graphviz、运行编译/分析或调用业务网络。原图为空/出错只能标静态关系未取得,不能写成零风险。
检查结果:静态关系与范围可复查,未证明的执行/安全部分明确。
怎样确认完成
- 形成节点/边/源码/编译范围对照与无法由图证明的事项。
- 仅解读已有文件,没有工具执行、图形程序安装或真实调用;未验项目安全。
常见错误与边界
- 旧Wiki示例文件名不等0.11.6固定源码命名,缺文件名/正文不宜按空图解释。
- 重载、不同合约与顶层函数不可仅按简短名字合并。
- 缺边不证明没有low-level、动态外部目标或真实资金操作。