导语
本文主要描述了在包含多 target 与 注入 dylib 的场景下该如何进行重签名的操作。
环境 & 工具
macOS Sierra 10.12.4
Xcode 8.3.1
Jailbreak iPad 8.4
No Jailbreak iPhone 10.1.1
yololib
theos
mobiledevice
Wechat 6.5.7
多 target
在 Apple 官方的Code Signing Guide 中提到参与签名的有二进制文件,库文件,资源文件。微信的 .ipa 包中包含了 PlugIns 目录,里面包含了插件的二进制文件,Watch 目录,其中包含了应用在 Watch OS 平台下的二进制文件。
该如何签名呢? 创建一个工程,添加了 ShareExtension + Watch OS 的 target*,然后 *Archive 看看 Xcode 是如何执行签名流程的。
从上面的截图可知 Xcode
签名的所需要的内容,还是和上篇中说的一致,但是多 target
环境下需要对二进制由内到外进行签名操作,同时每个 target
都需要有各自的描述文件。
用 otool -l path/to/unix_exec_file | grep -B 2 crypt
来确定是否被加壳了。经过测试发现 Plugins 目录下的二进制是加密的,而 Watch 目录下的二进制并没有被加密
因为加壳的代码要脱壳才能进行重签名,一般会用类似 dumpdecrypted 的工具在运行时通过 dump 的方式来获得脱壳后的文件,因此在这里可以将 Plugins 和 Watch 目录删除,这样处理后,应用就从多 target 就转换为单 target 了。
以微信 6.5.7 版本为例,准备好 AdHoc 类型的描述文件之后,进行如下操作:
- 删除应用中的 _CodeSignature 目录
- 用脱壳后的二进制文件替换掉原应用的二进制文件
- copy 描述文件到应用目录中
- 修改 info.plist 中的包名替换为重签名的描述文件对应的包名
- 对整个应用的二进制进行签名(
codesign ...
) - 拖拽到 iTunes 生成 .ipa 文件
安装 .ipa 结果成功。
注入 dylib
用 Xcode 中的 OpenDev 模板(需要单独下载),生成要注入到微信中的 dylib,在生成的工程中添加类似下面的方法。
1 |
|
⌘ B 编译生成动态库,用 yololib 将动态库注入到微信的二进制。同时将该动态库拷贝到微信应用的目录中
1 | ./yololib 目标可执行文件 需注入的dylib |
同样进行重签名操作,拖到 iTunes
中生成 .ipa
文件。用 mobiledevice
工具进行安装操作。
1 | $ mobiledevice install_app /path/to/.ipa |
❎ 安装失败
错误一: dylib
未重签名
查看设备日志,发现如下输出,可以看出是动态库没有进行签名操作
1 | <Notice>: SystemUI unknown identifier: 'com.coder.demo' |
解决方法
1 | # codesign --force --sign xxxxxx -a arm64 Dylib.dylib |
因为我脱壳的是 arm64 的二进制,所以可以通过 -a 指定对动态库的具体架构进行签名操作。
错误二: dylib
路径错误
因为 yololib 注入后动态库的执行路径由 @executable_path 指明,所以要确认在执行时能找到对应的动态库二进制。下面就是一个错误的路径
如果动态库执行路径错误时,可以安装,但是运行就会闪退
解决方法
cd 到 WeChat.app 目录下,确保 yololib 注入后,动态库的执行路径为 @executable_path /Dylib.dylib
结果
查看设备日志,可以看到动态库已成功注入
总结
要注意的是,由于中国的开发者利用免费的证书大量对应用进行重签名,所以目前苹果加上了许多限制,免费开发者的provisioning证书有效时间从之前的30天改为7天,过期后需要重新签名。另外就是一个星期内最多只能申请到10个证书。
本文通过 Xcode 的一次多 target 的工程签名流程入手,了解多 target 的签名顺序。因为重签名需要进行脱壳的操作,因此对多 target 的应用,在不影响的情况下,可删除其他 target 文件,将其转换为单 target*。注入的 *dylib 需要独立签名,同时使用 yololib 时需要注意执行路径的问题。
最后把整体流程再整理下:
- 删除应用中的 _CodeSignature 目录
- 用脱壳后的二进制文件替换掉原应用的二进制文件
- copy 描述文件到应用目录中
- 修改 info.plist 中的包名替换为重签名的描述文件对应的包名
- 使用 Xcode 的 OpenDev 模板生成 dylib 文件
- 对动态库进行签名
- 使用 yololib 将动态库注入到二进制文件中
- 对整个应用的二进制进行签名(
codesign ...
) - 拖拽到 iTunes 生成 .ipa 文件
- 使用 mobiledevice 安装 ipa 文件