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

Hypervisor.framework(HVF)の中身

 Hypervisor.framework(HVF)の中身

87ff69458c87fb9b2bfdfa9574375d95?s=128

Mach0xFF

June 06, 2020
Tweet

Transcript

  1. Hypervisor.framework(HVF) の中身を見る(仮)

  2. % whoami - M6M [@Mach0xFF] (/mɑːkɒf/, /mʌkɒf/) - https://wiki.m6m.dev -

    Wiki形式の情報アウトプット先 - 今回の発表が正直HVFではなくXNUのkextよりの話になってしまった希ガス - ごめんなさい
  3. 目次 1. 前置き 2. Hypervisor.framework と AppleHV.kext a. Framework b.

    Kernel extension (kext) 3. macOS(x86_64)のシステムコール 4. カーネル空間の視点から 5. ユーザ空間の視点から
  4. 前置き

  5. 前置き - Hypervisor.framework (HVF) - HVFはQEMUのソースコード内で用いられている略称 - AHFという略称も見かける - Apple製ハイパーバイザ

    for x86_64 macOS - “Build virtualization solutions on top of a lightweight hypervisor, without the need for third-party kernel extensions.” - 3rdパーティ製のハイパーバイザ(Intel HAXM)などは個々にKernel extensionが必要    (e.g. /Library/Extensions/intelhaxm.kext/Contents/MacOS/intelhaxm) - 最初からKextとして組み込むことで, ユーザが3rd party kextを手動でロードする手間を省く (締め出し) - 動機: どうやって動作しているのか理解したかった
  6. Hypervisor.framework と AppleHV.kext

  7. Hypervisor.framework と AppleHV.kext - 前者はユーザ空間におけるFramework(ライブラリ)(Ring 3), 後者は Kernel extension(Ring 0)

    - /System/Library/Frameworks/Hypervisor.framework/Versions/A/Hypervisor - /System/Library/Extensions/AppleHV.kext/Contents/MacOS/AppleHV - Intel VMXの命令が必要 - カーネル空間の機能を使うため, システムコールを通してやりとりする - C.f. KVM, ioctl(fd, KVM_CREATE_VM, 0);
  8. Framework - ユーザ空間からSYSCALL 命令を通してカーネルのAPIを利用させる - macOS 10.15でAPIに変更(追加)が入った模様 - ヘッダファイルを見ると, 10.15で追加されたAPIが存在することがみてとれる

    - hv_capability No overview available.
  9. Kernel extension(kext) - (TL;DR) ドライバ - LinuxのKernel moduleに相当 - kextstat

    コマンドでロード済みのkext一覧を表示できる(後述) - 必要不可欠なkextは出荷時にあらかじめカーネルにリンクされている    (Prelinkedkernel)
  10. macOS(x86_64)のシステムコール

  11. macOS(x86_64)のシステムコール [1/2] - XNUがHybrid(monolithic + micro)カーネルであるため, それぞれの側面に 対してAPIを提供する必要がある - 異なる種類のシステムコール

    → 入口を分けるという選択 - IA32ではソフトウェア割り込み(INT 命令)でCPL3からCPL0へ - BSD側は引数に0x80, Mach側は0x81をとる(異なるIDT entry) - NeXTがAppleに買収されてMac OS Xの開発が始まったとき, Mac OS 9と同じ 当時の製品向けPowerPC版と, NeXTSTEPと同じx86版が並行開発されていた - “Mac OS X has been leading a secret double life for the past five years.” - Steve Jobs, WWDC 2005 - 各アーキ依存のシステムコールが必要に - 第3のシステムコール, Machdep(Machine dependent)
  12. macOS(x86_64)のシステムコール [2/2] - IA32では前述のINT 命令に0x82をとらせる - x86_64ではSYSCALL 命令でCPL3 → 0へ移行するが,

    引数を取らない - SYSCALL_CLASS - System call番号(%RAX)の上位バイトでMach(1), Unix(2), Machdep(3), Diagnostic(4)を判定 - HVFは現状x86_64にのみ実装されている - MachdepシステムコールとしてHypervisorのAPIを提供 - HV関連は2種類 - %RAX ← 0x3000000 (hv_vm_* 系)%RAX ← 0x3000001(hv_vcpu_* 系) - %RDI 以降のレジスタに可変長引数をとる - 理屈の上では%RAXレジスタのビット[31:24]の部分がSYSCALL_CLASSとし て扱われているので, 各クラスごとに十分な数のエントリを持つsyscall table を構築できる.
  13. None
  14. カーネル空間の視点から [1/2] - AppleHV.kext はすでにカーネルに静的リンクされている - 起動時にkxld (Kernel eXtension LoaDer)でアドレス空間にロード

    - 各kextの__DATA.__mod_init_funcセクションに格納された関数ポインタを 実行
  15. カーネル空間の視点から [2/2] - AppleHV::start() が実行される - 内部でAppleHV::enable_traps() が呼ばれる. - XNUのソース内でTrap

    tableの初期化 - XNUのカーネル本体で先に空の構造体が作られる - Trap tableを設定(hv_set_traps) - hv_vm_t::get_traps (hv_vm_*系統) - hv_vmx_vm_t::get_traps - hv_vmx_vm_t::task_traps - hv_vcpu_t::get_traps (hv_cpu_*系統) - hv_vmx_vcpu_t::get_traps - hv_vmx_vcpu_t::task_traps
  16. None
  17. ユーザ空間の視点から - Kextがロードされたことで, HVF関連のシステムコールハンドラが登録された - 理論上はFrameworkなしで, アセンブリだけでHVFが使えるのでは? - 間に合いませんでした -

    もしできたらWiki更新します movl $0x3000000, %eax xorl %edi, %edi syscall
  18. matome - Hypervisor.frameworkもXNUのトリッキーな構造に隠れてはいるが, システ ムコールでHypervisorのAPIを使うのはKVMなどと変わらない. - 最新のXNUソースでは, ARM64(AArch64)のEL2に言及するコードが登場 - A13チップ搭載のデバイスにImplementation

    defined レジスタが存在する模様 - 現状 CTRR という機能のために存在(おそらく何かしらのRegionをReadonlyにする) - 将来的にARM64のXNUでもHypervisorが使えるようになる可能性? - このスライドはARM Macが発表されたら焚書してください
  19. Reference J. Levin, MacOS and iOS Internals, vol. 2. Technologeeks.com,

    2019. A. Singh, Mac OS X internals: A Systems Approach. Addison-Wesley, 2010. Apple Inc, “Source Browser,” XNU - Apple Open Source. [Online]. Available: https://opensource.apple.com/source/xnu/xnu-6153.81.5/. [Accessed: 06-Jun-2020].