4 điểm bởi GN⁺ 2025-04-07 | 1 bình luận | Chia sẻ qua WhatsApp

Khởi đầu hành trình giả lập iOS 14 trên QEMU

  • Ban đầu đã dùng dự án mã nguồn mở alephsecurity/xnu-qemu-arm64, nhưng do ở trạng thái chỉ đọc (read-only) nên thiếu khả năng mở rộng
  • Sau đó chuyển sang dự án TrungNguyen1909/qemu-t8030 và có thể tận dụng các tính năng sau:
    • Khôi phục iOS (kèm QEMU đồng hành cho kết nối USB)
    • Chạy iOS 14
    • Dựa trên phiên bản QEMU mới nhất
    • Có tài liệu wiki chi tiết
  • Đã sửa launchd.plist để truy cập shell và SSH thành công, qua đó tạo được điểm khởi đầu tốt
  • Mục tiêu là xây dựng một môi trường giả lập iOS hoàn chỉnh có thể chạy UI và ứng dụng

Vá kernel và đưa PongoOS vào

  • Dự án t8030 có cấu trúc vá kernel ngay bên trong QEMU → phát sinh vấn đề về bảo trì và mở rộng
  • Dựa trên kinh nghiệm jailbreak, đã chuyển sang cấu trúc áp dụng bản vá checkra1n thông qua PongoOS
  • Tăng kích thước SRAM trong QEMU để chạy PongoOS, rồi chèn mô-đun checkra1n-KPF
  • Khi khởi động, do thiếu một số chức năng của bootrom/iboot nên phát sinh lỗi FPU chưa được cấu hình → tham khảo tài liệu ARM để xử lý
  • Từ A13 trở đi, PAC (Pointer Authentication) được đưa vào, khiến một số bản vá mất hiệu lực
  • So sánh nhị phân trước và sau khi PAC được đưa vào bằng ví dụ task_for_pid0 (tfp0)

Phát triển công cụ tự động hóa vá kernel

  • Cách vá động hiện có của checkra1n khó đọc và bất tiện khi sửa đổi → đưa vào phương thức vá dạng khai báo dựa trên văn bản
  • So sánh hai nhị phân Mach-O để trích xuất khác biệt ở mức assembly, sau đó tạo bản vá văn bản
  • Dump bộ nhớ sau khi khởi động bằng Pongo để tái lắp ráp kernel → sắp xếp toàn bộ bản vá vào tệp văn bản và thêm chú thích

Kết xuất đồ họa: Metal so với kết xuất phần mềm

  • iOS thực hiện toàn bộ việc kết xuất UI thông qua API Metal → cần GPU
  • Do giả lập GPU quá phức tạp, đã cân nhắc các phương án thay thế:
    • Kết xuất phần mềm
    • Proxy các lời gọi Metal sang thiết bị thật
  • Trên iOS 14, bootarg gpu=0 đã bị loại bỏ → phân tích QuartzCore và xác nhận cơ chế fallback
  • QuartzCore trên máy đã jailbreak để xác nhận kết xuất phần mềm hoạt động được (dù chậm nhưng khả thi)
  • Cũng đã thử phương án proxy Metal, nhưng dừng lại vì Objective-C và API quá phức tạp

Gỡ lỗi framebuffer và IOSurface

  • t8030 QEMU không có triển khai framebuffer → dùng fork ChefKissInc/QEMUAppleSilicon
  • Khi khởi động ban đầu có hiện logo Apple và thanh tiến trình, nhưng sau đó màn hình đen → bắt đầu gỡ lỗi
  • Kết quả phân tích IOMFB kext cho thấy có hai chế độ:
    • Framebuffer địa chỉ cố định (dùng cho hiển thị ban đầu)
    • Cấu hình đa mặt phẳng dựa trên DMA
  • Trong quá trình hệ thống khởi động, chế độ dựa trên DMA được dùng → kiểm tra việc thiết lập thanh ghi kernel bằng trace của QEMU
  • Tuy vậy, vẫn không có gì được hiển thị trên màn hình

Vô hiệu hóa ngẫu nhiên hóa địa chỉ

  • Có thể tắt ngẫu nhiên hóa địa chỉ kernel trong mã khởi tạo bo mạch
  • Ngẫu nhiên hóa ở không gian người dùng được vô hiệu hóa bằng cách vá _load_machfile
  • Dyld cache là một nhị phân lớn chứa toàn bộ thư viện động → được nạp vào địa chỉ cố định khi khởi động
  • Tạo công cụ C để dlopen, sau đó kiểm tra địa chỉ bằng các hàm _dyld_*
  • Cho phép gỡ lỗi thư viện dyld bằng GDB → đặc biệt quan tâm tới IOMFB, SpringBoard, QuartzCore

Truy cập log USB và vượt qua lockdownd

  • Trên thiết bị thật, có thể thu thập log hệ thống bằng idevicesyslog → cần xác thực USB
  • lockdownd dùng keybag cần SEP để lưu khóa → trình giả lập không có
  • Chèn shellcode vào vị trí hàm hiện có để nạp trực tiếp từ tệp khóa
  • Đã vượt qua xác thực khóa giữa các QEMU kết nối USB → có thể thu thập log
  • Xác nhận QuartzCore khởi tạo bình thường và đang dùng kết xuất phần mềm

