越狱iOS无法运行MacOS应用程序。 我花了一个星期,了解为什么

2021-06-08 00:20:56

我通过替换iOS的Dydd共享缓存(所有IOS的代码)与麦斯科斯队的越野,我在越野的iPhone上运行命令行麦斯科斯工具,如Bash和Geekbench。但是,图形应用程序永远不会有效:麦斯科斯州的Windowserver不会启动,因为iOS的驱动程序太不同了。

在另一个WWDC的前夜,是时候反思了与过去3个WWDCS相关的主题:Apple的移动和桌面线之间的融合。

设计:MacOS Big Sur的IOS启发造型,IMACS采用iPhone的方形线和多彩的背部

通过这个统一,许多人想知道:如果完全相同的处理器可以运行麦斯科群岛和iOS,那么停止越狱在iOS上运行麦斯科斯应用程序的越狱?

史蒂夫乔布斯着名宣布iPhone“RAN OS X”。经过一周的工作,我们确定:这是一个谎言。虽然iOS和麦克斯共享一个基础,但他们的司机足以不兼容。

iOS内核/驱动程序的某些部分与MACOS共享。例如,两者都使用与同一UNIX / DARWIN基础的相同内核。

因此,对于运行命令行应用程序,所有我需要做的是: - 用修补的麦斯科斯骨牌替换iOS的Dydd - 用重新签名的麦斯科斯芯片缓存替换iOS的Dydd缓存 - 挂钩调试器中的一些方法

但是,即使在苹果硅,iOS和摩托斯上的许多驱动程序也是不同的。 MacOS图形代码不知道如何与iOS内核/驱动程序交谈,因此图形应用程序无法运行。

还没有办法将iOS内核和驱动程序用MacOS等效物替换:麦斯卡斯仅支持M1设备,而iPhone X的IOS设备没有已知的Bootloader漏洞。

获取IOS上运行的MacoS应用程序将需要一个多年统一项目,其范围与Catalyst的范围相当,或者在VM中隔离MacOS,类似于Mac OS 9在早期OS X上的经典模式中运行的VM中。

这些选择都没有用于越狱,但它们可供Apple。因此,最好的选择是在明天的WWDC中穿过MacOS-On-iOS的手指。

那么如果我试图在越狱手机上运行麦斯科座应用程序会发生什么?

所有测试都在iPhone 12上运行iOS 14.1和Taurine(1.0.4)越狱。麦斯科斯文件从Macos 11.4获取(尽管我用11.3.1进行了早期测试)。

如果我直接在iOS上运行麦克斯应用程序,例如geekbench的命令行版本,它会因为缺少的库而立即错误:

电话:〜root#/ usr / local / lobuowei / geekbench_aarch64ded:警告:无法加载插入的库' /usr/lib/pspawn_payload-stg2.dylib'进入硬化过程,因为没有发现合适的图像。确实发现:/usr/lib/pspawn_payload-stg2.dylib:mach-o,但没有为portoon macos / susr/lib/pspawn_payload-stg2.dylib:mack-o构建,但不是用于平台macosdyld:library未加载库: /system/library/frameworks/carbon.framework/versions/a/carbon来自:/ usr / local / zhuowei / geekbench_aarch64原因:图片不是foundzsh:abort / usr / local / zhuowei / geekbench_aarch64

对于运行的应用程序,我们需要为它们提供摩托斯上可用的所有库。为此,我们需要加载MacOS Dyd Shared Cache。

Dyd Shared Cache是​​IOS或MacOS上所有库的预先链接捆绑包。它由Dyd装载。

/ usr / bin / dyd是动态链接器。程序启动时,内核将该程序和Dyd加载到内存中。然后,Dyd加载程序所需的所有其他库。

DYLD在MYDLD中有多个调试选项,其源头可在线获取。

Dydd共享缓存通常由设备上运行的所有进程共享,但使用两个Dyd标志,我们可以询问Dyd加载自己的共享缓存文件,与其他进程分开。

手机:〜root#dyld_shared_region = private dydd_shared_cache_dir = / usr / local / local / local / local / buuowei / geekbench_aarch64 dyld:dyld缓存加载错误:共享缓存文件是针对不同的平台

此检查是通过ValidatePlatform执行的:我们可以通过强制Machofile :: CurrentPlatform来绕过它来返回平台:: MacOS:

我无法让我的debugserver以暂停模式推出一个应用程序,因此我制作了一个小的助手洛提策划工具,呼叫Posix_spawn与暂停的标志。

