Obfuscation とは?
Code Obfuscation とはコードを故意に複雑にして読んで理解することを諦めさせてしまう技術です。自然とそういうコードを書いてしまう才能の持ち主もいますが、obfscator は自然に記述されたコードをそういうコードに変換してくれるツールで、white box encription と呼ぶ事もあります。意味を変えないように命令を置き換えたり、無意味な分岐を入れたり、ひとまとまりの論理の途中で関数呼び出しに分けたりといった、読んでると腹が立って読めなくなるコードに変換します。ソースコードを obfuscate する実装もありますが、中間コードを obfuscate する実装が多いようです
PlayReady とか DLNA とかといったコピー・プロテクション やリンクプロテクションのアプリケーションを解析して暗号鍵とかカーブシェイプとかをとられたりしないように暗号ルーチンを obfuscate したりすることを規格が推奨しています
他に、不発のミサイルを敵に拾われて組み込みプログラムを解析されたりしないようにとか、ゲームをパクられないようにとか、あと面白い例ではアンチウイルスソフトをすり抜けるためにウイルスソフトに obfuscation を施したりする例もあるそうです
私も某著名な商用 Obfuscator の出力を(それがどれぐらい丈夫なのか自分の目で見とかないとシャレにならない立場だったので)Hex-Ray とかにかけて追っかけてみたりしたこともあるのですが、制御構造を再現してくれる Decompiler でみても全くわかりませんでした。
Obfuscation の種々の手法についてはこちらが大変参考になりました。
馬鹿っぽい絵の表紙で電話帳みたいに分厚い本なのですが、分厚い分だけ説明が丁寧で理解しやすいです。高校生の頃に読んで感動した「親切な物理」みたいです。
Obfuscator-LLVM とは
ICSE の併設カンファレンスに今年から SPRO( International Workshop on Software Protection) というのが出来てたんですね、大事なテーマなので今までなかったのも不思議ですが、こちらで発表されていたようです。Proceeding と パワポ とgithub です
その名のとおり、LLVM の中間コードに対して Obfuscation を行う OSS の実装だそうです。ただ、現在は会社が忙しいので OSS 版は under maintenance なんだそうです。そういえば某有名商用実装も LLVM の中間コードに対する Obfuscator でした。
Mac で Obfuscator-LLVM を試す
wiki の手順どおりで以下のようになります
git clone -b llvm-3.6.1 https://github.com/obfuscator-llvm/obfuscator.git
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE:String=Release ../obfuscator/
make -j5
これで、build 配下の bin/clang ができているので例えば
main(){
printf ("今年はフィレンツェだったんだ...¥n");
}
とかを
bin/clang test.c -mllvm -sub -mllvm -fla -mllvm -bcf
とかコンパイルして
nm a.out
と nm で見てみると _x とか _y とかへんなエントリができてややこしくなっています
MBA:build takeyuki$ nm a.out
0000000100000000 T __mh_execute_header
0000000100000f50 T _main
U _printf
0000000100001018 S _x
000000010000101c S _y
U dyld_stub_binder
感想
ここ数年、フリーの obfscator を探していたので(自分で実装する根性もなかった orz)、ついに見つけた!って感じでルンルン🎶気分です。
参考 URL
本文中の参照の繰り返しになりますが参照の便に
related works
- Obfuscating Android Applications using O-LLVM and the NDK Android の ネイティブアプリに Obfuscator-LLVM をかけた事例報告。OSX 用、Linux 用にコンパイルされた Obfuscator-LLVM が公開されている
- Deobfuscation: recovering an OLLVM-protected program Obfuscaor-LLVM の出力を Miasm でriverse engineering を試みた結果の報告。結論は「出来なかったし、決してできない」だそうです
- llvm obfuscator passes doesnt work with opt Stack Overflow でのQ&A. アカデミックなプロジェクトだと思ってたらこんなところで Q&A が成り立つほどすでにプラクティカルな存在だったんだ!と驚いたです