IPA-Patch/Kanade

GitHub: IPA-Patch/Kanade

Kanade 是一个与内核无关的原生 ARM64 dylib 嵌入工具,通过静态修补 Mach-O 二进制文件绕过 iOS 18+ 的 CSM 限制,实现非越狱环境下的 runtime hook。

Stars: 0 | Forks: 0

# Kanade — 与内核无关的原生 ARM64 Dylib 嵌入器

license platform arch org

Kanade 是 [IPA-Patch](https://github.com/IPA-Patch) 插件的宿主机端 Python 工具——它会在**签名前重写磁盘上的**目标 Mach-O 二进制文件,嵌入 code cave 和 dylib 加载命令,从而确保 runtime hook 的分发完全不触碰 `__TEXT`。这是 iOS 18–26 侧载目标上唯一可行的方案,因为内核的 Code Signing Monitor 会杀掉任何在 runtime 向自身 `__TEXT` 段写入数据的进程。 **runtime 的 C/ObjC 端**(slot 解析、image 查找、原始 trampoline 恢复)位于 [IPA-Patch/Chinlan](https://github.com/IPA-Patch/Chinlan) 中。Kanade 和 Chinlan 设计为配合使用。 ## 为什么需要静态 patch 在 iOS 18–26 上,非越狱目标的 runtime 内联重写 hook(MSHookFunction、Dobby、Frida)会被 CSM 杀掉。IPA-Patch 的方案如下: 1. 将每个 hook 点的第一条指令覆写为 `B `。 2. 在二进制文件的 `__TEXT` 零填充尾部追加一个小型的 trampoline cave。 3. 该 cave 在 runtime 从 `__DATA,__bss` slot 读取函数指针,并通过它调用 tweak dylib。 4. tweak dylib 在加载时,会将其 hook 地址写入该 slot——这是一个对 `__DATA` 的写入操作,CSM 允许此行为。 步骤 1–3 在宿主机的构建阶段完成。本仓库提供了执行这些操作的 Python 工具。 ## 本仓库包含什么 - `encode.py` — 纯 Python 的 ARM64 指令编码器(4 字节小端序输出,构建时无需外部汇编器)。 - `machoops.py` — 通用的 Mach-O 操作:`add_lc_load_dylib`、`reserve_hook_slot`、`assert_slot_in_bss`、`iter_thin_binaries`。由 `lief` 提供底层支持。 - `caves.py` — 幂等 patch 引擎:`apply_patches(target, patches, cave_patches, cave_region)`。应用内联字节 patch,并将单指令站点路由至 code cave payload。 - `patch_macho.py` — CLI 驱动程序:`python3 -m tools.patch_macho --recipe NAME TARGET`。recipe 模块管理着所有特定于目标的常量。 - `patch_plist.py` — CLI:`python3 -m tools.patch_plist --recipe NAME PLIST`(或使用 `--set KEY=VALUE` 进行一次性覆写)。 - `verify_lc_load.py` — patch 后的冒烟测试,确认修补后的二进制文件中存在预期的 `LC_LOAD_DYLIB`。 - `verify_sites.py` — 将 hook 点的 RVA 与 `dump.cs` 索引进行交叉比对,以捕捉目标 App 更新后出现的 RVA 偏移。 - `build_patched_ipa.sh` — 端到端的 IPA 流水线:解密 → patch Mach-O → patch plist → 注入 dylib → 重新打包 → 签名。由 `--recipe / --framework / --dylib / --input` 驱动。 - `scaffold_recipe.py` — 为新的特定目标 recipe 模块生成脚手架。 `tools` 是一个 [PEP 420](https://peps.python.org/pep-0420/) 命名空间包。使用方项目可以将 `tools/recipes/.py` 放置在 `shared/` 旁边,并通过同一个 `tools.*` 命名空间导入所有内容。 ## 用法 将两个 submodule 添加到你的使用方项目中: ``` git submodule add https://github.com/IPA-Patch/KANADE.git shared git submodule add https://github.com/IPA-Patch/Chinlan.git Sources/Chinlan ``` 通过 `PYTHONPATH` 接入 Python 工具: ``` PYTHONPATH=shared:. python3 -m tools.patch_macho --recipe recipes.yourtweak TARGET PYTHONPATH=shared:. python3 -m tools.verify_sites \ --recipe recipes.yourtweak \ --index assets/dump.cs.index.json \ --ipa assets/YourApp.ipa ``` 或者通过 `pyproject.toml`: ``` [tool.pytest.ini_options] pythonpath = ["shared", "."] ``` 将你的 recipe 写在 `tools/recipes/yourtweak.py`。它会作为 `tools.recipes.yourtweak` 被导入——命名空间包会自动合并 `shared/tools/` 和 `./tools/`: ``` from tools.encode import b_imm # from shared/tools from tools.recipes.yourtweak import PATCHES # from ./tools/recipes/ ``` 存放在 recipe 中特定于目标的常量包括:cave 地址、site RVA、预期的 prologue 字节、dylib 名称、`LC_LOAD_DYLIB` 路径、plist 键。 有关 runtime 的布线配置(slot 表、`publish_*()` 辅助函数、引导构造函数),请参阅 [Chinlan README](https://github.com/IPA-Patch/Chinlan)。 ## 检查目标更新后的 RVA 偏移 当目标 App 更新时,其 RVA 会发生变化。在进行 patch 之前,请针对新构建的版本运行 `verify_sites`: ``` PYTHONPATH=shared:. python3 -m tools.verify_sites \ --recipe recipes.yourtweak \ --index assets/dump.cs.index.json \ --ipa assets/YourApp-new.ipa ``` 任何不匹配之处都会连同预期与实际发现的 prologue 字节一起报告。请更新 `ChinlanSites.h` 和 recipe 中的 RVA 使其匹配,然后重新验证。 ## 开发 ``` make test # pytest make lint # ruff check make format # ruff format ``` 编码器的黄金值是使用 [theos](https://github.com/theos/theos) 的 linux iphone 工具链中附带的 LLVM 汇编器生成的。要重新生成其中一个值: ``` $THEOS/toolchain/linux/iphone/bin/llvm-mc \ -triple=arm64-apple-ios -show-encoding <<< 'stp x29, x30, [sp, #-0x90]!' ``` 更新 `tests/test_encode.py` 中对应的 `bytes.fromhex(...)` 字面量。 ## 许可证 MIT — 详见 [LICENSE](LICENSE)。
标签:逆向工具