Obfuscator-LLVM を Mac で試してみました


# Obfuscation とは？
Code Obfuscation とはコードを故意に複雑にして読んで理解することを諦めさせてしまう技術です。自然とそういうコードを書いてしまう才能の持ち主もいますが、obfscator は自然に記述されたコードをそういうコードに変換してくれるツールで、white box encription と呼ぶ事もあります。意味を変えないように命令を置き換えたり、無意味な分岐を入れたり、ひとまとまりの論理の途中で関数呼び出しに分けたりといった、読んでると腹が立って読めなくなるコードに変換します。ソースコードを obfuscate する実装もありますが、中間コードを obfuscate する実装が多いようです

PlayReady とか DLNA とかといったコピー・プロテクション やリンクプロテクションのアプリケーションを解析して暗号鍵とかカーブシェイプとかをとられたりしないように暗号ルーチンを obfuscate したりすることを規格が推奨しています

他に、不発のミサイルを敵に拾われて組み込みプログラムを解析されたりしないようにとか、ゲームをパクられないようにとか、あと面白い例ではアンチウイルスソフトをすり抜けるためにウイルスソフトに obfuscation を施したりする例もあるそうです

私も某著名な商用 Obfuscator の出力を（それがどれぐらい丈夫なのか自分の目で見とかないとシャレにならない立場だったので）[Hex-Ray](https://www.hex-rays.com/products/decompiler/) とかにかけて追っかけてみたりしたこともあるのですが、制御構造を再現してくれる Decompiler でみても全くわかりませんでした。

Obfuscation の種々の手法についてはこちらが大変参考になりました。
<a rel="nofollow" href="http://www.amazon.co.jp/gp/product/0321549252/ref=as_li_tf_il?ie=UTF8&camp=247&creative=1211&creativeASIN=0321549252&linkCode=as2&tag=grenouille0d-22"><img border="0" src="http://ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=0321549252&Format=_SL110_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=grenouille0d-22" ></a><img src="http://ir-jp.amazon-adsystem.com/e/ir?t=grenouille0d-22&l=as2&o=9&a=0321549252" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
馬鹿っぽい絵の表紙で電話帳みたいに分厚い本なのですが、分厚い分だけ説明が丁寧で理解しやすいです。高校生の頃に読んで感動した「親切な物理」みたいです。

# Obfuscator-LLVM とは
[ICSE](http://2015.icse-conferences.org) の併設カンファレンスに今年から [SPRO](http://www.wikicfp.com/cfp/servlet/event.showcfp?eventid=43235&copyownerid=73989)( International Workshop on Software Protection) というのが出来てたんですね、大事なテーマなので今までなかったのも不思議ですが、こちらで発表されていたようです。[Proceeding](http://dl.acm.org/citation.cfm?id=2821434) と [パワポ](https://aspire-fp7.eu/spro/wp-content/uploads/spro15_talk.pdf) と[github](https://github.com/obfuscator-llvm/obfuscator) です

その名のとおり、LLVM の中間コードに対して Obfuscation を行う OSS の実装だそうです。ただ、現在は会社が忙しいので OSS 版は　under maintenance なんだそうです。そういえば某有名商用実装も LLVM の中間コードに対する Obfuscator でした。

# Mac で Obfuscator-LLVM を試す

wiki の手順どおりで以下のようになります

```bash:
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 ができているので例えば

```c:test.c
main(){
  printf ("今年はフィレンツェだったんだ...¥n");
}
```
とかを

```bash
bin/clang test.c -mllvm -sub -mllvm -fla -mllvm -bcf
```

とかコンパイルして

```bash:
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
本文中の参照の繰り返しになりますが参照の便に

+ [元論文](http://dl.acm.org/citation.cfm?id=2821434)
+ [発表スライド](https://aspire-fp7.eu/spro/wp-content/uploads/spro15_talk.pdf)
+ [github](https://github.com/obfuscator-llvm/obfuscator)

# related works
1. [Obfuscating Android Applications using O-LLVM and the NDK](http://fuzion24.github.io/android/obfuscation/ndk/llvm/o-llvm/2014/07/27/android-obfuscation-o-llvm-ndk/) Android の ネイティブアプリに Obfuscator-LLVM をかけた事例報告。OSX 用、Linux 用にコンパイルされた Obfuscator-LLVM が公開されている
2. [Deobfuscation: recovering an OLLVM-protected program](http://blog.quarkslab.com/deobfuscation-recovering-an-ollvm-protected-program.html) Obfuscaor-LLVM の出力を Miasm でriverse engineering を試みた結果の報告。結論は「出来なかったし、決してできない」だそうです
3. [llvm obfuscator passes doesnt work with opt](http://stackoverflow.com/questions/33856696/llvm-obfuscator-passes-doesnt-work-with-opt) Stack Overflow でのQ&A. アカデミックなプロジェクトだと思ってたらこんなところで Q&A が成り立つほどすでにプラクティカルな存在だったんだ！と驚いたです