欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

区块链安全——以太坊智能合约静态分析

来源:本站整理 作者:佚名 时间:2019-01-10 TAG: 我要投稿
反编译代码的00058到00072行,对应的是汇编代码中tag_4标签内的代码。
反编译代码的00073到00085行,对应的是汇编代码中tag_5标签内的代码。0x73地址对应的指令是JUMPDEST,之后的指令会执行add函数中的所有代码。如果变量sellerBalance的值大于函数参数,接下来会执行JUMPI指令跳转到0x86地址处,否则顺序向下执行到0x85地址处。这里有个需要注意的地方,在汇编代码中此处显示invalid,但在反编译代码中,此处显示Missing opcode 0xfe。
反编译代码的00086到0008a行,对应的是汇编代码中tag_7标签内的代码。
0008b行对应的指令是STOP,执行到此处时整个流程结束。
2.4 总结
本章首先介绍了EVM的存储结构和以太坊中常用的汇编指令。之后逐行分析了智能合约编译后的汇编代码,最后反编译了智能合约的字节码,把反编译的代码和汇编代码做了对比分析。相信读完本章之后,大家基本上能够看懂智能合约的汇编代码和反编译后的代码。在下一章中,我们将介绍如何从智能合约的反编译代码中生成控制流图(control flow graph)。
 
第三章 从反编译代码构建控制流图
本章是智能合约静态分析的第三章,第二章中我们生成了反编译代码,本章我们将从这些反编译代码出发,一步一步的构建控制流图。
3.1 控制流图的概念
3.1.1 基本块(basic block)
基本块是一个最大化的指令序列,程序执行只能从这个序列的第一条指令进入,从这个序列的最后一条指令退出。
构建基本块的三个原则: 1. 遇到程序、子程序的第一条指令或语句,结束当前基本块,并将该语句作为一个新块的第一条语句。 2. 遇到跳转语句、分支语句、循环语句,将该语句作为当前块的最后一条语句,并结束当前块。 3. 遇到其他语句直接将其加入到当前基本块。
3.1.2 控制流图(control flow graph)
控制流图是以基本块为结点的有向图G=(N, E),其中N是结点集合,表示程序中的基本块;E是结点之间边的集合。如果从基本块P的出口转向基本块块Q,则从P到Q有一条有向边P->Q,表示从结点P到Q存在一条可执行路径,P为Q的前驱结点,Q为P的后继结点。也就代表在执行完结点P中的代码语句后,有可能顺序执行结点Q中的代码语句[2]。
3.2 构建基本块
控制流图是由基本块和基本块之间的边构成,所以构建基本块是控制流图的前提。接下来我们以反编译代码作为输入,分析如何构建基本块。
第二章中的反编译代码如下:
00000: PUSH1 0x80
00002: PUSH1 0x40
00004: MSTORE
00005: PUSH1 0x04
00007: CALLDATASIZE
00008: LT
00009: PUSH1 0x3e
0000b: JUMPI
0000c: PUSH4 0xffffffff
00011: PUSH29 0x0100000000000000000000000000000000000000000000000000000000
0002f: PUSH1 0x00
00031: CALLDATALOAD
00032: DIV
00033: AND
00034: PUSH4 0x1003e2d2
00039: DUP2
0003a: EQ
0003b: PUSH1 0x43
0003d: JUMPI
0003e: JUMPDEST
0003f: PUSH1 0x00
00041: DUP1
00042: REVERT
00043: JUMPDEST
00044: CALLVALUE
00045: DUP1
00046: ISZERO
00047: PUSH1 0x4e
00049: JUMPI
0004a: PUSH1 0x00
0004c: DUP1
0004d: REVERT
0004e: JUMPDEST
0004f: POP
00050: PUSH1 0x58
00052: PUSH1 0x04
00054: CALLDATALOAD
00055: PUSH1 0x73
00057: JUMP
00058: JUMPDEST
00059: PUSH1 0x40
0005b: DUP1
0005c: MLOAD
0005d: SWAP3
0005e: ISZERO
0005f: ISZERO
00060: DUP4
00061: MSTORE
00062: PUSH1 0x20
00064: DUP4
00065: ADD
00066: SWAP2
00067: SWAP1
00068: SWAP2
00069: MSTORE
0006a: DUP1
0006b: MLOAD
0006c: SWAP2
0006d: DUP3
0006e: SWAP1
0006f: SUB
00070: ADD
00071: SWAP1
00072: RETURN
00073: JUMPDEST
00074: PUSH1 0x00
00076: DUP1
00077: SLOAD
00078: DUP3
00079: ADD
0007a: DUP1
0007b: DUP3
0007c: SSTORE
0007d: DUP2
0007e: SWAP1
0007f: DUP4
00080: GT
00081: ISZERO
00082: PUSH1 0x86
00084: JUMPI
00085: Missing opcode 0xfe
00086: JUMPDEST
00087: SWAP2
00088: POP
00089: SWAP2
0008a: JUMP
0008b: STOP
我们从第一条指令开始分析构建基本块的过程。00000地址处的指令是程序的第一条指令,根据构建基本块的第一个原则,将其作为新的基本块的第一条指令;0000b地址处是一条跳转指令,根据构建基本块的第二个原则,将其作为新的基本块的最后一条指令。这样我们就把从地址00000到0000b的代码构建成一个基本块,为了之后方便描述,把这个基本块命名为基本块1。
接下来0000c地址处的指令,我们作为新的基本块的第一条指令。0003d地址处是一条跳转指令,根据构建基本块的第二个原则,将其作为新的基本块的最后一条指令。于是从地址0000c到0003d就构成了一个新的基本块,我们把这个基本块命名为基本块2。
以此类推,我们可以遵照构建基本块的三个原则构建起所有的基本块。构建完成后的基本块如下图所示:

基本块
图中的每一个矩形是一个基本块,矩形的右半部分是为了后续描述方便而对基本块的命名(当然你也可以命名成自己喜欢的名字)。矩形的左半部分是基本块所包含的指令的起始地址和结束地址。当所有的基本块都构建完成后,我们就把之前的反编译代码转化成了11个基本块。接下来我们将构建基本块之间的边。
3.3 构建基本块之间的边
简单来说,基本块之间的边就是基本块之间的跳转关系。以基本块1为例,其最后一条指令是条件跳转指令,如果条件成立就跳转到基本块3,否则就跳转到基本块2。所以基本块1就存在基本块1->基本块2和基本块1->基本块3两条边。基本块6的最后一条指令是跳转指令,该指令会直接跳转到基本块8,所以基本块6就存在基本块6->基本块8这一条边。

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载