PlayDay-iOS/LegacyWiFiFix
GitHub: PlayDay-iOS/LegacyWiFiFix
通过 Hook 修复 iOS 在 WPA2/WPA3 过渡模式下的 AKM 选择错误,使设备能正常关联 PSK 网络。
Stars: 3 | Forks: 0
# Legacy WiFi Fix
修复 iOS 3.x-12.x 上的 RSN IE AKM 选择错误,使过渡模式的
WPA2/WPA3 网络(AP 同时广播 PSK 和 SAE)能够与支持的安全关联密钥模式(AKM)关联
(例如 WPA2-PSK)。
## 错误说明
以 WPA2/WPA3 过渡模式运行的现代路由器会在同一个 RSN 信息元素中同时广播 PSK(AKM 2)
和 SAE(AKM 8)。在 AKM 选择器(例如 `_performAssociation`)中,iOS 会遍历
`IE_KEY_RSN_AUTHSELS` 来跟踪“最佳”AKM。当当前最佳或新候选值超出表驱动范围时,
比较会回退到原始值,因此后续未知的 AKM(SAE = 8)会覆盖先前的已知值(PSK = 2)。
随后对选定 AKM 的切换会命中 `default:` 并返回错误 `-0xF3C`。结果:即使 WPA2-PSK 可用,
整个网络也会被拒绝。
可接受的 AKM 范围取决于 iOS 版本。下表来自对 `_performAssociation` 中 switch 语句的
Ghidra 反编译结果,源自原生 `wifid` / `WiFiManager`:
| iOS | Switch cases present | Max AKM |
|-------------|----------------------|---------|
| 3.x - 5.x | 1, 2 | 2 |
| 6.x - 7.x | 1, 2, 3, 4 | 4 |
| 8.x - 12.x | 1, 2, 3, 4, 5, 6 | 6 |
已直接在 3.1.3、4.2.1、4.3.5、5.1.1、6.1.6、7.1.2、
8.4.1、9.3.6、10.3.3、10.3.4、11.4.1 和 12.5.8 二进制文件中验证 —— 从 iOS 3 到 iOS 12
的每个主要版本至少有一个采样点。运行时从 `kCFCoreFoundationVersionNumber` 中选择
`MAX_KNOWN_AKM`:>= iOS 8.0 为 6,>= iOS 6.0 为 4,否则为 2。
iOS 12.5.x 在 `_performAssociation` 的主 RSN 循环中新增了显式的 `(akm - 1) < 6` 保护,
但同级函数(12.5.8 wifid 中的 `FUN_100170a60`)仍使用未保护模式并通过自身的 1..6 切换
拒绝。因此该调整在 iOS 12 上仍然需要。
## 修复方案
Hook `parseRSN_IE`,并在下游代码读取 `IE_KEY_RSN_AUTHSELS` 之前,
删除其中超出 `1..MAX_KNOWN_AKM` 的 AKM。`MAX_KNOWN_AKM` 在加载时从
`kCFCoreFoundationVersionNumber` 选择(iOS <= 5 为 `2`,iOS 6 - 7 为 `4`,iOS >= 8 为 `6`)。
## 构建
该项目使用 [Theos](https://theos.dev) 并在容器中构建,因此无需本地 iOS 工具链。
### Docker
```
# 一键构建
docker compose up --build
# 或手动
docker build -t wififix-build -f Containerfile .
docker run --rm -v "$PWD:/build:Z" wififix-build
```
### Podman
```
# 一键构建
podman-compose up --build
# 或手动
podman build -t wififix-build -f Containerfile .
podman run --rm -v "$PWD:/build:Z" wififix-build
```
生成的 `.deb` 包会写入 `packages/`。
### 本地构建
安装 [Theos](https://theos.dev)(包含工具链和 SDK):
```
bash -c "$(curl -fsSL https://raw.githubusercontent.com/theos/theos/master/bin/install-theos)"
```
安装 iPhoneOS 12.4 SDK(项目所需):
```
$THEOS/bin/install-sdk iPhoneOS12.4
```
然后构建:
```
make package FINALPACKAGE=1
```
## 安装
将 `.deb` 复制到设备并安装:
```
scp packages/*.deb root@:/tmp/
ssh root@ 'dpkg -i /tmp/dev.playday3008.legacywififix_*.deb'
```
安装后的脚本会自动重启 `wifid`,因此 Substrate 会注入新进程 ——
无需执行 `ldrestart` 或重启设备。
## 测试
一个主机端测试框架会对从 IPSW 提取的真实 `wifid` /
`WiFiManager.bundle` 二进制文件运行查找器,针对每个采样的
iOS 版本和每种支持的架构(armv6、armv7、arm64)进行测试。
它针对存根 Mach-O 头构建 `test_finder.c` 三次,然后对每个固件调用构建结果,
并检查解析器地址是否与预期虚拟地址匹配。
将 `FIXTURES_DIR` 指向已提取的 IPSW 根目录并运行:
```
FIXTURES_DIR=/path/to/ipsws test/run_tests.sh
```
缺失的固件会被报告为 `SKIP`,因此可以使用部分集合运行测试套件。
`test/run_tests.sh` 中的预期地址来自 Ghidra 对原生二进制的反编译,
必须与真实地址完全匹配。
## 工作原理
该调整会注入到 `wifid` 和 `WiFiManager.bundle` ——
whichever image hosts the RSN IE parser on the running iOS version ——
并在运行时动态定位解析器:
1. 解析 Mach-O 头以查找 `__cstring` 和 `__cfstring` 段
2. 定位 CFString 常量 `IE_KEY_RSN_VERSION` 和
`IE_KEY_RSN_AUTHSELS`
3. 解码 ARM 指令序列以查找引用这些常量的代码 ——
`ldr`-literal + `add pc`(ARM 模式 armv6 和 iOS 4.x 上的 Thumb-16,
及其各自的编码)、`movw`/`movt` + `add pc`(Thumb-2),以及
`adrp`/`add`(或链接器优化的 `adr`)在 AArch64 上
4. 使用邻近性启发式算法区分解析器与其他引用相同字符串的函数
挂钩后,会从解析的 RSN IE 中剥离超出每个版本 `MAX_KNOWN_AKM` 的 AKM 套件,
仅保留当前 iOS 实际处理的 AKM。
标签:AKM选择, CFCoreFoundationVersionNumber, Ghidra, iOS 12.x, iOS 3.x, iOS兼容性, iOS安全, iOS越狱, PSK, RSN IE, SAE, table-driven AKM, tweak, wifid, WiFiManager, WiFi修复, WPA2, WPA3, 云资产清单, 安全补丁, 客户端加密, 漏洞修复, 目录枚举, 移动安全, 网络关联, 网络安全培训, 请求拦截, 过渡模式, 逆向工程