1.理解数据依赖性的概念。 2.在源代码分析时,可以从用户的输入跟踪受影响的合约变量。
通过本文可以学习到: 1.理解数据依赖性的概念。 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(依赖传递性)
# 定义了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_INPUT
key对应的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对应的依赖中,那么就返回这两个变量存在依赖关系。
那么这个DATA_DEPENDENCY
的内容是怎么来的呢?
代码所在的目录:/lib/python3.8/site-packages/slither/analyses/data_...
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!