一、先尝试将 App Store 下载的 app 直接装入其他未越狱手机
首先使用越狱手机上下载
腾讯视频
app,然后找到它的 APP 路径,将live4iphone.app
找出来。拷贝到 Mac 电脑上。Mac 电脑上创建一个
Payload
文件夹,将live4iphone.app
放进文件夹,然后进行 zip 压缩,压缩完毕后,重命名为Payload.ipa
,这样一个 iPhone 的安装包程序就搞好了。-
我们使用
iFunBox
程序将ipa
装到未越狱的手机,打开console.app
,获得如下错误:
从
console.app
,我们可以得知是签名不合法导致。我们猜测会不会是未脱壳的原因呢?接下来我们把live4iphone
脱壳,然后重复上面的步骤,获得的错误依然如上图所示。由此,我们可以得知,从 App Store 的应用是不能轻易安装到其他手机的,即使脱壳了也不行。
二、将 APP 进行重签名,安装到未越狱手机
我们先去开发者账号后台,配置一个通配符的
.mobileprovision
证书文件(需要将我们目标手机的 UDID 加入到证书的 devices 列表中),用于我们后面的重签名。从
embedded.mobileprovision
文件中提取出entitlements.plist
权限文件,指令如下(mac 自带指令):
carrot__lsp$ security cms -D -i embedded.mobileprovision > temp.plist
carrot__lsp$ /usr/libexec/PlistBuddy -x -c 'Print:Entitlements' temp.plist > entitlements.plist
- 使用
security find-identity -v -p codesigning
指令获得我们的可用开发者证书。
carrot__lsp$ security find-identity -v -p codesigning
1) 0D3C41A788FF61D05F6xxxxAD8AE2D7xxxx97084 "Apple Development: Su Mxx Yxxx (AGV6XXXXXV)"
- 使用我们的开发者证书给
live4iphone
签名,并且将embedded.mobileprovision
放入live4iphone.app
中
carrot__lsp$ codesign -fs 0D3C41A788FF61D05F6xxxxAD8AE2D7xxxx97084 live4iphone
live4iphone: replacing existing signature
- 使用
codesign
为整个live4iphone.app
签名
carrotdeMacBook-Pro:Payload carrot__lsp$ codesign -fs 0D3C41A788FF61D05F6xxxxAD8AE2D7xxxx97084 --entitlements entitlements.plist live4iphone.app
live4iphone.app: replacing existing signature
- 将
live4iphone.app
入上面所述方法打包成live4iphone.ipa
,使用iFunBox
安装到我们的未越狱手机中。~~安装成功,可以在其他手机打开我们安装的软件。
三、将 APP 进行hook,加入自己代码,安装到未越狱手机
步骤二所实现的只是将App Store 下载的 APP 通过我们的证书重新签名,并安装到其他手机,这似乎没有啥实际意义。接下来我们挑战更有意义的,将 APP 加入我们的代码,然后装到别人的手机上去。思路和步骤二几乎一致,下面仅仅介绍不同的地方。
编写 tweak 代码,hook 我们的目标 APP,并按照到越狱手机中。比如我这里是让
live4iphone
永远不展示启动广告,迅速进入 APP。找到我们编写的 tweak 代码, 在手机上生成的动态库。路径如下
/Library/MobileSubstrate/DynamicLibraries/
,找到qqvediotweak.dylib
文件,拿到 Mac 上。在手机的
/Library/Frameworks/CydiaSubstrate.framework/
目录下获取CydiaSubstrate
文件,拿到 Mac 上。我们把
CydiaSubstrate
、embedded.mobileprovision
、qqvediotweak.dylib
三个文件都放入live4iphone.app
中,还要确保live4iphone.app
已脱壳。接下来我们要思考如何让
live4iphone
加载我们的qqvediotweak.dylib
代码呢?可以使用insert_dylib
库将动态库注入到 Mach-O 文件中,下载地址 https://github.com/Tyilo/insert_dylib
用法如下:
// 将代码从 github 下载,用 xcode 编译生成 `insert_dylib` 可执行文件,放入 /usr/local/bin 目录下
carrot__lsp$ insert_dylib @executable_path/qqvediotweak.dylib live4iphone --weak -all-yes live4iphone
insert_dylib: invalid option -- a
Usage: insert_dylib dylib_path binary_path [new_binary_path]
Option flags: --inplace --weak --overwrite --strip-codesig --no-strip-codesig --all-yes
carrot__lsp$ insert_dylib @executable_path/qqvediotweak.dylib live4iphone --weak --all-yes live4iphone
live4iphone already exists. Overwrite it? [y/n] y
Binary is a fat binary with 2 archs.
LC_CODE_SIGNATURE load command found. Remove it? [y/n] y
LC_CODE_SIGNATURE load command found. Remove it? [y/n] y
Added LC_LOAD_WEAK_DYLIB to all archs in live4iphone
carrot__lsp$ otool -L live4iphone | grep qqvedio
@executable_path/qqvediotweak.dylib (compatibility version 0.0.0, current version 0.0.0, weak)
@executable_path/qqvediotweak.dylib (compatibility version 0.0.0, current version 0.0.0, weak)
- 我们通过
otool
可以查看动态库中加载其他动态库的情况,我发现qqvediotweak.dylib
依赖了CydiaSubstrate
动态库,但是路径不对,如何修改路径呢?
carrot__lsp$ otool -L qqvediotweak.dylib | grep Cydia
/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate (compatibility version 0.0.0, current version 0.0.0)
carrot__lsp$ install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @loader_path/CydiaSubstrate qqvediotweak.dylib
- 分别对
CydiaSubstrate
、live4iphone
、qqvediotweak.dylib
进行动态库签名
carrot__lsp$ codesign -fs 0D3C41A788FF61D05F6xxxxAD8AE2D7xxxx97084 live4iphone
carrot__lsp$ codesign -fs 0D3C41A788FF61D05F6xxxxAD8AE2D7xxxx97084 qqvediotweak.dylib
qqvediotweak.dylib: replacing existing signature
carrot__lsp$ codesign -fs 0D3C41A788FF61D05F6xxxxAD8AE2D7xxxx97084 CydiaSubstrate
CydiaSubstrate: replacing existing signature
- 对
live4iphone.app
重签名
carrot__lsp$ codesign -fs 0D3C41A788FF61D05F6xxxxAD8AE2D7xxxx97084 --entitlements entitlements.plist live4iphone.app
live4iphone.app: replacing existing signature
- 打包成
ipa
,安装到新的手机上,一切顺利,开屏广告不见了,APP 正常运行。
四、iOS 重签名知识点补充
- 重签名 GUI 工具 -
iOS App Signer
可以快速对 .app 重签名打包成 ipa
需要提在 .app 包中提供对应的 embedded.mobileprovision 文件
动态库还是需要自己手动重新签名
- 指令
otool -L xxx动态库
- 该指令可以查看动态库依赖其他动态库的情况
- 使用
MachOView
中的LoadCommond
字段也可以查看动态库依赖情况
- 动态库注入
- 可以使用 insert_dylib 库将动态库注入到 Mach-O 文件中
- 下载地址 https://github.com/Tyilo/insert_dylib
- 用法:
insert_dylib 动态库加载路径 Mach-O文件
-
--weak
,即使动态库找不到也不会报错 -
--all-yes
,后面所有的选择都为 yes - insert_dylib 的本质是往 Mach-O 文件的 Load Commands 中添加一个 LC_LOAD_DYLIB 或者 LC_LOAD_WEAK_DYLIB
- 更改动态库加载地址
- 可以使用 install_name_tool 修改 Mach-O 文件中动态库的加载地址
- 用法:
install_name_tool -change 旧地址 新地址 Mach-O文件
- @executable_path 代表可执行文件所在的目录
- @loader_path 代表动态库所在的目录
- 一些注意的点
- 安装包中的可执行文件必须是经过脱壳的,重签名才会有效
- .app包内部所有动态库(.framework、.dylib)、AppExtension(PlugIns 文件夹,拓展名是 appex)、WatchApp(Watch文件夹)都需要重新签名
- 重新签名打包后,安装到设备过程中,可能需要经常查看设备的日志信息
- 程序运行过程中:Window → Devices and Simulators → View Device Logs
- 程序安装过程中:Window → Devices and Simulators → Open Console
五、暂时无法解答的问题
为什么 pp 助手 爱思助手,可以在未越狱的用户手机上安装 App Store 呢?而且没有企业证书的信任提示。
- 这种安装的 APP 有个两个特点:①是无法更新,②在你进行换手机备份软件时,会要求你输入一个你不认识的 APPID 来获得 APP 的继续使用权。
- 基于上面的特点,我猜测很可能是是一种共享 APPID 的技术,并且他们模拟了一个 iTunes 来给我们的手机安装 APP。更多的细节就不得而知了。