WebAssemblyファイルをデコンパイルする
WebAssemblyはあらかじめコンパイルされているのでJavaScriptのように実行時にコードをパースする必要がなく、高速に動作します。WebAssemblyのコードはバイナリデータになっているので処理を隠蔽できているように見えますが、デコンパイルを行うことで人間が読める形に変換できます。
今回はwabtを使ってWebAssemblyのデコンパイルを行ってみます。
元になるコード
今回はGoを使っています。一番簡単なコードです。
package main | |
func main() { | |
println("Hello, wasm!") | |
} |
WebAssemblyにする
このコードをコンパイルしてWebAssemblyにします。
$ GOOS=js GOARCH=wasm go build -o test.wasm main.go |
そしてできあがるのが test.wasm です。このファイルは1.3MBありました。
デコンパイルする
ではここからデコンパイルします。その際に使うのがwabtです。WebAssembly用のツールが各種含まれています。ビルド時にはcmakeが必要です。
$ git clone –recursive https://github.com/WebAssembly/wabt | |
$ cd wabt | |
$ make |
そして生成されるwasm2watコマンドを使ってデコンパイルします。
bin/wasm2wat test.wasm > test.wat |
デコンパイルすると25.8MBになりました。かなり肥大化しているのが分かります。
コードを見る
デコンパイルされたコードは、WebAssemblyのテキスト版です。
(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 という文字列も入っています。
byte block (GC sweep waitHello, wasm!\0abad map statefatal error: |
つまりWebAssemblyでバイナリ化していたとしても、任意の処理がどこで、どのように行われているか、探そうと思えば探し出せると言うことです。
WebAssemblyでコードをコンパイルしたとしても、100%安全という訳ではありません。Javaと同レベルくらいに考える方が良いかもしれません。隠し方は幾つかありますので、なるべく分かりづらくなる方法を選ぶべきで、安直にキーなどをコードに書かない方が良さそうです。
コメントは受け付けていません。