原理
雖然這裡並不深入講解,但是最基本的原理我們還是要理解的,因為後面所做的工作,都是基於這個原理來進行開發的。越獄機器之所以能使用 tweak,主要是因為在越獄的時候,手機裡就安裝了 mobilesubstrate 這個庫,這個庫的作用就是能在程序運行的時候動態加載我們自己寫的 dylib 動態運行庫。
而由於非越獄手機系統裡面是沒有這個庫的,所以我們需要直接將這個庫打包進 ipa 當中,使用它的 API 實現注入。
獲取砸殼版本的微信 ipa因為在 AppStore 上面下載得到的應用都是經過加密的,可以執行文件上已經被加過一層殼,所以我們需要先拿到砸過殼版本的微信應用。
有兩種方法:
直接在 PP 助手下載
使用 Clutch 對越獄手機上應用進行砸殼
第一種方法沒什麼好說的,這裡主要講講第二種方法。
首先,將 Cluth 倉庫 clone 到本地:
$ git clone https://github.com/KJCracks/Clutch
$ cd Clutch
接著,使用 Xcode 進行構建,得到可執行文件:
$ xcodebuild -project Clutch.xcodeproj -configuration Release ARCHS="armv7 armv7s arm64" build
生成出來的可執行文件就在 Clutch 目錄下,將其拷貝到手機上:
scp Clutch/clutch root@<your.device.ip>:/usr/bin/
之後,就可以使用這個工具來進行砸殼了。
先 ssh 到越獄手機上,然後列出當前安裝的應用:
$ ssh root@<your.device.ip>
$ clutch -i
# Installed apps:
# 1: WeChat <com.tencent.xin>
# 2: DingTalk <com.laiwang.DingTalk>
# 3: 喜馬拉雅FM(聽書社區)電臺有聲小說相聲英語 <com.gemd.iting>
可以得到 clutch 把相應的包名也顯示出來了,這時我們就可以進行砸殼了:
$ clutch -d com.tencent.xin
# com.tencent.xin contains watchOS 2 compatible application. It's not possible to dump watchOS 2 apps with Clutch 2.0.4 at this moment.
# Zipping WeChat.app
# Swapping architectures..
# ASLR slide: 0xb3000
# ...
# writing new checksum
# DONE: /private/var/mobile/Documents/Dumped/com.tencent.xin-iOS7.0-(Clutch-2.0.4).ipa
# Finished dumping com.tencent.xin in 76.9 seconds
可以看到,clutch 將砸過後的 ipa 文件放到了 /private/var/mobile/Documents/Dumped/ 目錄下。
我們將它改成一個比較簡單的名字,然後拷回電腦上:
$ mv /private/var/mobile/Documents/Dumped/com.tencent.xin-iOS7.0-\(Clutch-2.0.4\).ipa /private/var/mobile/Documents/Dumped/wechat.ipa
$ scp root@<your.device.ip>:/private/var/mobile/Documents/Dumped/wechat.ipa ~/Desktop
這裡,我把它拷到了電腦桌面上。之後就可以進行下一步操作了。
準備 dylib 動態連結庫這步就很簡單了,直接到我的 WeChatRedEnvelop 147 上把源碼 clone 下來,然後執行 make 命令,就能拿到 dylib 文件了。
$ git clone https://github.com/buginux/WeChatRedEnvelop.git
$ cd WeChatRedEnvelop
$ make
# > Making all for tweak WeChatRedEnvelop…
# ==> Preprocessing Tweak.xm…
# ==> Compiling Tweak.xm (armv7)…
# ==> Compiling XGPayingViewController.m (armv7)…
# ...
# ==> Signing WeChatRedEnvelop…
$ cp .theos/obj/debug/WeChatRedEnvelop.dylib ~/Desktop # 注意是 .theos 目錄,這是個隱藏目錄
將生成的 dylib 文件拷貝到桌面,跟剛剛砸過殼的微信應用放到一個目錄層級。
檢查依賴項因為這個代碼是我自己寫的,所以我知道這個 dylib 除了 mobilesustrate 外沒有依賴其它的庫。但是如果我們拿到的是別人的 dylib,就需要先進行一下依賴項檢查,以確保之後我們將所有的依賴庫都打包進 ipa 當中。
使用 macOS 自帶的 otool 工具就可以進行依賴項檢查:
$ otool -L WeChatRedEnvelop.dylib
WeChatRedEnvelop.dylib (architecture armv7):
/Library/MobileSubstrate/DynamicLibraries/WeChatRedEnvelop.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1349.1.0)
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1348.0.0)
/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 3600.5.2)
/usr/lib/libsubstrate.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.4.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
WeChatRedEnvelop.dylib (architecture arm64):
/Library/MobileSubstrate/DynamicLibraries/WeChatRedEnvelop.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1349.1.0)
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1348.0.0)
/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 3600.5.2)
/usr/lib/libsubstrate.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.4.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
可以看到除了 substrate 庫,其它依賴的都是系統自帶的庫。我們將 libsubstrate.dylib 拷出,使用 install_name_tool 命令修改動態庫的路徑,指向 app 二進位文件的同級目錄。
$ scp root@<your.device.ip>:/usr/lib/libsubstrate.dylib ~/Desktop
$ install_name_tool -change /usr/lib/libsubstrate.dylib @loader_path/libsubstrate.dylib WeChatRedEnvelop.dylib
$ otool -L WeChatRedEnvelop.dylib
WeChatRedEnvelop.dylib (architecture armv7):
/Library/MobileSubstrate/DynamicLibraries/WeChatRedEnvelop.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1349.1.0)
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1348.0.0)
/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 3600.5.2)
@loader_path/libsubstrate.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.4.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
WeChatRedEnvelop.dylib (architecture arm64):
/Library/MobileSubstrate/DynamicLibraries/WeChatRedEnvelop.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1349.1.0)
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1348.0.0)
/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 3600.5.2)
@loader_path/libsubstrate.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 307.4.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
可以看到 libsubstrate.dylib 的路徑已經變更了。
將動態連結庫注入二進位文件中接下來,就需要將我們的庫注入到微信的二進位文件中,可以使用開源的 optool 工具。
編譯安裝 optool 工具:
# 因為 optool 添加了 submodule,因為需要使用 --recuresive 選項,將子模塊全部 clone 下來
$ git clone --recursive https://github.com/alexzielenski/optool.git
$ cd optool
$ xcodebuild -project optool.xcodeproj -configuration Release ARCHS="i386 x86_64" build
將砸殼過的 ipa 文件解壓,然後將 libsubstrate.dylib 與 WeChatRedEnvelop.dylib 拷貝到解壓後的 WeChat.app 目錄下。
$ cd ~/Desktop
$ unzip wechat.ipa -d wechat
$ cp libsubstrate.dylib WeChatRedEnvelop.dylib wechat/Payload/WeChat.app
使用 optool 把 WeChatRedEnvelop.dylib 注入到二進位文件中:
$ /path/to/optool install -c load -p "@executable_path/WeChatRedEnvelop.dylib" -t wechat/Payload/WeChat.app/WeChat
打包 ipa 與重籤名可以直接使用圖形化工具 ios-app-signer 來完成。
這個工具可以自動加載出本機的證書以及 Provisioning Profile 文件,使用起來十分方便,當然也可以手動選擇證書文件。
如果是使用個人開發者證書,需要先將設備的 UUID 加到 Provisioning Profile 中。
我這裡是直接從一個 archive 過的應用中提取 embedded.mobileprovision 文件,並在 Provisioning Profile 一欄中選擇 Choose Custom File 使用這個文件。
點擊 start 後,指定保存路徑,iOS App Signer 就會幫你搞定所有事情。
安裝在 iOS App Signer 完成打包與重籤名後,我們就可以進行安裝了。
安裝有兩種方法,一種是使用 iTool 工具安裝 ipa 文件。
另外一種是針對有 XCode 的同學,在菜單 - Window - Devices 中打開設置窗口。點擊 Installed Apps 欄下面的 + 號就可以選擇 ipa 文件進行安裝了。