Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
QEMUのDynamic Binary Translationがあって良かったねという話
Search
Yuma Kurogome
May 25, 2014
Programming
10
7.4k
QEMUのDynamic Binary Translationがあって良かったねという話
第十回カーネル/VM探検隊 発表資料
Yuma Kurogome
May 25, 2014
Tweet
Share
More Decks by Yuma Kurogome
See All by Yuma Kurogome
The Art of De-obfuscation
ntddk
16
27k
死にゆくアンチウイルスへの祈り
ntddk
55
39k
Windows Subsystem for Linux Internals
ntddk
10
3k
なぜマルウェア解析は自動化できないのか
ntddk
6
4.2k
Linear Obfuscation to Drive angr Angry
ntddk
4
830
CAPTCHAとボットの共進化
ntddk
2
1.1k
マルウェアを機械学習する前に
ntddk
3
1.6k
Peeling Onions
ntddk
7
3.6k
仮想化技術を用いたマルウェア解析
ntddk
8
27k
Other Decks in Programming
See All in Programming
ファインディLT_ポケモン対戦の定量的分析
fufufukakaka
0
920
お前もAI鬼にならないか?👹Bolt & Cursor & Supabase & Vercelで人間をやめるぞ、ジョジョー!👺
taishiyade
7
4.2k
第3回関東Kaggler会_AtCoderはKaggleの役に立つ
chettub
3
1.2k
Djangoにおける複数ユーザー種別認証の設計アプローチ@DjangoCongress JP 2025
delhi09
PRO
4
470
プログラミング言語学習のススメ / why-do-i-learn-programming-language
yashi8484
0
160
15分で学ぶDuckDBの可愛い使い方 DuckDBの最近の更新
notrogue
3
510
Rubyで始める関数型ドメインモデリング
shogo_tksk
0
140
Jasprが凄い話
hyshu
0
160
Serverless Rust: Your Low-Risk Entry Point to Rust in Production (and the benefits are huge)
lmammino
1
150
Honoとフロントエンドの 型安全性について
yodaka
7
1.4k
苦しいTiDBへの移行を乗り越えて快適な運用を目指す
leveragestech
0
1k
5分で理解する SOLID 原則 #phpcon_nagoya
shogogg
1
300
Featured
See All Featured
For a Future-Friendly Web
brad_frost
176
9.6k
Adopting Sorbet at Scale
ufuk
74
9.2k
Docker and Python
trallard
44
3.3k
Designing for humans not robots
tammielis
250
25k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.4k
How to train your dragon (web standard)
notwaldorf
91
5.9k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Building Your Own Lightsaber
phodgson
104
6.2k
Gamification - CAS2011
davidbonilla
80
5.2k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.7k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
133
33k
Transcript
QEMUの Dynamic Binary Translationが あって良かったねという話 5/25/2014 第十回カーネル/VM探検隊 @ntddk
自己紹介 • Yuma Kurogome(@ntddk) • Keio Univ. B2 • 作ったことがあるもの
– デバドラ, OS, VMM, EFI Application • 作ったことがないもの – CPU, GPU, ネットワーク機器 • チョトモワカラナイのにインターンでQEMUを 触ることになってしまった • ので調べた
アッ • この発表は遅延評価されました
なぜQEMUか • QEMUのソースは魔窟[要出典] – 構造体(クロージャ)のポインタを謎のマクロに投げ 続ける – Pure Cで書かれているにも関わらず •
new • object • クラスの継承
なぜQEMUか • 仮想化技術について学びたいなら……。 – bhyve – BitVisor – QEMUを読む優先度はあまり高くないのでは[要出典] https://twitter.com/syuu1228/status/460748398962806787
なぜQEMUか • Dynamic binary translation(DBT)ができるから – 動的バイナリ変換
QEMUのエミュレーション方式 • QEMUは2つの動作モードをサポートしている – カーネルモードエミュレーション • あるアーキテクチャ向けのOSを 異なるアーキテクチャのホスト上で動かす – ユーザーモードエミュレーション
• あるアーキテクチャ向けにビルドされたバイナリを、 異なるアーキテクチャで動かす • QEMUはdynamic binary translationによってこ れらを実現
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の肝[要出典]
Tiny Code Generatorの概略 • Tiny Code Generator(TCG)によってDBT を実現 • ゲストのコードを逆アセンブル
• 中間コードに変換 • 中間コードをホストのコードに 変換 Vitaly Chipounov and George Candea. Dynamically Translating x86 to LLVM using QEMU. In EPFL, 2010.
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
TCG Guest Code TCG Operations Host Code gen_intermediate_code() tcg_gen_code() •
target-[architecture] /translate.c • tcg/tcg.c QEMU Internals
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
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
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
TCG • Translation Block(TB) – translate-all.hで定義されたBasic Block – 分岐命令かページの境界まででコードを区切る •
コードキャッシュからreturnしていると遅くな るため、TBを繋げて実行 • なんかLLVMっぽくないですか?
QEMUのDBT(TCG)で何ができるか • バイナリをLLVMに逆コンパイル – S2E[ASPLOS11]
S2E • s2e.epfl.ch • WindowsバイナリをLLVM bitcodeに変換する
S2EにおけるDBT Vitaly Chipounov and George Candea. Dynamically Translating x86 to
LLVM using QEMU. In EPFL, 2010.
S2EにおけるDBT • x86とLLVM bitcodeの間にあるsemantic gapを どうするか? – Dagger(dagger.repzret.org)はオレオレIRを実装 • S2EはTCGで参照される辞書にLLVMの命令を
登録 • LLVM bitcodeに変換されたバイナリを KLEE[OSDI08]に投げる
KLEE • 与えられたソースコードをLLVMでビルド • Symbolic executionからテストケースを生成 • Coreutilsに試したところ、15年に渡る手動テス トを上回るカバレッジを89時間で達成!
Symbolic execution • 記号実行と訳される • 変数に代数シンボルを与えて監視 • プログラムはある結果に収束するか • どの入力値でどの実行パスを通るか
• 条件分岐に行き当たる度に分岐が実行可能か SAT solverに解かせる • あらゆる実行パスを通りたい
SAT solver • ブール式の充足可能性問題を解くプログラム • 式は連言標準形(CNF)で与えられる ( a1 or !a2
or a3 ... or an) and ( b1 or b2 or !b3 ... or !bn) and … – リテラル: a1や!a2といった命題変数またはその否定 – 節: 複数のリテラルの選言(or) – CNF式: 複数の節の連言(and)
SAT solver • ベースになっているのはDPLLアルゴリズム – 変数に値を代入して矛盾が起きるまで探索 – ヒューリスティックに変数を選択 – 分割規則を適用、再帰的な二分探索
– 式を満たす変数割当が見つかればSAT
KLEEのSAT solver • KLEEはSTPを使用 – 前身のEXE[CCS06]のために開発された – 厳密にはSAT solverの上位版であるSMT solver
• SMT solver – ブール式に加えて「背景理論」をサポートす • 配列 • ビットベクトル • etc …
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)
S2Eのまとめ • x86とLLVM bitcodeの間にあるsemantic gapを QEMUで克服 • Windowsバイナリに対してsymbolic execution を通じてテストケースを生成
• LLVMデコンパイラとして使える
LLVMデコンパイラで何ができるか • Windowsバイナリからテストケース生成 – S2E[ASPLOS11] • マルウェアの難読化を解除する – OptiCode[Syscan13]
OptiCode • バイナリをLLVM bitcodeに変換 – QEMUを用いたのかどうかは不明 • LLVMの最適化パスによって難読化を除去 – レジスタに無意味な値を挿入する難読化
• -dse, -simplifycfg – NOPと等価の命令を挿入する難読化 • -constprop, -instcombine – レジスタへの代入をばらけさせる難読化 • -instcombine – etc …
OptiCode • Opaque predicateへの対応 – LLVMによる最適化では解除できない – 常に真(偽)となる条件文を挿入、 実行されない箇所にコードを配置するというもの –
LLVM bitcodeに対してsymbolic execution – OptiCodeではSMT solverにZ3を使用
OptiCodeのまとめ • マルウェアをLLVM bitcodeに逆コンパイル • LLVMの最適化パスをそのまま難読化の解除に 使える • LLVM bitcodeに逆コンパイルできれば
symbolic executionで難読化の解除もできる
まとめ • QEMUはアーキテクチャ間のコード変換を実現 • LLVMへの逆コンパイルとsymbolic execution への適用 • QEMUのDBTがあって良かったね