Zhuowei-Mac:SRC Zhuowei $ LLDB / BIN / BASH(LLDB)目标创建" / BIN / BASH"当前可执行文件设置为' / bin / bash' (x86_64)。(LLDB)进程连接连接:// localhost:3335Process 858停止*线程#1,停止原因=信号sigstop帧#0:0x00000001025d5000 dyd`_dyld_startdrddle`_dyld_start: - > 0x1025d5000< + 0&gt ;: mov x28,sp 0x1025d5004< sp,x28,#0xfffffffffffff0 0x1025dffffffff0 0x1025d5008< mov x0,#0x0 0x1025d50c< + 12&gt ;: mov x1,#0x0target 0 :( Bash)停止。(LLDB)BYLD`dyld3 :: machofile :: currentplatformbreakpoint 1:其中= dyld`dyld3 :: machofile :: currentplatform(),地址= 0x00000001025fe01c(lldb)cprocess 858 resumingprocess 858停止*线程#1 ,停止原因=断点1.1帧#0:0x00000001025fe01c dyld`dyld3 :: machofile :: currentplatform()dyld`dyld3 :: machofile :: currentplatform: - > 0x1025fe01c< + 0&gt ;: mov w0,#0x2 0x1025fe020< + 4&gt ;: ret dyld`dyld3 :: machofile :: isdylib:0x1025fe024< + 0&gt ;: ldr w8,[x0,#0xc] 0x1025fe028< + 4&gt ;: cmp w8,#0x6; = 0x6目标0 :( bash)停止。(LLDB)线程返回1

通过在CurrentPlatform中返回1(Mac),缓存通过Dyd的检查...但是现在失败了iOS的代码签名检查。

电话:〜root #ddyld_shared_region = private xdyld_shared_cache_dir = / usr / local / zhuowei / system / library / caches / com.apple.dyld./littlespawn / usr / local / zhuowei / bash dyld:dyld缓存加载错误:代码签名注册共享缓存失败

AMFI:' / private / var / root / osdoubler / macos / system / library / dyld / dyld_shared_cache_arm64e'是adhoc签名.amfi:' / private / var / root / osdoubler / macos / system / library / dyld / dyld_shared_cache_arm64e':不适合这个平台/设备的CT策略0,拒绝签名。

ad-hoc签名完全验证在内核中,针对硬编码列表。这意味着牛磺酸,kpp的越狱,不能覆盖签名检查。

我需要用正常开发人员签名重新签名共享缓存。然后,牛磺酸可以拦截验证并指示AMFID守护程序允许执行代码。

令我惊讶的是,Xcode的代码可以签署Dyd高速缓存,即使从未使用过此功能:Dydd Cache Builder始终签署自己的缓存。

我写了一个脚本来删除现有签名并辞职。但是,加载新的缓存导致牛磺琴的大型漏洞在计算签名的Dyld缓存的CDHASH时:

内核exc_resource - >大使误合[449]超过MEM限制:InactiveHard 2098 MB(致命)内核1401.082 MemoryStatus:Killing_specific_Process PID 449 [AmfideBilitate](每次流程限制3)2331079KB - MemoryStatus_available_pages:50117Kernel AMFI:代码签名验证失败。由Jetsam原因杀死每次过程限制

值得庆幸的是,Taurine允许用户通过将其放入/ Taurine / CSTMP来预先编译文件的CDHASH,因此我添加了一个步骤来提取CDHASH。

放置文件后,DYLD缓存已开始加载...直到IOS Dyld设置了一个部分上的错误内存权限:

进程974停止*线程#1,停止原因= exc_bad_access(code = 2,地址= 0x1f53c8000)帧#0:0x0000000100E85524 Dyld`dyld3 :: loaddyldcache(dyld3 :: sharedcacheOptions contr& dyld3 :: sharedCacheloadInfo *)+ 700deD`dyld3 :: loaddyldcache: - > 0x100e85524< + 700> str x8,[x21] 0x100e85528< + 704&gt ;: cbnz x22,0x100e85500; < + 664> 0x100e8552c< + 708&gt ;: b 0x100e85554; < + 748> 0x100E85530< + 712&gt ;:添加x9,x24,w8,uxtwtarget 0 :( bash)停止。(LLDB)打印(VOID *)$ x21(void *)$ 1 = 0x00000001f53c8000

这是一个Kldude:我们以后要更换Dyd。目前,这让我们在Objective-C运行时将DYD陷入了崩溃:

