
著者 Ravikiran Betha
参考文献 HEIMDALL RS
快適な移動手段としてクルマに乗る人もいれば、何に乗るかに情熱を傾ける人もいる。また、運転することに情熱を傾ける人もいる。彼らは自分が運転しているマシンからどれだけ搾り取ったかで自分の技量を測る。
だからこそF1では、ドライバー、マシン、エンジニアリングチームが一緒に時間をかけてお互いの長所と限界を理解し、一緒に引き出せる力を最大限に引き出そうとしているのかもしれない。
最近、EVMとバイトコードにまつわる古いCTFをチェックし始めたんだけど、正直なところ、何から始めたらいいのかわからなかった。ドライバーは、スキルの本格的なアップスケーリングが必要だと感じた。この追求のために、いくつかの書き込みを見たが、それは本当に自分がどこに行かなければならないかを啓発するものだった。CTFが必ずしも直接的に監査スキルに貢献するとは限らないのは事実ですが、セキュリティの専門家としての能力にどれだけプラスになるかを実感しました。
私が悟ったのは、セキュリティ監査を行うことが意識的な努力だとすれば、CTFは潜在意識を鍛えるようなものだということだ。
このような動機から、私はバイトコードをソリッドにできるだけ近づける方法を学びたいと思いました。
以前、evm.codesを使ってバイトコードをオペコードに変換する実験をしたことがあり、その練習はとても役に立ったが、全パスをカバーするものではなかった。
制限
a) バイトコードの解釈は難しく、アセンブリも簡単ではない
b) バイトコードには変数や関数名に関する十分な情報がない。
c) バイトコードはプログラムの直線的な流れを表現しておらず、理解しにくい。
デコンパイル処理
元のコードに近づけるプロセスは逆コンパイルと呼ばれ、4つのステップに分けられる。
Step 1 :
逆アセンブル: これは、バイトコードをアセンブリ表現に変換するプロセスである。
Step 2 :
シンボリック実行: 上記のアセンブリ命令からフローシーケンスへの分岐を生成するプロセス。JUMPI命令はすべて分岐を生成する。
Step 3 :
分岐解析: 上記のブランチは、ロジックフローの高レベル表現をレンダリングするために、互いにインターリーブされる可能性があります。
Step 4:
後処理: 上記で組み立てた高レベルの表現をより読みやすくする。
evmにまつわるさまざまなCTFの書き込みを読むと、バイトコードを理解するために使われた以下の3つのツールに出会った。
b) https://github.com/eveem-org/panoramix
c) https://github.com/Jon-Becker/heimdall-rs
この記事では、Heimdall-rsで実験することにした。
Heimdall-rsによるデコンパイル
Heimdall-rsをデプロイされた契約を分解するツールとして使用します。あなたのマシンにインストールするには、以下のリンクを参照してください。
Ethereumメインネットへのrpcエンドポイントを設定するには、リンク先の設定セクションを参照してください。
次のセクションでは、イーサリアムメインネット上にデプロイされたWETHコントラクトのコードをビルドバックしてみましょう。
アドレス : 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
バイトコードをデプロイした:

Heimdall-rsは、私たちのためにすべてのハードワークを行い、デプロイされた契約からソースコードをビルドバックする方法を簡素化します。
a) Solidity コードをビルドします:
以下のコマンドが動作するように、Heimdall-rs用にrpcエンドポイントEthereum mainnetを設定しました。
heimdall decompile 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 -vvv -d --include-sol --skip-resolving
上記のコマンドを実行すると、出力が生成され、ローカル・マシンのoutputフォルダに書き込まれる。

生成される出力ファイルは2つある。
i) abi.json
ii) decomplied.sol
i) abi.json
このファイルには、コントラクトのABIが含まれています。以下を参照してください。

ii) decomplied.sol
このファイルには、オリジナルのコントラクトのソースコードが含まれています。変数やコントラクトの名前はバイトコードにはないため、生成されたコードには以下のような一般的な命名がされています。

b) 制御フローグラフの生成
以下のコマンドを使用すると、制御フロー・グラフを生成し、出力を.dotファイルに書き出すことができます。
heimdall cfg 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 -vvv
出力ファイルをビジュアル・スタジオで開くと、以下のようなコントロール・フロー・グラフが表示される。

c) インタラクティブ・スナップショットの作成
基本的に、私たちはヘイムダルの選手たちがハードワークをこなしながら、多くのピースが組み合わさっていくのを見た。しかし、スナップショットは、契約の機能を学ぶためのインタラクティブなモードを提供するもう一つのクールな機能である。
heimdall snapshot 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 -d -vvv
以下のインタラクティブ画面では、各関数を見て、その関数に付随する様々な重要な側面を理解することができます。
i) 関数のシグネチャ
ii) 修飾子
iii) ガス
iv) イベント
v) ストレージ
vi) 制御文

デコンパイルプロセスは非常に複雑なプロセスであり、その複雑さは基礎となるコントラクトコードに基づいて増大しますが、heimdall-rsは複雑な反復プロセスの多くの層を取り除き、デコードを簡素化し、手作業の多くの時間を節約します。
以下は、WETH.solのソースコード[potential]とheimdall-rsによってビルドバックされたものを並べて比較したものです。

Heimdall-rsの能力を探った結果、少なくともバイトコードで始まるCTFの明確なスタート地点ができた。