[レポート]DeClang: ハッキング対策コンパイラ – DeClang: Anti-hacking compiler – – CODE BLUE 2020 #codeblue_jp

CODE BLUE 2020で行われた「DeClang: ハッキング対策コンパイラ - DeClang: Anti-hacking compiler -」というセッションのレポートです。
2020.10.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、臼田です。

今回はCODE BLUE 2020で行われた以下のセッションのレポートです。

DeClang: ハッキング対策コンパイラ - DeClang: Anti-hacking compiler -

クライアントプロテクション技術には、パッキング、難読化、アンチデコンパイル、改ざん検知など、さまざまなアプローチがあるが、本発表ではこれらのアプローチの優劣について検討し、我々のコンパイラ型のクライアントプロテクションツール DeClang を紹介する。 今までの先行研究では、LLVM ベースのオープンソースプロジェクトは沢山存在する。しかし、これらのプロジェクトのほとんどが実験段階にとどまり、バグが潜んでいる、ARMがサポートされていない、モバイルアプリのビルドフローに適用できないなど、様々な欠点が存在している。DeClang はこれらの問題を克服し、実用レベルの難読化コンパイラとして一部オープンソース化される。 本発表では、Unity のビルドフローを分析し、いかにして DeClang を Unity のビルドフローに取り込めるかを説明する。さらに、難読化コンパイラとして実用レベルのものとするにあたり、obfuscator-llvm というプロジェクトに長期潜んでいたバグを見つけ、解決した手法についても紹介する。本発表を通じて誰でも手軽にモバイルアプリを守れるように実現させたいと考えている。

Presented by : 万萌遠(ホウエン・バン)

レポート

  • 自己紹介
    • DeNAでセキュリティエンジニア
  • アジェンダ
    • 理由とモチベーション
    • 概要と機能の紹介
    • O-LLVMのバグとFix
    • 展望
  • DeClang開発モチベーション
    • ゲーム会社としてゲームやアプリのハッキングの対策をしている
    • メモリ・タイムハッキング
    • ネットワーク
    • などなどいろいろある
    • 対策の方法としては商業用のソリューションを使う方法がある
    • しかし高い
    • オープンソースのツールが作れないか考えた
    • ハッカーに対するヒントになるのでよろしくないからコンパイラ型にした
    • DeClangが誕生した
      • アンチハッキングコンパイラ
      • LLVMに基づいて拡張した
      • Apache License 2.0に基づいている
      • 誰でも自分のゲームを守ることができる
    • なぜわざわざ作ったか
      • Unityのビルドフローに互換性がある
      • クロスプラットフォーム
        • X86/64 / ARM / AArch64なども対応
        • Visural Studioはこれから対応したい
  • フロー
    • Unityで作成してC++に変換
    • AndroidならNDK Clangに変更してAPK
    • iOSはらXcodeを使ってIPA
    • 組み込み方
      • NDKやXcodeをDeClangにする
      • パラメータの渡し方
        • コマンドラインでフラグを渡す
        • ソースコードにアトリビュートを追加
      • しかしこれらはUnityのビルドフローに適切ではない
      • パラメータを渡したりできない
      • C++は自動生成なのでそこにアトリビュートを加えるのは難しい
      • なのでDeClangでは環境変数を使っている
      • これは元のビルドフローを破壊せずコンパイルできる
      • shellやPower Shellスクリプトでいける
  • DeClangの機能
    • 難読したいものを指定するconfigを書く
      • 難読化するとBasicBlocksがたくさんになって前後関係も分かりづらい
      • IDAのデコンパイルをしてもだいぶ読みづらい
    • Indirect Branch
      • 関数を指定する必要がない
      • 先程の機能よりは弱い
      • Branch命令をIndirect Branchに書き換える
      • IDAだとどこにジャンプするかわからなくなる
    • ほかにも色々ある
      • ただOSSにしすぎるとよろしくないので公開できない
    • 原理だけ簡単に説明する
    • 関数レベルのアンチタンパ
      • 関数にタンパを先頭に組み込む
      • お互いに改ざん検知ができる
      • 関連する関数全部改ざんしないといけなくなる
  • O-LLVMバグ
    • フラッディングすると目的通りに実行されない
    • フラッディングのロジックを説明する
    • bb1はprologue
    • O-LLVMでswitch bbを作成する
    • 単純なブランチ命令ではなく条件分岐の場合
    • 条件分岐を2つのbbに分ける
    • 1.1と1.2を作る
    • 分割することでパターン1をパターン2に戻せる
    • ただし別のパターンが有りこれがO-LLVMが考慮されていない
    • 次に実行する部分が隣接していない場合
    • 初期化されたswitchVarが0x1のママになり順序が変わってしまう
    • 実際にフラッディングするとそうなっている
    • どうやってFixするか
      • BBを毎回スプリットする
    • この例は変なコードだけど誰が書くのか
    • Unityが書く
    • GOTOが大量にあることによるバグということになる
  • DeClangモットー
  • @DeNAxTechもフォローしてね

感想

IDAでうまく見れないように色々工夫されているのは面白いですね。

Unityとの相性も考慮して作られているようなので、ゲーム開発者の方は是非試してみてください!