从solc编译过程来理解solidity合约结构
广告位API接口通信错误,查看德得广告获取帮助
现在以一个最简单的代码来开始我们的逆向旅程,为了方便学习,所有的代码编译和分析都在http://remix.ethereum.org/# 上进行.默认IDE 选项是关闭代码优化(Enable Optimization)和使用0.4.25 版本的solidity 编译器编译.pragma solidity ^0.4.24;
contract test {
function a() {
uint a = 123;
}
}
在Remix 上输入上述代码,点击Start to Compile 对代码进行编译,可以在Details 按钮里面获取编译出来的结果.结果包含如下:
METADATA 编译器元数据,包含:编译器版本,编译器设置,源码信息等
BYTECODE 合约编译完整的字节码结果
ABI 应用程序接口,用于标识合约提供了哪些函数给外部调用
WEB3DEPLOY Web3js版合约部署代码
METADATAHASH 元数据哈希
GASESTIMATES 编译器计算函数调用需要消耗的Gas表
RUNTIME BYTECODE 合约运行时字节码
ASSEMBLY 字节码反汇编
读者们会注意到,编译结果里面有ByteCode 和Runtime Bytecode ,分别表示什么意思呢,在此先略过这个疑问,我们关注Runtime Bytecode 中返回的字节码.对代码结构分析和字节码分析的标注后所有代码如下:
000 PUSH1 80
002 PUSH1 40
004 MSTORE ; 把0x80 写到[0x40 ,0x40 + 0x20] 这块内存里面,因为内存是空的,这会创建新的内存
005 PUSH1 04
007 CALLDATASIZE ; 获取CALLDATA 的长度
008 LT ; LT 和PUSH1 0x4 对应,判断CALLDATA 的长度是否小于0x4
009 PUSH1 3f
011 JUMPI ; 如果小于0x4 就往下跳转到0x3F
012 PUSH1 00
014 CALLDATALOAD ; CALLDATALOAD 0x0 ,PUSH1 0x0 是给CALLDATALOAD 的参数,意思要获取CALLDATA 数据的偏移位置
015 PUSH29 0100000000000000000000000000000000000000000000000000000000
045 SWAP1
046 DIV ; DIV 和PUSH29 对应,意思是把上面的数据向左移28 字节,剩下4 字节是调用合约函数名的哈希
047 PUSH4 ffffffff
052 AND ; AND 和PUSH4 0xFFFFFFFF 对应,保留低位4 字节数据,高位去处
053 DUP1
054 PUSH4 0dbe671f ; 这个是合约有的函数名,经过sha3() 精简过的
059 EQ ; 判断传递过来的函数调用名是否相等
060 PUSH1 44
062 JUMPI ; 如果两值相等就往下跳转到0x44
063 JUMPDEST ; 空指令
064 PUSH1 00
066 DUP1
067 REVERT ; 没有匹配到相应的函数就撤销所有操作,Revert(0,0)
068 JUMPDEST
069 CALLVALUE ; 获取用户转帐数额
070 DUP1
071 ISZERO ; 如果用户转帐数额为0
072 PUSH1 4f
074 JUMPI ; 转帐数额不为0 则跳到0x4F,否则就退出
075 PUSH1 00
077 DUP1
078 REVERT ; 因为调用函数a() 是不需要附加转帐金额的,所以检测到带有附加金额的函数调用就退出,参考payable 关键字
079 JUMPDEST
080 POP
081 PUSH1 56
083 PUSH1 58
085 JUMP ; 跳转到地址88
086 JUMPDEST
087 STOP ; 停止执行
088 JUMPDEST 现在以一个最简单的代码来开始我们的逆向旅程,为了方便学习,所有的代码编译和分析都在http://remix.ethereum.org/# 上进行.默认IDE 选项是关闭代码优化(Enable Optimization)和使用0.4.25 版本的solidity 编译器编译.
pragma solidity ^0.4.24;
contract test {
function a() { www.wnhack.com
uint a = 123;
}
}
在Remix 上输入上述代码,点击Start to Compile 对代码进行编译,可以在Details 按钮里面获取编译出来的结果.结果包含如下:
www.wnhack.com
METADATA 编译器元数据,包含:编译器版本,编译器设置,源码信息等
BYTECODE 合约编译完整的字节码结果
ABI 应用程序接口,用于标识合约提供了哪些函数给外部调用
WEB3DEPLOY Web3js版合约部署代码
本文来自无奈人生安全网
METADATAHASH 元数据哈希
GASESTIMATES 编译器计算函数调用需要消耗的Gas表
RUNTIME BYTECODE 合约运行时字节码
ASSEMBLY 字节码反汇编
读者们会注意到,编译结果里面有ByteCode 和Runtime Bytecode ,分别表示什么意思呢,在此先略过这个疑问,我们关注Runtime Bytecode 中返回的字节码.对代码结构分析和字节码分析的标注后所有代码如下: copyright 无奈人生
000 PUSH1 80
002 PUSH1 40
004 MSTORE ; 把0x80 写到[0x40 ,0x40 + 0x20] 这块内存里面,因为内存是空的,这会创建新的内存
005 PUSH1 04 本文来自无奈人生安全网
007 CALLDATASIZE ; 获取CALLDATA 的长度
008 LT ; LT 和PUSH1 0x4 对应,判断CALLDATA 的长度是否小于0x4
009 PUSH1 3f
011 JUMPI ; 如果小于0x4 就往下跳转到0x3F copyright 无奈人生
012 PUSH1 00
014 CALLDATALOAD ; CALLDATALOAD 0x0 ,PUSH1 0x0 是给CALLDATALOAD 的参数,意思要获取CALLDATA 数据的偏移位置
015 PUSH29 0100000000000000000000000000000000000000000000000000000000
045 SWAP1
无奈人生安全网
046 DIV ; DIV 和PUSH29 对应,意思是把上面的数据向左移28 字节,剩下4 字节是调用合约函数名的哈希
047 PUSH4 ffffffff
052 AND ; AND 和PUSH4 0xFFFFFFFF 对应,保留低位4 字节数据,高位去处
053 DUP1
内容来自无奈安全网
054 PUSH4 0dbe671f ; 这个是合约有的函数名,经过sha3() 精简过的
059 EQ ; 判断传递过来的函数调用名是否相等
060 PUSH1 44
062 JUMPI ; 如果两值相等就往下跳转到0x44 本文来自无奈人生安全网
063 JUMPDEST ; 空指令
064 PUSH1 00
066 DUP1
067 REVERT ; 没有匹配到相应的函数就撤销所有操作,Revert(0,0)
内容来自无奈安全网
068 JUMPDEST
069 CALLVALUE ; 获取用户转帐数额
070 DUP1
071 ISZERO ; 如果用户转帐数额为0
copyright 无奈人生
072 PUSH1 4f
074 JUMPI ; 转帐数额不为0 则跳到0x4F,否则就退出
075 PUSH1 00
077 DUP1 本文来自无奈人生安全网
078 REVERT ; 因为调用函数a() 是不需要附加转帐金额的,所以检测到带有附加金额的函数调用就退出,参考payable 关键字
079 JUMPDEST
080 POP
081 PUSH1 56 copyright 无奈人生
083 PUSH1 58
085 JUMP ; 跳转到地址88
086 JUMPDEST
087 STOP ; 停止执行 www.wnhack.com
088 JUMPDEST。 (责任编辑:wnhack)
【声明】:无奈人生安全网(http://www.wnhack.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱472701013@qq.com,我们会在最短的时间内进行处理。