Vượt qua PAC (Pointer Authentication)

  • Khi sửa backboardd, phát sinh lỗi PAC → đây là tính năng bảo mật được đưa vào từ ARMv8.3
  • Cách thay lệnh PAC bằng NOP là quá xâm lấn
  • Có thể biên dịch lệnh PAC theo cách tương thích → nếu QEMU bỏ qua PAC thì vẫn chạy được
  • QEMU 7 không thể vượt qua PAC → chuyển sang QEMU 8.2.1
  • Cần chuyển rất nhiều mã tùy biến QEMU như lệnh riêng của Apple, exception level của GL, v.v.
  • Kết quả là đã khởi động thành công iOS trên QEMU 8 và có thể vô hiệu hóa tác động của PAC

Xác nhận backboardd và đầu ra đồ họa

  • backboardd có hoạt động nhưng không hiển thị hình ảnh → có thể do nhiều nguyên nhân
  • Dump bộ nhớ DMA cũng không cho ra nội dung có ý nghĩa
  • Đã xác định địa chỉ trong iosurface_lock và dump frame, nhưng có vẻ dữ liệu được gửi tới GPU ở dạng nén
  • Trên iPhone X (t8015), xác nhận đầu ra không nén → sửa DTB của QEMU để đổi chip-id từ t8030 sang t8015
  • Kết quả là sau khi khởi động, logo Apple được hiển thị

Theo dõi thanh tiến trình và lỗi hệ thống

  • Sau logo, thanh tiến trình màu trắng xuất hiện → dừng ở 90%
  • Qua phân tích log, phát hiện vấn đề ở mobileactivationdSpringBoardFoundation → sau khi vá thì UI thay đổi
  • Để giải quyết hiện tượng bị kẹt ở thanh tiến trình, cần phân tích thêm nhiều log hệ thống

Tự động hóa vá dyld cache và không gian người dùng

  • Tương tự kernel, không gian người dùng cũng dùng phương thức vá dạng văn bản
  • Dyld cache có kích thước 2GB nên rất kém hiệu quả khi sửa trực tiếp → đã cải tiến công cụ nội bộ để:
    • Theo dõi offset trong dyld
    • Vá trực tiếp vào vị trí cụ thể bằng lệnh dd
  • Đồng thời cũng cần bản vá để vượt qua kiểm tra chữ ký kernel

Chạy PreBoard và xác nhận UI

  • Ứng dụng PreBoard là app hệ thống hiển thị khi có lỗi → có thể chạy trực tiếp
  • Thêm máy chủ VNC để thử mở khóa màn hình bằng bàn phím
  • Sau khi mở khóa, framework vImage dùng lệnh AMX (Apple Matrix Coprocessor) → QEMU không hỗ trợ
  • Vá sang đường fallback phần mềm của vImage để giải quyết vấn đề
  • Sau bản vá, đã hiển thị thành công đến màn hình có thể nhập văn bản

Kết luận

  • Đã tiến tới ngay trước khi chạy SpringBoard → việc chạy UI hoàn chỉnh giờ chỉ còn là vấn đề thời gian
  • Đã thực hiện phân tích và vá theo nhiều hướng với kernel, không gian người dùng, đồ họa, và các tính năng bảo mật như PAC
  • Xác nhận tiềm năng tạo ra môi trường thực tế để gỡ lỗi và kiểm thử ứng dụng iOS dựa trên QEMU

1 bình luận

 
GN⁺ 2025-04-07
Ý kiến trên Hacker News
  • Mong rằng dự án https://github.com/devos50/qemu-ios sẽ phát triển đến mức hỗ trợ iPhone OS 3.x. Điều này sẽ giúp có thể trải nghiệm các ứng dụng iPhone đời đầu để phục vụ mục đích bảo tồn số
  • https://github.com/touchHLE/touchHLE cũng rất tuyệt, nhưng ngoài các ứng dụng mặc định thì cần phải vá
  • Đã làm theo hướng dẫn tại https://github.com/TrungNguyen1909/qemu-t8030/… để chạy, nhưng bị crash nhiều lần. Dù vậy vẫn khá ấn tượng
  • Từng mô phỏng NumWorks N0100 và HP Prime G1 bằng QEMU. Kết quả đủ thành công để chạy firmware chính thức
  • Một cách vui để tận dụng dự án này: cài postmarketOS lên một chiếc điện thoại có hỗ trợ phần cứng tốt, rồi dùng QEMU để boot iOS trên điện thoại Android. Có lẽ có thể tùy biến QEMU để chuyển tiếp phần cứng của điện thoại vào iOS VM
  • Tò mò không biết điều này có nghĩa là có thể test Safari và biên dịch iOS trên hệ thống Linux mà không cần phần cứng Apple hay không
  • https://github.com/ChefKissInc/QEMUAppleSilicon
  • Không thấy nhắc gì về kết nối mạng. Có vẻ họ không mô phỏng chipset WiFi hay modem di động. Tò mò không biết cách kết nối thiết bị mô phỏng với Internet là gì. Có thể là kiểu Ethernet qua USB
  • Phiên bản lưu trữ: https://archive.ph/l1CwO
  • Tò mò không biết có kho mã nào để tái hiện việc này hay không
  • Tò mò Apple sẽ cần những gì để chấp nhận phát triển iOS đa nền tảng