*线程#1,队列=' com.apple.main-thread',停止原因= exc_bad_access(code = 1,地址= 0x7c81fb1d9a80)帧#0:0x000000018fef745c libobjc.a.dylib`addclasstableentry(objc_class * ,bool)+ 32libobjc.a.dylib`addclasstableentry: - > 0x18fef745c< + 32&gt ;: ldr x8,[x0,#0x20] 0x18fef7460< x8,x8,#0x7fffffffff8 0x118fef7464:ldrh w8,[x8,#0x4] 0x18fef7468< + 44&gt ;: ADRP x9,438970target 0 :( bash)停止。(LLDB)BT *线程#1,队列=' com.apple.main-thread',停止原因= exc_bad_access(code = 1,地址= 0x7c81fb1d9a80)*帧#0:0x000000018fef745c libobjc.a.dylib`addclasstableentry(objc_class *,bool)+ 32帧#1:0x000000018fedc5d8 libobjc.a.dylib`_read_images + 2624帧#2:0x000000018fedb54c libobjc.a.dylib`map_images_nolock + 2464帧#3:0x000000018feeccc00 libobjc.a.dylib`map_images + 92帧#4:0x0000000100E65b04 dyld`dyld :: notifagatchpartial(dydd_image_states,bool,char const *(*)(dydd_image_states,unsigned int,dyd_image_info const *),bool ,bool)+ 1672帧#5:0x0000000100e65cf0 dyld`dyld :: greaterobjcnotifiers(void(*)(unsigned int,char const * const *,mach_header const * const *),void(*)(char const *,mach_header const * ),空白(*)(char const *,mach_h eader const *))+ 80帧#6:0x000000019004e224 libdyld.dylib`_dyld_objc_notify_register + 284

地址似乎是奇数:0x7c81fb1d9a80在内存之外,但如果我们删除前三位数,0x1fb1d9a80是一个实际的目标-c类。这些数字来自哪里?

在放置断点后,我发现崩溃呼叫是添加元类的第二个(递归)addClasstableEntry调用。为此,它从ISA指针获取MetaClass:

这在编译时计算。但是,Mach_VM_MAX_ADDRESS在iOS和MACO上不同,因为IOS具有较小的地址空间,并且在PAC签名中使用指针中的更多位。

PAC由内核配置,因此在iOS内核上运行的MacOS应用程序将收到比预期的更多PAC签名位,导致PAC位在屏蔽后留在指针中。

解决方案简单:修补任何ARM64E应用程序,以便作为ARM64启动,禁用PAC。

(LLDB)CProcess 1012 Resuming Process 1012停止*线程#1,队列=' com.apple.main-thread',停止原因= exc_breakpoint(code = 1,子码= 0x182700E70)帧#0:0x0000000182700E70 libsystem_darwin。 dylib`_check_internal_content.cold.1 + 24libsystem_darwin.dylib`_check_internal_content.cold.1: - > 0x182700E70< + 24&gt ;: brk#0x1libsystem_darwin.dylib`os_variant_has_internal_diagnostics.cold.1:0x182700e74< + 0&gt ;: pacibsp 0x182700e78< + 4&gt ;: stp x29,x30,[sp,#-0x10]! 0x182700e7c< + 8&gt ;: mov x29,sptarget 0 :( bash_arm64)停止。(LLDB)BT

拒绝MacOS和iOS存储有关在kern.osvariant_status sysctl变量中构建信息(beta /内部)的信息。 iOS版本有位设置困惑的麦克斯。

手机:〜root#xdyld_shared_region = private xdyld_shared_cache_dir = / usr / local / local / local / local / local / loce / locawei / bash_arm64ded:警告:无法加载插入的库' /usr/lib/pspawn_payload-stg2.dylib&# 39;进入硬化过程,因为没有发现合适的图像。发现:/usr/lib/pspawn_payload-stg2.dylib:mach-o,但不是用于平台macos /usr/lib/pspawn_payload-stg2.dylib:mack-o,但没有为平台macos构建默认交互式shell现在zsh.to更新您的帐户以使用zsh,请运行`chsh -s /bin/zsh`.请访问https://support.apple.com/kb/ht208050.%M%::%〜% n%#

但许多其他可执行文件仍然无法加载,因为DYLD尝试从磁盘加载iOS库:

