http://www.7klian.com

智能合约安详系列文章反汇编·上篇

智能合约安详系列文章反汇编·上篇

媒介

通过上一篇反编译文章的进修,我们对智能合于opcode的反编译有了基本的进修,对付初学者来说,要想纯熟运用还得多加操练。本篇我们来一块进修智能合约反汇编,同样利用的是Online Solidity Decompiler在线网站,智能合约反汇编对付初学者来说,较难领略,但对付智能合约代码来说,只要能读懂智能合约反汇编,就可以很是清晰的相识到合约的代码逻辑,对审计合约和CTF智能合约都有很是大的辅佐

反汇编内容

由于solidity智能合约的opcode颠末反汇编后,指令较多,我们本篇阐明简明要义,以一段简朴合约代码来阐明其反汇编后的指令内容

合约源码如下:

pragma?solidity?^0.4.24; ? ?contract?Tee?{ ????? ?????uint256?private?c; ? ?????function?a()?public?returns?(uint256)?{?self(2);?} ????? ?????function?b()?public?{?c++;?} ? ?????function?self(uint?n)?internal?returns?(uint256)?{ ????????? ?????????if?(n?<=?1)?{?return?1;?} ? ?????????return?n?*?self(n?-?1); ?????} ?}

合约陈设后生成的opcode:

0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630dbe671f14604e5780634df7e3d0146076575b600080fd5b348015605957600080fd5b506060608a565b6040518082815260200191505060405180910390f35b348015608157600080fd5b5060886098565b005b60006094600260ab565b5090565b6000808154809291906001019190505550565b600060018211151560be576001905060cd565b60c86001830360ab565b820290505b9190505600a165627a7a7230582003f585ad588850fbfba4e8d96684e2c3fa427daf013d4a0f8e78188d4d475ee80029

通过在线网站Online Solidity Decompiler反汇编后功效(runtime bytecode)如下:

智能合约和平系列文章反汇编·上篇

反汇编阐明

我们从第一部门指令label_0000开始

0000????60??PUSH1?0x80 ??0002????60??PUSH1?0x40 ??0004????52??MSTORE ??0005????60??PUSH1?0x04 ??0007????36??CALLDATASIZE ??0008????10??LT ??0009????60??PUSH1?0x49 ??000B????57??*JUMPI

push指令是将字节压入栈顶,push1-push32依次代表将1字节-32字节推压入栈顶,这里PUSH1 0x80和PUSH1 0x40暗示将0x80和0x40压入栈顶,故今朝栈的机关如下:

1:?0x40 ?0:?0x80

MSTORE指令暗示从栈中依次出栈两个值arg0和arg1,并把arg1存放在内存的arg0处。今朝来说栈中已无数据,这里将0x80存放在内存0x40处。

PUSH1 0x04将0x04压入栈中,CALLDATASIZE指令暗示获取msg.data挪用数据,今朝栈的机关如下:

1:?calldata ?0:?0x04

LT指令暗示将两个栈顶的值取出,假如先出栈的值小于后出栈的值则把1入栈,反之把0入栈。这里假如calldata挪用数据小于0x04字节,就将1入栈;假如calldata挪用数据大于便是0x04字节,就将0入栈。今朝栈的机关为:0: 0 或0: 1。

继承阐明,PUSH1 0x49指令将0x49压入栈顶,今朝栈的机关为:

1:0x49 ?0:?0?可能?1

下面一条指令JUMPI指令暗示从栈中依次出栈两个值arg0和arg1,假如arg1的值为真则跳转到arg0处,不然不跳转。假如arg1值为1,则指令会跳转到0x49处;假如arg1值为0,则会顺序执行下一条指令。详细执行进程如下:

智能合约和平系列文章反汇编·上篇

这里我们先来阐明顺序执行的内容label_000C,,指令如下

000C????60??PUSH1?0x00 ??000E????35??CALLDATALOAD ??000F????7C??PUSH29?0x0100000000000000000000000000000000000000000000000000000000 ??002D????90??SWAP1 ??002E????04??DIV ??002F????63??PUSH4?0xffffffff ??0034????16??AND ??0035????80??DUP1 ??0036????63??PUSH4?0x0dbe671f ??003B????14??EQ ??003C????60??PUSH1?0x4e ??003E????57??*JUMPI

今朝颠末上一步运算栈中机关为空,PUSH1 0x00指令将0压入栈中。CALLDATALOAD指令接管一个参数,该参数可以作为发往智能合约的calldata数据的索引,然后从该索引处再读取32字节数,由于前一个指令传入的索引值为0,所以这一步指令会弹出栈中的0,将calldata32字节压入栈中。PUSH29指令将29个字节压入栈中。今朝栈的机关如下:

1:0x0100000000000000000000000000000000000000000000000000000000 ?0:calldata值

SWAP1指令暗示将仓库顶部元素与之后的第一个元素举办互换,也就是0x0100000000000000000000000000000000000000000000000000000000和calldata值举办互换。接下来DIV指令暗示(栈中第一个元素 // 栈中第二个元素)取a//b的值,这里也就是calldata的32字节除29字节,由于除法的运算干系,这里举办除法运算后的字节为4位,预计各人也可以想到,这就是函数标识符4字节。那么今朝栈的机关如下:

0:函数标识符4字节

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。