一、先嘗試將 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。更多的細節就不得而知了。