wasm是基於堆棧的虛擬機的二進制指令格式。在這次比賽中遇到,記錄一下。
IDA反編譯插件
下載地址:https://github.com/fireeye/idawasm
食用方法:
- install the python module:
python.exe setup.py install
- manually install the WebAssembly file loader:
mv loaders\wasm_loader.py %IDADIR%\loaders\wasm_loader.py
- manually install the WebAssembly processor:
mv procs\wasm_proc.py %IDADIR%\procs\wasm_proc.py
WASM編譯環境搭建
git clone https://github.com/juj/emsdk.git cd emsdk ./emsdk install --build=Release sdk-incoming-64bit binaryen-master-64bit ./emsdk activate --global --build=Release sdk-incoming-64bit binaryen-master-64bit source ./emsdk_env.sh
編譯C為WASM
emcc biu.c -s WASM=1 -o biu.html -g4 -O2
-s WASM=1指定輸出為wasm形式,Emscripten默認為asm.js的形式
-o biu.html可以指定生成html文件、以及wasm文件
-g4指定debug信息等級,詳情看—-help
-O2指定優化等級,詳情看—-help
WABT工具包
WABT(我們將其稱為“ wabbit”)是用於WebAssembly的一套工具,包括:
- wat2wasm:從 WebAssembly文本格式轉換為 WebAssembly二進制格式
- wasm2wat: wat2wasm的逆函數,從二進制格式轉換回文本格式(也稱為.wat)
- wasm-objdump:顯示有關wasm二進制文件的信息。與objdump類似。
- wasm-interp:使用基於堆棧的解釋器解碼並運行WebAssembly二進制文件
- wasm-decompile:將wasm二進制文件反編譯為可讀的類似C的語法。
- wat- desugar:解析規范解釋程序支持的.wat文本格式(S表達式,平面語法或混合格式)並打印“規范”平面格式
- wasm2c:將WebAssembly二進制文件轉換為C源代碼和標頭
- wasm-strip:刪除WebAssembly二進制文件的部分
- wasm-validate:驗證WebAssembly二進制格式的文件
- wast2json:將wasm spec測試格式的文件轉換為JSON文件和關聯的wasm二進制文件
- wasm-opcodecnt:計算指令的操作碼使用量
- spectest-interp:讀取Spectest JSON文件,然后在解釋器中運行其測試
將wasm轉換為C語言,主要用到wasm2c
食用方法
git clone --recursive https://github.com/WebAssembly/wabt
cd wabt
mkdir build
cd build
cmake ..
cmake --build .
wasm2c使用
測試文件:https://lanzous.com/id1pybe
/home/ubuntu/wabt/build/wasm2c chall.wasm -o out.c
將chall.wasm轉換為out.c
此時的C代碼並不直觀。
優化
將之前反編譯出來的wasm.c,wasm.h,以及wabt項目內的wasm-rt.h,wasm-rt-impl.c,wasm-rt-impl.h三個文件放到同一個文件夾。
gcc -c out.c -o out.o
這樣得到的源文件在IDA中分析就會輕松一些
i32_load形式的函數為取值函數,第一個參數為取值對象,第二個參數為偏移
i32_store形式的函數為操作存儲函數,第一個參數為存儲對象,第二個參數為存儲位置,第三個參數為操作方式
動態調用
Python開啟服務器
全局安裝
npm i http-server -g
快速使用
http-server
默認端口8080,指定端口
http-server <path> -a 127.0.0.1 -p 8090
如果路徑中有index.html,默認為主頁
HTML調用
參考:https://developer.mozilla.org/zh-CN/docs/WebAssembly/Using_the_JavaScript_API
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Simple template</title> <script> fetch('chall.wasm') .then(res => res.arrayBuffer() ).then(bytes => WebAssembly.instantiate(bytes, importObject) ).then(results => { results.instance.exports.exported_func(); }); </script> </head> <body> </body> </html>
chall.wasm放在與index.html同目錄