iOS 安全攻防 -- 动态库注入
虽然咱不是去破解别人的包,但是咱得了解破解手段为 IPA 包的安全做防护,咱就讲不一堆理论啥的,想看的自己百度去,不多说废话,继续上干货。
在上篇 iOS 安全攻防 -- 越狱与砸壳 操作后我们获取到 IPA 包,这边就开始对 IPA 包做个动态库注入的操作。具体步骤如下:
- 解压 IPA 包
- 动态库注入
- IPA 重签名
- 制作 IPA
解压 IPA 包
这个简单,直接上终端操作一下,比手动去整快一些(手动的话需要将 xxx.ipa,文件后缀改为 xxx.zip 然后右键解压,只想说繁琐),终端执行:
$ cd xxx
$ unzip -oqq xxx.ipa
搞定,拿到解压后的 Payload 文件。
动态库注入
这边简单说一下,动态库注入可以借助 yololib,也可以借助 optool,将对应的执行文件下载后,放置于/usr/local/bin
目录下。
PS: 使用 yololib
注入动态库后在64位的系统上运行会直接闪退(亲测的结果,具体为啥闪退咱就不懂了,反正它就是闪退了,无限闪退、没拿到崩溃日志具体是啥原因 emmm...),不建议使用,所以咱们这边就使用 optool
。
使用提前准备好的动态库(比如随便创建个动态库,动态库内实现个 +(void)load 函数,在 load 函数内实现个延迟弹窗)。
使用终端注入动态库:
$ optool install -c <command> -p <payload> -t <target> [-o=<output>] [-b] [--resign]
# 例如 optool install -c weak -p "@executable_path/Frameworks/xx.framework/xxx" -t Payload/xxx.app/xxx
执行后提示
Found thin header...
Inserting a LC_LOAD_WEAK_DYLIB command for architecture: arm64
Successfully inserted a LC_LOAD_WEAK_DYLIB command for arm64
Writing executable to Payload/xxx.app/xxx...
则表示注入成功,再将 Framewrok,放置于 Payload/xxx.app/Framewroks
文件夹内就行,这步千万别遗漏,漏了直接闪退给你看。
PS:
- 如果
Payload/xxx.app/
内没有Framewroks
文件夹,则自己手动创建一个再将动态库放置进去即可。 - 如果
Payload/xxx.app/Framewroks
内有其它动态库,需要先将Framewroks
内的其它动态库先进行签名。
对 Framework 重签名:
# 查看本地的证书
$ security find-identity -v -p codesigning
$ cd Payload/xxx.app/Frameworks
# 重新签名
$ codesign -fs "Apple Development: xxx (CertID)" Frameworks/~.framework
动态库注入成功后,通过 MachOView 这款 Mac 软件来校验一下是否有注入成功。
启动MachOView
, 快捷键 cmd + o
打开文件夹,选中 Payload/xxx.app
内的可执行文件,例如作者注入的LibHook.framework
动态库:

验证完成,动态库注入成功,后续就是重签名安装包校验一下是否生效了。
IPA重签名
签名这种小事简单,三下五除二的就搞定了。
1. embedded.mobileprovision
文件:
新建个工程bundle id
你随意,工程代码随意,直接打包出 IPA,解压 IPA 拿到 Payload/xxx.ipa/
文件夹内的embedded.mobileprovision
文件。
将embedded.mobileprovision
文件拷贝放进需要重签名的Payload/xxx.ipa/
里面。
PS:
- a.
embedded.mobileprovision
文件内包含调试设备的 UUID 等信息 - b. 记得将要重签名的
Payload/xxx.ipa/info.plist
内的bundle id 修改成上面新建工程的bundle id,不然可能会导致重签名后的包无法正常安装。(注意 bundle id 与需要调试的设备 UUID 关联)
2. 生成 entitlements.plist
文件
先读取embedded.mobileprovision
:
$ security cms -D -i embedded.mobileprovision
找到类型下方的内容:
<key>Entitlements</key>
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.networking.vpn.api</key>
<array>
<string>allow-vpn</string>
</array>
<key>application-identifier</key>
<string>9GT7E28KP9.com.feiyu.ismyturn</string>
<key>keychain-access-groups</key>
<array>
<string>9GT7E28KP9.*</string>
<string>com.apple.token</string>
</array>
<key>get-task-allow</key>
<true/>
<key>com.apple.developer.team-identifier</key>
<string>9GT7E28KP9</string>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
</dict>
新建 plist 文本,文本名为entitlements.plist
,将上面的内容拷贝出来,放进新建的 文本内。完整的entitlements.plist
文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>9GT7E28KP9.com.feiyu.eatfatty</string>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>9GT7E28KP9</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>9GT7E28KP9.*</string>
<string>com.apple.token</string>
</array>
</dict>
</plist>
将 entitlements.plist
放置于 Payload/
文件夹内,也就是与xxx.app
同级下。
3. App 重签名
执行重新签名命令:
$ cd Payload
$ codesign -fs "Apple Development: xxx (CertID)" --no-strict --entitlements=entitlements.plist xxx.app
签名成功后,将entitlements.plist
文件删除,最后将 Payload 重新制作成 ipa 就行了。
4. 制作 IPA
继续上终端命令(当然,如果喜欢手动的也行,我不会告诉你直接将 Payload 压缩一下改一下文件名,改一下后缀为 .ipa 就行了):
$ zip -ry xxx.ipa Payload
搞定,直接用 xcode 安装一下看看,运行成功并且启动后延迟弹窗,动态库注入 over。