Ảo hóa iOS trên Apple Silicon
(nickb.website)- Đây là một thử nghiệm dùng Virtualization.framework trên Mac Apple silicon và môi trường vma2 để khởi động bản dựng iOS 15.0.2 cho iPhone XR tới
PreBoard.app - Điểm cốt lõi của cách tiếp cận là tái sử dụng chuỗi khởi động của macOS 12.0.1 và chỉ thay thế image hệ thống iOS,
mtree,root_hash,trustcache, nhằm giảm gánh nặng sửa đổi chuỗi khởi động giai đoạn đầu - Khi hạ VM xuống trạng thái CPFM
01bằng lệnh gọi không công khai_setProductionModeEnabled(false), TSS sẽ ký firmware tùy ý cho thiết bị vma2 công khai, làm giảm nhu cầu dùng phương pháp vma2pwn trước đây - Để khởi động thực tế cần các bản vá kernel và hệ thống đụng tới kiểm tra nền tảng của XNU, system keybag, kiểm tra kích thước IOMFB, ramdisk,
launchd,mount, DYLD shared cache,lockdownd,mobileactivationd - Vấn đề lớn nhất còn chưa giải quyết là khả năng tương thích system keybag; cũng chưa xác nhận liệu nhập liệu cảm ứng có thể thực hiện qua API không công khai của Virtualization.framework hay không
Mục tiêu và điểm xuất phát của thử nghiệm
- Sau quá trình chuyển sang Apple silicon và Mac Catalyst, iOS và macOS đã gần nhau hơn; khi ảo hóa macOS trở nên khả thi, câu hỏi cốt lõi là liệu iOS cũng có thể được ảo hóa bằng cách sửa đổi chuỗi khởi động cùng họ hay không
- Công việc trước đó, vma2pwn, là dự án tạo chuỗi khởi động macOS vma2 có thể chỉnh sửa cho VM khách macOS, và trở thành nền tảng cho thử nghiệm lần này
- Một ví dụ công khai đã hoàn chỉnh về ảo hóa/mô phỏng iOS là sản phẩm virtual iPhone cloud của Corellium
- qemu-t8030, các công việc dựa trên QEMU và bài viết của Zhuowei Zhang cũng được tham khảo; đặc biệt, mối quan hệ giữa
IOSurfaceRootcủa macOS vàIOCoreSurfaceRootcủa iOS đã giúp ích cho việc tìm kiếm các bản vá kernel về sau - Bài viết của Zhuowei Zhang cho rằng ứng dụng macOS GUI không thể chạy trên iOS, nhưng ứng dụng iOS đồ họa có thể chạy trên macOS; tính chất này cũng áp dụng cho phần lớn hệ thống đồ họa iOS
Các tính năng không công khai của Virtualization.framework
- Virtualization.framework của Apple có hàm private chưa được tài liệu hóa
_setProductionModeEnabled(false) - Lệnh gọi này cùng chức năng tương ứng trong cấu hình VM hạ VM xuống Chip Fuse Mode CPFM
01, cấu hình thiết bị ảo ở trạng thái vừa “secure” vừa “non-production” - Trên thiết bị vật lý, TSS từ chối ký SHSH blob cần thiết cho các thiết bị non-production/non-secure như CPFM
00hoặc01 - Với thiết bị vma2 công khai, TSS ký firmware tùy ý được cung cấp, nên nhu cầu dùng phương pháp vma2pwn để tạo chuỗi firmware đã sửa đổi giảm đi đáng kể
Cách cấu hình VM iOS
- Cách tiếp cận thành công nhất là dùng nguyên chuỗi khởi động macOS 12.0.1, rồi thay image OS hệ thống bằng image và các tệp liên quan của bản dựng iOS 15.0.2 cho iPhone XR
- Các mục được thay thế là image hệ thống,
mtree,root_hash,trustcache - Cách này tránh được phần lớn nhu cầu sửa đổi chuỗi khởi động và ramdisk khôi phục ở giai đoạn trước khi iOS khởi tạo
- Các mục được thay thế là image hệ thống,
- Bản dựng iPhone XR được chọn vì hỗ trợ arm64e và khả năng có độ phân giải thấp
- Các cấu hình thiết bị arm64e khác cũng có thể thành công, nhưng kernel vma2 được hardcode để trả về
"iPad8,6"cho một số khóa sysctl - Bản dựng arm64 gặp thêm vấn đề và không tương thích nhị phân, nên được đánh giá là ít đáng thử
- Để chạy VM, thử nghiệm dùng super-tart, một fork của tart, ứng dụng bên thứ ba để quản lý VM Apple silicon
- super-tart cho phép dùng các tính năng không công khai cần thiết của Virtualization.framework
- Một số thay đổi, như thay đổi thiết lập
_setProductionModeEnabled(false), hiện chưa được push đầy đủ - Công cụ Virtualization.framework dùng private API cần tắt SIP, và có thể cũng cần tắt AMFI
- Công cụ khôi phục được dùng là một fork của idevicerestore
Bản vá kernel
- Có thể cần các bản vá kiểm tra chữ ký đã dùng trong vma2pwn, nhưng với cách CPFM
01thì chưa chắc có bắt buộc hay không - Các bản vá liên quan đến chữ ký trong kernel vma2 có dạng làm cho các hàm sau trả về 0
_apfs_extract_root_hash_arm_authenticate_root_hash__img4_firmware_property_callback_is_root_hash_authentication_required_img4_firmware_evaluate
- Cần vá
lookup_in_static_trust_cacheđể trả về 1 - Vì binary iOS không phải binary nền tảng simulator, ban đầu chúng bị kết thúc với lỗi
EXEC, [0xe] Binary with wrong platform- Vấn đề được giải quyết bằng cách vá để bỏ qua dòng kiểm tra
PLATFORM_IOScủa XNU - Trên kernel vma2, việc này được áp dụng bằng cách đổi
B.NEthànhB
- Vấn đề được giải quyết bằng cách vá để bỏ qua dòng kiểm tra
- Do không tương thích system keybag,
PreBoard.apphiển thị “Swipe up to upgrade.” thay vìSetup.app- Nếu áp dụng hai bản vá cho
ipc_make_system_keybagđể ép hàm không trả về lỗi, có thể đi tớiPreBoard.app - Giới hạn này vẫn chưa được giải quyết hoàn toàn
- Nếu áp dụng hai bản vá cho
- Sự không khớp kích thước struct IOMFB giữa framework hệ thống iOS và kernel macOS gây kernel panic kèm chuỗi
CLCDTransaction size mismatch. Returning error 0x%X.- Nếu loại bỏ kiểm tra kích thước trong
IOMobileFramebufferUserClient::swap_submit, panic sẽ dừng
- Nếu loại bỏ kiểm tra kích thước trong
Chuẩn bị vá tệp hệ thống
- Ramdisk khôi phục và các tệp hệ thống iOS đều được ký, nên nếu không ký lại sau khi vá, chúng sẽ bị kết thúc khi chạy
- Trong môi trường chỉnh sửa, khuyến nghị dùng
ldidcủa Procursus- Ví dụ cài đặt:
brew install ldid-procursus - Ví dụ ký lại:
ldid_macosx_arm64 -S -M <binary> -Spseudo-sign binary, còn-Mgiữ nguyên entitlements hiện có
- Ví dụ cài đặt:
- Nhiều binary kiểm tra identity, nên trước khi ký lại cần đổi tên thành identity rồi đổi lại tên ban đầu
keybagdxác nhậnIdentifier=com.apple.keybagdbằngcodesign -d -v keybagdmv keybagd com.apple.keybagdldid_macosx_arm64 -S -M com.apple.keybagdmv com.apple.keybagd keybagd
- Các hàm không tự động được gắn symbol có thể tìm bằng cách tìm XRef của chuỗi, rồi lần theo hàm gọi thông qua tham chiếu tới lời gọi logging
- Có thể port Bash và LaunchDaemon để có shell tương tác trên serial terminal
- Cách được dùng là sao chép các tệp liên quan từ payload jailbreak iOS tương thích phiên bản như Procursus
Sửa DMG và ramdisk
- Để vá hệ thống hoặc ramdisk khôi phục, cần sửa trực tiếp volume DMG
- Trong ví dụ iOS 15.0.2, iOS System volume trong IPSW được chuyển sang dạng có thể đọc/ghi
hdiutil convert -format UDRW -o 018-66258-074-rw.dmg 018-66258-074.dmg- Sau khi mount:
sudo mount -uw /Volumes/Sky19A404.N104N841OS - Sau khi sửa:
hdiutil convert -format ULFO -o 018-66258-074.dmg 018-66258-074-rw.dmg - Sau đó:
asr imagescan --source 018-66258-074.dmg
- Trước khi khởi động iOS, cần sửa
/usr/local/bin/restored_externaltrong ramdisk khôi phục- Phiên bản iOS của
restored_externalcố tạo system keybag bằngMKBKeyBagCreateSystem, nhưng không tương thích với kernel macOS - Bỏ qua bằng cách loại bỏ kiểm tra lỗi
- Vá điều kiện gọi
ramrod_set_NVRAM_variableđể đặtallow-root-hash-mismatchthành true, tức1, và bỏ qua xác thực root hash
- Phiên bản iOS của
- Cũng cần sửa
/usr/sbin/asrtrong ramdisk khôi phục- Có thể dùng asr64_patcher của iSuns9
- Tìm hàm in chuỗi
"Image failed signature verification.", rồi trong hàm tham chiếu tới nó, đổi lệnh gọi ARMv8-ABLthành nhảyBtới đường dẫn"Image passed signature verification" - Trong binary
asrcủa iOS 15.0.2, áp dụngb #0x7ctại file offset0x27A18
Sửa volume hệ thống iOS
- Để bản thân iOS khớp với kernel macOS, cần chuyển phần lớn các tệp sẽ được cài vào filesystem root từ system volume sang
/System/Library/Templates/Data - Khi hệ thống khởi động, các tệp này sẽ tồn tại ở
/ - Các thư mục rỗng ở root thông thường có thể vẫn cần tồn tại trong system volume ngay cả khi thực sự rỗng
- Ví dụ là
/Applications - Phần này chưa được kiểm thử đầy đủ
- Ví dụ là
Vá launchd và keybagd
- Ở giai đoạn đầu khởi động iOS,
/sbin/launchdđược chạy; để bắt đầu quá trình khởi động ban đầu mà không lỗi, cần vá nó - Bản vá đầu tiên được áp dụng cho plist cấu hình nhúng trong binary
- Tìm chuỗi
<key>SIGTERMTimeout</key>và nhìn lùi khoảng 172 byte để thấy cấu hình tương ứng - Thêm
<key>PerformAfterUserspaceReboot</key><true/>vào các mụcmount-phase-2,fips,tzinit,finish-demo-restore,fud,xpcroleaccountd,prng_seedctl,MSUEarlyBootTask - Đổi
RequireSuccesstrong mụcdata-protectionthành<false/>
- Tìm chuỗi
- Thay đổi
data-protectionlà cần thiết vì/usr/libexec/init_data_protectionthất bại khi chạy trong VM- Tệp đó là symbolic link tới
/usr/libexec/seputil
- Tệp đó là symbolic link tới
- Thay đổi plist nhúng có thể vượt quá không gian chuỗi hiện có, nên có thể dùng XML minimizer để nén XML rồi dán vào, sau đó ghi đè vùng còn lại bằng ký tự khoảng trắng thân thiện với XML
launchdcũng khởi tạo/usr/libexec/keybagd, nhưng binary này thất bại do khác biệt kernel nêu trên- Một cách bỏ qua là biên dịch một executable chỉ thoát với exit code 0 để thay thế
keybagd - Dự án fixkeybag cũng đã được xem xét, nhưng mã tạo system keybag của app đó cũng gọi
MKBKeyBagCreateSystem, nên vẫn thất bại ngay cả trong trạng thái iOS đã khởi động
- Một cách bỏ qua là biên dịch một executable chỉ thoát với exit code 0 để thay thế
launchdcần thêm bản vá để NOP nhánh điều kiệnTBZgây chuỗi panicUserspace reboot changed system version: previous %s != current %s
Sửa mount, DYLD shared cache và tầng đồ họa
- Vì quá trình khôi phục được xử lý bằng chuỗi khởi động macOS và ramdisk macOS,
/sbin/mountcủa iOS không xử lý đúng các APFS volume được tạo - Giải pháp là lấy binary
mounttừ system volume macOS, sửa metadata Mach-O để có thể chạy trên iOS, rồi thay thế- Có thể làm thủ công, hoặc dùng
vtoolcó sẵn trong macOS
- Có thể làm thủ công, hoặc dùng
- Bản sửa khó hơn là vá DYLD shared cache
IOSurfaceRootcủa macOS vàIOCoreSurfaceRootcủa iOS về cơ bản là cùng một driver, nhưng không tương thích do khác tên- Trong DYLD shared cache của iOS có chuỗi dài hơn
"IOCoreSurfaceRoot", nên đổi chuỗi này thành"IOSurfaceRoot"và lấp các byte còn lại bằng0x00
- Công cụ ipsw của blacktop được dùng để phân tích và trích xuất DYLD shared cache
- Tách dylib nhúng bằng
ipsw dyld split <dsc file> - Trong binary
/System/Library/Frameworks/IOSurface.framework/IOSurface, tìm tham chiếu"IOCoreSurfaceRoot"của hàm__iosConnectInitalize - Chuyển địa chỉ ảo thành file offset bằng
ipsw dyld a2o - Trong ví dụ, patch offset
0x28fde373củadyld_shared_cache_arm64e
- Tách dylib nhúng bằng
- Sau khi sửa DYLD shared cache, cdhash ở vị trí khác không khớp nên phát sinh exception
- Dùng GDB stub do frontend Virtualization.framework cung cấp để đặt breakpoint vào hàm
cs_validate_hashcủa kernel và xác định toàn bộ cdhash - Trong ví dụ iOS 15.0.2, vá các byte cũ tại file offset
0x5a9cffc0bằng cdhash mới
- Dùng GDB stub do frontend Virtualization.framework cung cấp để đặt breakpoint vào hàm
Vá daemon hệ thống và activation
watchdogdkiểm tra liệu nó có đang chạy trong VM không và gây crash-loop vì không có code path macOS để thoát bình thường, nhưng crash này được coi là không gây hại- Với
backboardd, đã thử vá các lệnh gọi liên quan đến di trú dữ liệu có thể kích hoạtPreBoard.app, nhưng không thấy khác biệt ngoài việc dừng ở logo Apple - Trong hàm
get_device_type_internal_block_invokecủalockdownd, lệnh gọigetMGIntcho"ShouldHactivate"được vá thànhmov x0, #1để ép hactivation, qua đó bỏ qua hạn chế activation iOS thông thường trong môi trường phát triển mobileactivationdcũng có thể được vá để cho phép hactivation- Đổi hàm
shouldHactivatethành các lệnh ARMv8-Amov x0, #0vàret
- Đổi hàm
- Các sửa đổi bổ sung cần thiết cho vma2 device tree được để lại như bài tập cho người đọc
- Một số hành vi có thể cần biện pháp bất thường như
chmod -R 777 /
Các giới hạn còn lại và nhập liệu cảm ứng
- Để vượt qua vấn đề system keybag, cần hiểu thêm cấu trúc tương ứng trong hệ thống iOS và kernel, rồi tạo thêm bản vá
- Dự án đã tốn ít nhất vài trăm giờ, và trạng thái tiến triển công khai hiện tại là khởi động tới
PreBoard.app - Chưa xác nhận liệu chức năng cảm ứng có hoạt động thông qua kernel và firmware Mac vma2 công khai hay không
- Virtualization.framework có các API không công khai liên quan tới cảm ứng
_VZAppleTouchScreenConfiguration_VZUSBTouchScreenConfiguration_VZTouch_VZMultiTouchEvent
- Các API này có thể gửi sự kiện cảm ứng, nhưng cách dùng tham số chính xác chưa được nắm rõ hoàn toàn
- enum
TouchPhaselà enum đơn giản triển khai các giá trị cùng tên vớiNSTouch.Phase - Mã ví dụ đôi khi có thể tạo exception
- Chưa xác nhận các giá trị tọa độ có được ánh xạ theo cách VM kỳ vọng hay không, cũng như VM có xử lý được chúng hay không
- enum
- Demo cho thấy chuỗi khởi động, trong đó đoạn chờ khoảng 30 giây ở giữa đã được cắt bỏ
1 bình luận
Ý kiến trên Hacker News
Corellium đã thắng trong tranh chấp pháp lý, nên giờ có thể cho thuê VM iOS trên đám mây phục vụ nghiên cứu bảo mật https://hn.algolia.com/?query=corellium
Nếu có thể ảo hóa iOS trên MacBook Apple Silicon, nhu cầu với các dịch vụ ảo hóa iOS thương mại có thể giảm
Mức giá khoảng $400/tháng cho cá nhân, $60.000/năm cho doanh nghiệp https://support.corellium.com/subscriptions/pricing
Hay đấy. Lần tới hy vọng họ cũng tìm ra cách cài macOS lên iPad, để cuối cùng ta có thể dùng được chiếc máy tính đó mà ta vẫn mong Apple làm ra
https://www.theverge.com/2024/7/22/24200536/windows-xp-ipad-...
Mac Catalyst dường như cũng chỉ hoạt động một chiều như dự đoán
Xét về kích thước thì iPad Mini rất ổn, nhưng iPadOS vô dụng, nên hiện tôi đang xem Surface Go. Có điều nó hơi lớn
Tôi biết là không có sản phẩm nào chạy MacOS, nhưng nếu có gợi ý về tablet nhỏ chạy được Win11 thì mong được chỉ giúp. Nếu cần tôi cũng sẵn sàng đặt từ Trung Quốc
Nhìn hồ sơ GitHub của tác giả thì có vẻ vừa là sinh viên tốt nghiệp ngành khoa học máy tính, nhưng đây thực sự là một công trình ấn tượng
Tôi có cảm giác lý do Apple không biến Simulator thành Emulator là vì họ không muốn mọi người đào sâu vào lớp nền bên trong iOS
Sau khi qua bootloader, đặc biệt trong bối cảnh Apple kiểm soát cả phần cứng, tôi tự hỏi liệu có lý do gì để tiếp tục duy trì nhiều khác biệt giữa hai hệ điều hành như vậy không
Người tạo qemu-t8030 đã chạy được SpringBoard https://mastodon.social/@ntrung03/109712247237110967, nhưng không công bố mã nguồn
Nếu tiến triển đó có thể được kết hợp với công trình này thì sẽ rất tuyệt
https://www.xia0.sh/2024/03/09/Boot-Newer-iOS-with-QEMU-Step...
Bình luận trước đây: https://news.ycombinator.com/item?id=40219423
Bài liên quan: https://worthdoingbadly.com/hv/
Nói về máy ảo tăng tốc bằng phần cứng trên iPhone 12 đã jailbreak / iOS 14.1
Hơi lạc đề một chút, nhưng tôi tò mò liệu đã có ai từng ảo hóa ARM macOS trên x86-64 chưa
Vì vậy chỉ có thể ảo hóa hệ điều hành được build cho cùng kiến trúc CPU với hệ thống host
Với các trường hợp còn lại, như chạy phần mềm ARM trên x86 hoặc ngược lại, phải dùng mô phỏng, tức là diễn giải mã hoặc biên dịch lại động
Theo định nghĩa thì thứ gì cũng có thể được mô phỏng trên bất kỳ thứ gì khác. Gần đây còn có trường hợp boot Linux cho MIPS trên Intel 4004, bộ vi xử lý đầu tiên, nhưng hiệu năng có thể là vấn đề
Ảo hóa CPU Mn có lẽ còn ít hữu ích hơn
Apple đã cung cấp iOS Simulator trong Xcode rồi, nên tôi tò mò dự án này tốt hơn công cụ Apple cung cấp ở điểm nào
Ví dụ, bạn không thể lấy một binary iOS từ App Store rồi chạy nguyên trạng trong iOS Simulator, đặc biệt càng không thể trên Intel Mac
Vì Simulator không chạy iOS đầy đủ, bạn cũng không thể khảo sát và học cách nội bộ iOS thật sự hoạt động. Nếu đào đủ sâu vào framework của Simulator, cuối cùng bạn sẽ quay lại macOS
Ngược lại, emulator chạy toàn bộ bản build iOS giống như trên thiết bị thật. Về lý thuyết, nó có thể chạy bất kỳ binary iOS nào mà không cần sửa đổi và cho phép khảo sát cách hệ điều hành thật vận hành
Nó giống khác biệt giữa chạy ứng dụng bằng Wine và chạy ứng dụng trong VM Windows. Tuy nhiên với Simulator, tình huống còn gần với việc phải biên dịch lại và link riêng ứng dụng Windows cho phù hợp với môi trường Wine trước khi chạy hơn
Nếu muốn nghiên cứu nội bộ Windows, chỉ chạy bằng Wine thì không học được nhiều, nhưng khảo sát một VM Windows sẽ học được nhiều hơn rất nhiều
Đây sẽ là món quà Giáng sinh sớm cho các click farm