WebAssemblyファイルをデコンパイルする
WebAssemblyはあらかじめコンパイルされているのでJavaScriptのように実行時にコードをパースする必要がなく、高速に動作します。WebAssemblyのコードはバイナリデータになっているので処理を隠蔽できているように見えますが、デコンパイルを行うことで人間が読める形に変換できます。
今回はwabtを使ってWebAssemblyのデコンパイルを行ってみます。
元になるコード
今回はGoを使っています。一番簡単なコードです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
func main() { | |
println("Hello, wasm!") | |
} |
WebAssemblyにする
このコードをコンパイルしてWebAssemblyにします。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ GOOS=js GOARCH=wasm go build -o test.wasm main.go |
そしてできあがるのが test.wasm です。このファイルは1.3MBありました。
デコンパイルする
ではここからデコンパイルします。その際に使うのがwabtです。WebAssembly用のツールが各種含まれています。ビルド時にはcmakeが必要です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ git clone –recursive https://github.com/WebAssembly/wabt | |
$ cd wabt | |
$ make |
そして生成されるwasm2watコマンドを使ってデコンパイルします。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bin/wasm2wat test.wasm > test.wat |
デコンパイルすると25.8MBになりました。かなり肥大化しているのが分かります。
コードを見る
デコンパイルされたコードは、WebAssemblyのテキスト版です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(module | |
(type (;0;) (func (result i32))) | |
(type (;1;) (func (param i32))) | |
(type (;2;) (func (param i64 i64 i64 i64) (result i64))) | |
(type (;3;) (func (param i32 i32 i32) (result i32))) | |
(type (;4;) (func (param i64 i64 i64) (result i64))) | |
(type (;5;) (func (param i64 i64))) | |
(type (;6;) (func (param i32 i32))) | |
(type (;7;) (func (param i32 i32 i32))) | |
(type (;8;) (func (param i64 i64) (result i64))) | |
(type (;9;) (func (param f64) (result i64))) | |
(import "go" "debug" (func (;0;) (type 1))) | |
(import "go" "runtime.wasmExit" (func (;1;) (type 1))) | |
: |
その中に Hello, wasm という文字列も入っています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
byte block (GC sweep waitHello, wasm!\0abad map statefatal error: |
つまりWebAssemblyでバイナリ化していたとしても、任意の処理がどこで、どのように行われているか、探そうと思えば探し出せると言うことです。
WebAssemblyでコードをコンパイルしたとしても、100%安全という訳ではありません。Javaと同レベルくらいに考える方が良いかもしれません。隠し方は幾つかありますので、なるべく分かりづらくなる方法を選ぶべきで、安直にキーなどをコードに書かない方が良さそうです。
コメントは受け付けていません。