xdyld_shared_region = private xdyld_shared_cache_dir = / usr / local / zhuowei dydd_root_path = / usr / local / zhuowei ./littlespawn / usr / local / zhuowei / windowserver_arm64ded:警告:无法加载插入的库' / usr / lib / pspawn_payload-stg2 .dylib'进入硬化过程,因为没有发现合适的图像。确实发现:/usr/lib/pspawn_payload-stg2.dylib:mach-o,但没有为portoon macos / susr/lib/pspawn_payload-stg2.dylib:mack-o构建,但不是用于平台macosdyld:library未加载库: /usr/lib/libpam.2.dylib来自:/system/library/frameworks/security.framework/versions/a/security原因:未找到合适的图像。确实发现:/usr/lib/libpam.2.dylib:mach-o,但没有为platform macos / susr/lib/libpam2.dylib:mach-o构建,但不是用于平台麦斯科斯/ usr / lib / libpam.2.dylib:mach-o,但不是用于平台麦克斯/ usr/lib/libpam2.dylib:mach-o,但不是为平台麦斯斯建造的

它结果将始终尝试原始的,未经配置的路径作为最后的手段。

要绕过这一点,我决定只是补丁Dydd的stat64方法,这样,如果路径没有以/ usr / local / zhuowei开始,则始终找不到返回文件。

我用麦斯科斯骨牌作为基础,并在一些在App Launch期间通常使用的CelutureWriter内容的额外代码添加了额外的代码。

由于无法在App Launch期间指定哪个Dyd使用,因此我启动应用程序暂停,然后使用VM_Remap运行一个工具来替换应用程序内存中的Dyd。

作为一个奖金,使用真正的麦克斯DYLD而不是iOS一个人让我们摆脱当前平面打破和MProtect解决方法。

手机:〜root#xdyld_shared_region = private xdyld_shared_cache_dir = / usr / local / local / local / local / loce / loce / geekbench / geekbench / geekbench \ 5.app/contents/resources/geekbench_aarch64 dyld:警告:无法加载插入的库&# 39; /usr/lib/pspawn_payload-stg2.dylib'进入硬化过程,因为没有发现合适的图像。发现:/usr/lib/pspawn_payload-stg2.dylib:stat()使用errno = 78geekbench 5.4.1试用:https://www.geekbench.com/geekbench 5在试用模式和自动时需要有效的互联网连接将基准测试结果上传到GeekBench浏览器。宝布从灵长类机Labs商店提供了一个GeekBench 5许可,以启用脱机使用和解锁其他功能:https://store.primatelabs.com/v5Enter使用以下命令行:/ usr您的GeekBench 5许可证/ local / zhuowei / geekbench / geekbench 5.app/contents/resources/geekbench_aarch64 - 单调<电子邮件> < key>运行收集系统信息系统信息操作系统MacOS 14.1(Build 18A8395)型号D53GAP模型ID D53GAP主板D53GAP

结果恰好是普通iPhone 12基准的30%,可能是iOS限制背景过程的结果。

命令行应用程序在iOS上运行Fine,因为命令行应用程序和内核之间的UNIX API接口为30岁,并且与MacOS和iOS不同。

不幸的是,这不适用于图形应用程序,因为iOS的图形堆栈和麦斯科斯群体的图形堆栈在十年上分开开发。

即使在宏之后采用了某些IOS的功能(例如IOMobileFrameBuffer)作为Apple硅转换的一部分,IOS的图形和输入驱动程序仍然存在不同的接口,并且无法与麦斯卡斯空间合作。

我尝试运行Windowserver,负责使用我的工具在麦斯卡斯播放Windows。它不起作用,并显示苹果仍然需要做多少融合工作来统一iOS和麦克斯。

首先,它出错的是因为IOHIDSystem,负责鼠标游标和键盘控制的司机在iOS上完全缺少。我用-virtualonly绕过了,但是..

iOSurface寻找iOSurfaceroot驱动程序而不是iOS的Iocoresurfaceroot。修补了......

金属寻找麦克斯的ioaccelerator而不是ios的iogpu。我试图强迫这个,它没有用。

在我设置假装有0个屏幕的断点后,跳过输入初始化,并跳过金属初始化,Windowserver决定放弃和赛格。 (设置内存调试标志表明它是一个使用欠缺错误,因为地址是所有0x55s。我想它不希望0屏幕?)

如果Apple曾经实现了反向催化剂,则可能在VM /经典环境中,而不是无缝:差异太大,需求不足以证明另一个多年统一项目

在WWDC之前,我应该停止在最后几个小时内完成研究,所以我有时间修改这篇文章,而不是上传我的第一次草案