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
Apple Silicon HVF
Search
Mach0xFF
July 10, 2021
0
790
Apple Silicon HVF
Kernel/VM Online Part3 LT
Mach0xFF
July 10, 2021
Tweet
Share
More Decks by Mach0xFF
See All by Mach0xFF
Hypervisor.framework(HVF)の中身
mach0xff
2
1.6k
Featured
See All Featured
Building a Scalable Design System with Sketch
lauravandoore
460
33k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
How to train your dragon (web standard)
notwaldorf
89
5.8k
Statistics for Hackers
jakevdp
797
220k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
28
2.2k
Building Applications with DynamoDB
mza
93
6.2k
Typedesign – Prime Four
hannesfritz
40
2.5k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.8k
Agile that works and the tools we love
rasmusluckow
328
21k
Fireside Chat
paigeccino
34
3.1k
Become a Pro
speakerdeck
PRO
26
5.1k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.2k
Transcript
Apple Silicon HVF K/VM Online Part3
% whoami - M6Mです(Mach0xFFです) - 前回も似たようなテーマだった - ごめんなさい
作ろうとしたもの - keystone engineとHVFを組み合わせたA64アセンブリ(ARM64)のREPL - 先に言うとREPLはできていません - Linux用にptraceベースな既存のものが存在する - https://github.com/yrp604/rappel
- A64命令、少し複雑なものが多々ある(UBFX, BICS, FJCVTZS) - 必要に応じて命令を実行してくれるツールがあったらいいなあ - アセンブリ書いたファイル読み込ませてレジスタダンプするところまではできた
← x2 = x0 & ~x1
ここからは - ここからはHVFの実装について調査した結果を書きます - REPLもどきは一度忘れてください
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による動作が必要
hv_vm_create
hv_trap - X16レジスタに(-5)を入れてSVC - カーネルではどうなるか
- 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のソースコードにはここまでしか書かれていないが…
- macOS 11.3のカーネル、handle_svc()に該当するDisassembly - CMN (CoMpare Negative)命令によりtrap_noを(-5)と比較 - この部分はまだオープンになっていない
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される
迂回路 (boot-args) - 迂回路はある - boot-argsに “amfi_get_out_of_my_way=1” を設定 - %
sudo nvram boot-args=... - これやるとセキュリティ的によろしくない状態になる - ソフトウェアやドライバが動かなくなることもしばしば - 実験が終わったら元に戻しましょう - こうするとamfidによるチェックが行われなくなるため、先述の(2)•(3)の Entitlementsを付与可能 - (1)•(2)•(3)は具体的にどう違うのか?
Hidden HVF API - _hv_capability(uint64_t cap, uint64_t *out) - 引数名は適当
- Hypervisor.frameworkのヘッダファイルに存在しない API - 共有ライブラリにシンボルとして存在する - 内部ではX0レジスタに#0を設定した上でSVCをする - 先程の3種のEntitlementsをそれぞれ設定して呼び出してみる
None
None
HACR_EL2 - control_hacr だけ異なっている - hacr → Hypervisor Auxiliary Control
Register - 64-bitレジスタ、内容はIMPLEMENTATION DEFINED - すなわちコア実装による - (2)•(3)ではbit 0がセットされている - このビットに何か秘密がある? - カーネルを読んでみたが、まだ詳細は不明 …
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を設定するフィールドがあるっぽい - (時間切れ)
- まとまりのない話になってしまった - 将来的に(privateが外れて)vmappleのEntitlementが解放されたら嬉しい - Apple Silicon VMWareとかParallelsはこのEntitlementを使って開発されてそう - 調査継続します(REPLも作りたい)