08.slither中数据依赖检测示例

  • 小驹
  • 更新于 2023-06-30 10:58
  • 阅读 1578

1.理解数据依赖性的概念。 2.在源代码分析时,可以从用户的输入跟踪受影响的合约变量。

通过本文可以学习到: 1.理解数据依赖性的概念。 2.在源代码分析时,可以从用户的输入跟踪受影响的合约变量。

1. 数据依赖性的重要性

数据依赖性可以用来回答类似这样问题:

  • 在一个源代码中,用户的输入参数,可以影响到哪些变量的变化?
  • 假设erc20合约中存在一个自定义的function func_A (uint user_input) public,那么黑客通过修改user_input的值,最终能否影响到合约的balance状态变量。

2.相关概念的定义

上下文的定义

数据依赖涉及到上下文的概念,上下文只能取函数或者合约,目前不支持其他的上下文类型。请一定记住,讨论数据依赖性必须在上下文中讨论,没有上下文讨论数据依赖性没有意义,而且上下文只能从函数或者合约这两者中选一个。

污染的定义

如果在一个上下文中,输入的参数能否影响到某变量的值,那么我们就说这个变量是否可以被污染。

数据依赖的定义

数据依赖性是为了了解给定变量的值是否受另一个变量值的影响。

对这些定义的理解

由于智能合约是基于状态机的架构,因此数据依赖的结果取决于分析的上下文(函数/合约),在不同的分析上下文中,数据依赖的结果是不同。考虑以下示例:

contract MyContract{
    uint a = 0;
    uint b = 0;

    function setA(uint input_a) public{
        a = input_a;
    }

    function setB() public{
        b = a;
    }

}

在这个例子中

  • 在setA的上下文中

    a 依赖与input_a

  • 在setB的上下文中

    b 依赖与 a

  • 在合约的上下文中

    a 依赖与input_a

    b 依赖与a和input_a(依赖传递性)

3. 实现原理

依赖数据保存的位置

# 定义了6个key,用来存放数据依赖。KEY_INPUT和KEY_INPUT_SSA用来存放用户输入的变量。

KEY_SSA = "DATA_DEPENDENCY_SSA"
KEY_NON_SSA = "DATA_DEPENDENCY"

# Only for unprotected functions
KEY_SSA_UNPROTECTED = "DATA_DEPENDENCY_SSA_UNPROTECTED"
KEY_NON_SSA_UNPROTECTED = "DATA_DEPENDENCY_UNPROTECTED"

KEY_INPUT = "DATA_DEPENDENCY_INPUT"
KEY_INPUT_SSA = "DATA_DEPENDENCY_INPUT_SSA"

在源代码编译的时候,会对每个函数或者合约生成一个context对象,这个对象下面的compilation_unit.context是一个字典对象,DATA_DEPENDENCY_INPUTkey对应的set就为所有的该上下文对象的数据依赖的输入。如果在这个上下文中,要判断A变量是否可以被污染,那么污染的源头就是compilation_unit.context[DATA_DEPENDENCY_INPUT]

依赖数据怎么生成的

compute_dependency_contract 函数中,如果函数是["public", "external"],将函数的参数就保存到输入变量的字典中。

if function.visibility in ["public", "external"]:
    [compilation_unit.context[KEY_INPUT].add(p) for p in function.parameters]
  [compilation_unit.context[KEY_INPUT_SSA].add(p) for p in function.parameters_ssa]

在这个函数中遍历所有的function

compute_dependency_function(function)函数中,会遍历函数中的所有node,遍历每个node中的ir,如果ir为OperationWithLValue类型,通过ir.read 读取到该ir读取的变量的名字,将满足这种条件的变量保存到context[DATA_DEPENDENCY]中。

🎉 关键的数据结构 ir.read 保存了ir中读取的变量。通过这个成员变量就可以得到上下文中的读取的变量(ir读取的变量有可能是常数Constant类型,在保存到字典时不需要常数类型)。

对于 SSA类型的变量(如LocalIRVariable,StateIRVariable,TemporaryVariableSSA,ReferenceVariableSSA,TupleVariableSSA),存在一个non_ssa_version属性,可以返回该SSA变量对应的非SSA的变量

依赖数据怎么使用

context对象中有个context变量,key为DATA_DEPENDENCY的表明了所有变量的依赖关系,通过

return variable in context_dict[KEY_NON_SSA] and source in context_dict[KEY_NON_SSA][variable]

说明variable在这个上下文中,并且source在variable对应的依赖中,那么就返回这两个变量存在依赖关系。

image.png

那么这个DATA_DEPENDENCY 的内容是怎么来的呢?

4.常用函数

代码所在的目录:/lib/python3.8/site-packages/slither/analyses/data_...

剩余50%的内容订阅专栏后可查看

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
小驹
小驹
0xcD46...3461
weixin: xiaoju521区块链安全分析,欢迎私信沟通交流