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

Apple Silicon HVF

Mach0xFF
July 10, 2021
770

Apple Silicon HVF

Kernel/VM Online Part3 LT

Mach0xFF

July 10, 2021
Tweet

Transcript

  1. 作ろうとしたもの - keystone engineとHVFを組み合わせたA64アセンブリ(ARM64)のREPL - 先に言うとREPLはできていません - Linux用にptraceベースな既存のものが存在する - https://github.com/yrp604/rappel

    - A64命令、少し複雑なものが多々ある(UBFX, BICS, FJCVTZS) - 必要に応じて命令を実行してくれるツールがあったらいいなあ - アセンブリ書いたファイル読み込ませてレジスタダンプするところまではできた
  2. Apple A14/M1チップ - μArchは基本同じ - Firestorm (big/p-core) / Icestorm (LITTLE/e-core)

    - A14 for iOS devices、M1 for macOS/iPadOS devices - A14/M1チップ上ではEL2によるXNU(カーネル)の動作モードが存在する - これは以下のことからわかる - XNUで(実質的に)最初に実行される関数 start_first_cpuで、HCR_EL2レジスタに E2H (EL2 Host, bit 34)が設定される - その裏付けとして、EL2動作時に*_EL1システムレジスタに( re-routeされずに)アクセスするための *_EL12レジスタが実装され、読み書き( MRS/MSR)されている - Hypervisorが実装されている以上、どこかしらで EL2による動作が必要
  3. - SVC命令によるExc発生→Synchronous exception from Lower EL using AArch64 - ESR_EL1(Exception

    Syndrome Register EL1)の値からExcの要因を取得 - EL2で動作している場合、ESR_EL2にre-routingされる(はず) - SVC命令によるものだとKernelが判定→handle_svc()関数へ - UserがX16に入れたSyscall numberをint trap_noとして取得 - 基本的に正ならUnix、負ならMach - 例外として (osfmk/mach/arm/traps.h) - MACH_ARM_TRAP_ABSTIME (-3) - MACH_ARM_TRAP_CONTTIME (-4) - xnuのソースコードにはここまでしか書かれていないが…
  4. Entitlements - ところでApple Silicon HVFを使うには実行ファイルを署名した上で、必要な Entitlementsを付与する必要がある - Entitlements: 実行ファイルが「何か権限の必要なこと」を行う際に必要となる、Plist形式のデータ -

    PlistはとりあえずXMLと考えて構わない - XNUが認識するVM作成に関するEntitlementsは以下の3つ - (1) com.apple.security.hypervisor - (2) com.apple.private.hypervisor.vmapple - (3) com.apple.private.hypervisor - 公式には(1)のみ存在することになっている( VM作成ならこれで事足りる) - https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_hypervisor - カーネル内部では(2)・(3)のEntitlementsの有無も確認する - 許可される最大のISAのレベルが変化する - HVF経由だと(1)しか作れない(hv_vm_create()に適切な引数を渡す必要あり) - ただしcom.apple.privateで始まるため、通常起動時はこの権限を付与したバイナリは実行を拒否される - 具体的には、amfidというデーモンにSIGKILLされる
  5. 迂回路 (boot-args) - 迂回路はある - boot-argsに “amfi_get_out_of_my_way=1” を設定 - %

    sudo nvram boot-args=... - これやるとセキュリティ的によろしくない状態になる - ソフトウェアやドライバが動かなくなることもしばしば - 実験が終わったら元に戻しましょう - こうするとamfidによるチェックが行われなくなるため、先述の(2)•(3)の Entitlementsを付与可能 - (1)•(2)•(3)は具体的にどう違うのか?
  6. Hidden HVF API - _hv_capability(uint64_t cap, uint64_t *out) - 引数名は適当

    - Hypervisor.frameworkのヘッダファイルに存在しない API - 共有ライブラリにシンボルとして存在する - 内部ではX0レジスタに#0を設定した上でSVCをする - 先程の3種のEntitlementsをそれぞれ設定して呼び出してみる
  7. HACR_EL2 - control_hacr だけ異なっている - hacr → Hypervisor Auxiliary Control

    Register - 64-bitレジスタ、内容はIMPLEMENTATION DEFINED - すなわちコア実装による - (2)•(3)ではbit 0がセットされている - このビットに何か秘密がある? - カーネルを読んでみたが、まだ詳細は不明 …
  8. vmapple - ...vmappleのEntitlementを付与するとAppleのIMPLEMENTATION DEFINEDなシステム レジスタが使える…? - https://blog.svenpeter.dev/posts/m1_sprr_gxf/#open-questions - https://twitter.com/never_released/status/1390394188395597831 -

    システムレジスタの値を取得するには - hv_vcpu_get_sys_reg(hv_vcpu_t vcpu, hv_sys_reg_t reg, uint64_t *value) - ただし、ヘッダファイルには reg (uint16_t) としてIMPLEMENTATION DEFINEDレジスタはない - 各種Entitlementsを付与しても、エラー発生せずに取得できるシステムレジスタに変化はなかった - 内部で呼ばれるSyscallを使って取得できる? - 該当Syscallの引数が固定されている - カーネル内部の構造体に、r/wが許可されるsysregを設定するフィールドがあるっぽい - (時間切れ)