Upgrade to Pro — share decks privately, control downloads, hide ads and more …

QEMUのDynamic Binary Translationがあって良かったねという話

QEMUのDynamic Binary Translationがあって良かったねという話

第十回カーネル/VM探検隊 発表資料

Yuma Kurogome

May 25, 2014
Tweet

More Decks by Yuma Kurogome

Other Decks in Programming

Transcript

  1. QEMUの
    Dynamic Binary Translationが
    あって良かったねという話
    5/25/2014
    第十回カーネル/VM探検隊
    @ntddk

    View Slide

  2. 自己紹介

    Yuma Kurogome(@ntddk)

    Keio Univ. B2

    作ったことがあるもの
    – デバドラ, OS, VMM, EFI Application

    作ったことがないもの
    – CPU, GPU, ネットワーク機器

    チョトモワカラナイのにインターンでQEMUを
    触ることになってしまった

    ので調べた

    View Slide

  3. アッ

    この発表は遅延評価されました

    View Slide

  4. なぜQEMUか

    QEMUのソースは魔窟[要出典]
    – 構造体(クロージャ)のポインタを謎のマクロに投げ
    続ける
    – Pure Cで書かれているにも関わらず

    new

    object

    クラスの継承

    View Slide

  5. なぜQEMUか

    仮想化技術について学びたいなら……。
    – bhyve
    – BitVisor
    – QEMUを読む優先度はあまり高くないのでは[要出典]
    https://twitter.com/syuu1228/status/460748398962806787

    View Slide

  6. なぜQEMUか

    Dynamic binary translation(DBT)ができるから
    – 動的バイナリ変換

    View Slide

  7. QEMUのエミュレーション方式

    QEMUは2つの動作モードをサポートしている
    – カーネルモードエミュレーション

    あるアーキテクチャ向けのOSを
    異なるアーキテクチャのホスト上で動かす
    – ユーザーモードエミュレーション

    あるアーキテクチャ向けにビルドされたバイナリを、
    異なるアーキテクチャで動かす

    QEMUはdynamic binary translationによってこ
    れらを実現

    View Slide

  8. QEMUの論文
    ● F. Bellard. QEMU, a fast and portable
    dynamic translator. In USENIX, 2005.
    – 開発者による論文
    – Wikiには”QEMU is a generic and open source
    machine emulator and virtualizer.”とあり、
    – 今でこそQEMUはKVMの一部になっているが、
    – そもそもVT-xを云々というよりdynamic translator
    としての側面が大きい[要出典]

    DBTがQEMUの肝[要出典]

    View Slide

  9. Tiny Code Generatorの概略

    Tiny Code Generator(TCG)によってDBT
    を実現

    ゲストのコードを逆アセンブル

    中間コードに変換

    中間コードをホストのコードに
    変換
    Vitaly Chipounov and George Candea. Dynamically Translating x86 to LLVM using QEMU. In EPFL, 2010.

    View Slide

  10. TCG

    main()からcpu_exec()

    cpu-exec.cのtb_find_fast/slow()でunchained
    blockまで実行
    cpu_exec()
    Prologue
    Epilogue
    Pre-generated code Translation Cache
    Code
    QEMU Internals

    View Slide

  11. TCG
    Guest Code
    TCG Operations
    Host Code
    gen_intermediate_code()
    tcg_gen_code()

    target-[architecture]
    /translate.c

    tcg/tcg.c
    QEMU Internals

    View Slide

  12. TCG
    Guest Code
    TCG Operations
    Host Code
    gen_intermediate_code()
    tcg_gen_code()
    push %ebp
    mov %esp,%ebp
    not %eax
    add %eax,%edx
    mov %edx,%eax
    xor $0x55555555,%eax
    pop %ebp
    ret
    QEMU Internals

    View Slide

  13. TCG
    Guest Code
    TCG Operations
    Host Code
    gen_intermediate_code()
    tcg_gen_code()
    ld_i32 tmp2,env,$0x10
    qemu_ld32u
    tmp0,tmp2,$0xffffffff
    ld_i32 tmp4,env,$0x10
    movi_i32 tmp14,$0x4
    add_i32 tmp4,tmp4,tmp14
    st_i32 tmp4,env,$0x10
    st_i32 tmp0,env,$0x20
    movi_i32 cc_op,$0x18
    exit_tb $0x0
    QEMU Internals

    View Slide

  14. TCG
    Guest Code
    TCG Operations
    Host Code
    gen_intermediate_code()
    tcg_gen_code()
    mov 0x10(%ebp),%eax
    mov 0x10(%ebp),%edx
    mov (%ecx),%eax
    mov %eax,%ecx
    add $0x4,%edx
    mov %edx,0x10(%ebp)
    mov %eax,0x20(%ebp)
    mov $0x18,%eax
    mov %eax,0x30(%ebp)
    xor %eax,%eax
    jmp 0xba0db428 (retのみ)
    QEMU Internals

    View Slide

  15. TCG

    Translation Block(TB)
    – translate-all.hで定義されたBasic Block
    – 分岐命令かページの境界まででコードを区切る

    コードキャッシュからreturnしていると遅くな
    るため、TBを繋げて実行

    なんかLLVMっぽくないですか?

    View Slide

  16. QEMUのDBT(TCG)で何ができるか

    バイナリをLLVMに逆コンパイル
    – S2E[ASPLOS11]

    View Slide

  17. S2E

    s2e.epfl.ch

    WindowsバイナリをLLVM bitcodeに変換する

    View Slide

  18. S2EにおけるDBT
    Vitaly Chipounov and George Candea. Dynamically Translating x86 to LLVM using QEMU. In EPFL, 2010.

    View Slide

  19. S2EにおけるDBT

    x86とLLVM bitcodeの間にあるsemantic gapを
    どうするか?
    – Dagger(dagger.repzret.org)はオレオレIRを実装

    S2EはTCGで参照される辞書にLLVMの命令を
    登録

    LLVM bitcodeに変換されたバイナリを
    KLEE[OSDI08]に投げる

    View Slide

  20. KLEE

    与えられたソースコードをLLVMでビルド

    Symbolic executionからテストケースを生成

    Coreutilsに試したところ、15年に渡る手動テス
    トを上回るカバレッジを89時間で達成!

    View Slide

  21. Symbolic execution

    記号実行と訳される

    変数に代数シンボルを与えて監視

    プログラムはある結果に収束するか

    どの入力値でどの実行パスを通るか

    条件分岐に行き当たる度に分岐が実行可能か
    SAT solverに解かせる

    あらゆる実行パスを通りたい

    View Slide

  22. SAT solver

    ブール式の充足可能性問題を解くプログラム

    式は連言標準形(CNF)で与えられる
    ( a1 or !a2 or a3 ... or an)
    and ( b1 or b2 or !b3 ... or !bn)
    and …
    – リテラル: a1や!a2といった命題変数またはその否定
    – 節: 複数のリテラルの選言(or)
    – CNF式: 複数の節の連言(and)

    View Slide

  23. SAT solver

    ベースになっているのはDPLLアルゴリズム
    – 変数に値を代入して矛盾が起きるまで探索
    – ヒューリスティックに変数を選択
    – 分割規則を適用、再帰的な二分探索
    – 式を満たす変数割当が見つかればSAT

    View Slide

  24. KLEEのSAT solver

    KLEEはSTPを使用
    – 前身のEXE[CCS06]のために開発された
    – 厳密にはSAT solverの上位版であるSMT solver

    SMT solver
    – ブール式に加えて「背景理論」をサポートす

    配列

    ビットベクトル

    etc …

    View Slide

  25. S2Eにおけるsymbolic execution

    Q. バイナリを直接symbolic executionすれば良
    いのでは?

    A. x86はSSAでないのでレジスタがコンフリク
    トを起こすかも
    mov esi, 0x13
    mov edx, 0x2014
    mov esi, 0x13

    mov esi, 0x2014
    (esi == 0x13) and (edx == 0x2014)
    (esi == 0x13) and (esi == 0x2014)

    View Slide

  26. S2Eのまとめ

    x86とLLVM bitcodeの間にあるsemantic gapを
    QEMUで克服

    Windowsバイナリに対してsymbolic execution
    を通じてテストケースを生成

    LLVMデコンパイラとして使える

    View Slide

  27. LLVMデコンパイラで何ができるか

    Windowsバイナリからテストケース生成
    – S2E[ASPLOS11]

    マルウェアの難読化を解除する
    – OptiCode[Syscan13]

    View Slide

  28. OptiCode

    バイナリをLLVM bitcodeに変換
    – QEMUを用いたのかどうかは不明

    LLVMの最適化パスによって難読化を除去
    – レジスタに無意味な値を挿入する難読化

    -dse, -simplifycfg
    – NOPと等価の命令を挿入する難読化

    -constprop, -instcombine
    – レジスタへの代入をばらけさせる難読化

    -instcombine
    – etc …

    View Slide

  29. OptiCode

    Opaque predicateへの対応
    – LLVMによる最適化では解除できない
    – 常に真(偽)となる条件文を挿入、
    実行されない箇所にコードを配置するというもの
    – LLVM bitcodeに対してsymbolic execution
    – OptiCodeではSMT solverにZ3を使用

    View Slide

  30. OptiCodeのまとめ

    マルウェアをLLVM bitcodeに逆コンパイル

    LLVMの最適化パスをそのまま難読化の解除に
    使える

    LLVM bitcodeに逆コンパイルできれば
    symbolic executionで難読化の解除もできる

    View Slide

  31. まとめ

    QEMUはアーキテクチャ間のコード変換を実現

    LLVMへの逆コンパイルとsymbolic execution
    への適用

    QEMUのDBTがあって良かったね

    View Slide