ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Madeira Wine分支的三栈跨异常分派:ARM64EC异常处理架构详解

Madeira Wine分支的三栈跨异常分派:ARM64EC异常处理架构详解 Madeira Wine分支的三栈跨异常分派ARM64EC异常处理架构详解【免费下载链接】MadeiraRun x86-64 Windows PC games on jailed iOS via FEX-Emu Wine DXMT项目地址: https://gitcode.com/GitHub_Trending/mad/MadeiraMadeira 是一个在越狱jailediOS 设备上运行 x86-64 Windows PC 游戏的项目通过FEX-Emu Wine DXMT三层技术栈实现。它最精巧的模块就是 Wine 分支中的ARM64EC 异常处理架构——当客端Guest游戏代码访问了非法内存时整个系统要在「iOS 原生异常」与「Windows 结构化异常SEH」之间做跨栈分派而不是简单崩溃。本文带你完整看懂这套机制。 一、为什么在 iPhone 上跑 Windows 游戏需要「异常处理」先理解三层模拟的关系层级组件职责指令翻译FEX-Emu将 x86-64 指令翻译为 ARM64 执行API 兼容Wine提供 Windows 系统调用与 SEH 异常语义图形桥接DXMT将 DirectX 12 命令转换为 Metal在 Windows 上程序访问非法地址会触发硬件异常然后由 ntdll 的KiUserExceptionDispatcher进入 SEH结构化异常处理流程——很多游戏依赖try/catch这类机制做边界检查。但在 Madeira 上异常链被拉长成了一条跨三栈的分派链故障首先发生在 iOS 内核层MachEXC_BAD_ACCESS或 POSIXSIGSEGV而最终要送达的是运行在 ARM64EC 客端语义下的 Windows SEH 处理器。中间差着的就是 Madeira 自己写的异常分派器。⚡ 二、三「栈」分别指什么这里的「三栈」不是三根调用栈而是异常在分派时要跨越的三个代码世界第 1 栈PE 客端栈Guest PE VA 空间游戏 DLL 在 Wine 中拥有标准的 PE 虚拟地址例如0x7FFE0000的KUSER_SHARED_DATA。这些地址在 iOS 上并不真实存在必须被重定向到真实映射。第 2 栈FEX JIT 翻译池栈JIT PoolFEX-Emu 把 x86-64 代码翻译成 ARM64 指令放入 JIT 池。部分模块副本、惰性写入的函数指针可能残留着 PE 地址直接执行会再次触发故障——这就是「PE→JIT 池执行重定向」要解决的问题。第 3 栈iOS 宿主异常栈Mach/POSIX越狱 iOS 的 mach 层通过每线程异常端口把EXC_BAD_ACCESS送进 Madeira 的 Mach 异常处理线程无法恢复的异常则落到 POSIXSIGSEGV兜底。核心源码全部集中在 ntdll 的 iOS 移植层信号与 Mach 异常处理signal_arm64_ios.c虚拟内存与 W^X 管理virtual_ios.cWOW64 兼容约定ios_wow.hARM64EC 混合模式 ntdll 入口点约定ios_mixed.h 三、分派流程一次故障的完整旅程故障捕获客端代码执行了非法访存iOS 内核通过 Mach 异常端口通知 Madeira 的单一异常处理线程一个线程服务所有 Wine「进程」线程靠注册表查找故障线程对应的 TEB 与跳板。三重自愈修复分派器先判断故障是否「可自愈」处理三类典型场景x18寄存器丢失TEB 损坏——ARM64EC 约定 x18 必须指向 TEBKUSER_SHARED_DATA0x7FFE0000等规范地址的读取重定向PE→JIT 池的执行重定向——把跳到 PE 地址的指令修正为跳到 JIT 池副本。构造 Windows 异常上下文若不可自愈分派器在exc_stack_layoutCONTEXT CONTEXT_EX EXCEPTION_RECORD布局严格对齐 Windows 规范见 signal_arm64_ios.c上搭建异常帧。调用 KiUserExceptionDispatcher客端 SEH 展开器接管游戏自己的try/catch得以正常工作——这是「跨异常分派」的终点。兜底未处理的异常落回 POSIXSIGSEGV处理器生成可读的崩溃报告。 一个有趣的工程细节Mach 往返开销被实测标注在代码注释中约 33 微秒所以分派器内置了「风暴闸门」storm gate——同一个故障循环每秒可能触发 3 万次闸门按 20 次全量、之后抽样打印的策略避免日志爆炸。 四、两个进阶机制W^X 降级实验默认关闭当同一页反复触发写故障时可临时把页从 RX 降级为 RW 提高性能出现执行故障时再同步恢复。该机制已知存在陈旧翻译风险因此被设计为显式开启写入Documents/madeira-wx.txt安全默认值优先——这一点在 virtual_ios.c 中有详细记录。自愈式陈旧指针修补器JIT 池中的模块副本里可能残留指向 PE 地址的函数指针例如惰性初始化的 IAT 槽位每次调用都会故障一次。Mach 处理器把所有故障过的 PE 地址入队一个低优先级扫描线程随后把模块池里所有匹配槽位改写为池内地址——每个陈旧指针只故障一次之后永不再犯。 五、如何快速定位相关代码你想看什么去哪里Mach 异常处理器入口signal_arm64_ios.c异常帧布局exc_stack_layoutsignal_arm64_ios.cARM64EC 混合模式 ntdllios_mixed.hARM64EC 与 SEH 的提交溯源wine-lgpl-provenance.mdWOW6432 位兼容架构WOW64.md构建与部署流程BUILDING.md✅ 六、总结Madeira 的 Wine 分支用单一 Mach 异常线程 三类自愈重定向 严格对齐 Windows 规范的异常帧在越狱 iOS 上重建了 Windows SEH 语义。三栈之间的每一次跨异常分派都意味着一次「内核故障 → Windows 异常」的语义翻译——这正是 x86-64 游戏能跑在 iPhone 上却不轻易崩溃的关键。想要亲手研究完整实现可以获取仓库源码git clone https://gitcode.com/GitHub_Trending/mad/Madeira【免费下载链接】MadeiraRun x86-64 Windows PC games on jailed iOS via FEX-Emu Wine DXMT项目地址: https://gitcode.com/GitHub_Trending/mad/Madeira创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进