要解決這個關卡,您只需向 Ethernaut 提供一個合約Solver,該合約 whatIsTheMeaningOfLife()
以正確的 32 位元組數字回應。
容易吧?嗯…有個問題。
求解器的程式碼必須非常小。真的很小。就像真的非常非常小:最多 10 bytes。
提示:也許是時候暫時離開 Solidity 編譯器的舒適感,並手動建立這個編譯器了 O_o。沒錯:原始 EVM bytes。
祝你好運!
這一題牽扯到比較多底層的知識,必須要透過 opcode 完成。
題目要求建造一個合約,會回傳 42
這個數字,而且程式碼要在 10 bytes 完成。要完成的方法就是自己寫 opcode;若透過寫 Solidity 的方式,在編譯的過程中,會把程式進入點、函式判斷都編譯進去 byte code 裡面,超過 10 bytes。
所以我們要自己寫一個合約,在部署的時候就會自動以 opcode 的方式寫入一個「回傳 42」的功能。
關於底層 EVM 可以參考
關於合約在部署時的流程可以參考
要實現「回傳 42」,會用到以下三個 opcode:
Opcode | Name | Description | Stack Input |
---|---|---|---|
60 | push | Place 1 byte item on stack | |
52 | mstore | Save word to memory | offset, value |
F3 | return | Halt execution returning output data | offset, size |
mstore(value, position)
,把 value
放到指定的位置,用於儲存題目指定的數字「42」:
return(offset, size)
,回傳指定的記憶體位置:
組合起來,達成「回傳42」的功能,長度剛好 10 bytes:
所以只要將這段 bytecode 寫入合約的 runtime 區域即可
在 constructor()
中透過 mstore(value, position)
寫入,再用 return(offset, size)
。攻擊如下: