在學習了上一章什麼是加密解密、數字簽名以及證書以後,如今咱們再來學習iOS的簽名機制就事半功倍了。其實iOS簽名機制的做用就是保證安裝到用戶手機上的App都是通過Apple官方容許的。固然,越獄設備除外。ios
在平時開發時,不論是真機調試,仍是發佈App到App Store,咱們都須要通過如下幾個步驟git
通過以上的一系列操做以後,咱們最終就能夠拿到ios_development.cer或者ios_distribution.cer證書文件,以及mobileprovision描述文件。經過安裝這些文件到Mac上就能夠進行真機調試。固然,若是你在Xcode中勾選了Automatically manage signing選項,那麼Xcode會自動幫咱們執行以上的全部操做。github
那麼,以上操做每一步執行的做用是什麼?最後得到的ios_development.cer或者ios_distribution.cer證書文件,以及mobileprovision描述文件的做用又是什麼?這些文件中又包含了什麼內容?bash
要想知道上述全部文件的具體做用,就須要瞭解iOS簽名的完整流程。在使用Xcode編譯、運行完項目以後,Xcode其實幫咱們作了簽名操做。markdown
其實就是利用codeSign指令對.app文件進行簽名操做。app
想要執行iOS簽名流程,就須要有如下公鑰、私鑰信息iphone
iOS項目在編譯完成以後會生成.app文件,App的簽名操做從拿到.app文件開始ide
對.app安裝包進行簽名以後,壓縮生成ipa安裝包,而後將ipa安裝包安裝到iPhone上時,會進行簽名驗證操做。工具
在文件mobileprovision中,有devices、app id以及entitlement信息,它們的做用分別是:oop
- devices標識着哪些設備能夠安裝此App,若是設備不在devices中,安裝會失敗。
- app id,指定此標識的App才能安裝,若是App的惟一標識和此app id不對應,則安裝失敗。
- entitlement中存放在App所具有的權限信息,若是App所使用的權限和entitlement中存放的權限不一致,也會產生問題。
上文學習了iOS簽名的具體流程,如今,咱們就來一步步的執行實際的操做來對咱們所學的簽名流程進行驗證。同時瞭解ios_development.cer或者ios_distribution.cer證書文件,以及mobileprovision等文件的實際做用。
此步驟就是利用Apple的私鑰,對Mac公鑰進行簽名,生成證書文件ios_development.cer和ios_distribution.cer
此步驟就是將devices、app id、entitlement和證書文件,經過Apple私鑰進行簽名,生成最後的mobileprovision文件。並且生成的mobileprovision文件就決定了當前App能夠安裝的設備有哪些,能夠安裝的App的BundleId,以及App所擁有的權限。
Apple官方驗證流程以下:
當咱們逆向了一款App,爲App編寫了相應的插件,而且安裝到了咱們本身的越獄手機上。可是,逆向過的App只能在本身越獄手機上使用,若是咱們想要將App和咱們本身編寫的插件從新打包,安裝到未越獄的iPhone上,那就須要學習如何對App進行重簽名。
學習重簽名以前,須要注意幾點
生成mobileprovision文件有兩種方式,第一種是經過Xcode自動生成,在編譯後的App包中能夠找到,第二種是到Apple官網生成,上文有詳細步驟。
// 首先從embedded.mobileprovision文件中導出權限信息,存放到temp.plist中 security cms -D -i embedded.mobileprovision > temp.plist # 而後使用PlistBuddy工具將temp.plist轉換成Entitlements格式的文件entitlements.plist /usr/libexec/PlistBuddy -x -c 'Print :Entitlements' temp.plist > entitlements.plist 複製代碼
security find-identity -v -p codesigning
複製代碼
獲得的結果以下
➜ ~ security find-identity -v -p codesigning 1) D9E2802126C89BF6BF6621064FC5547F895FC25E "iPhone Developer: xxxxx@xxxx.com (KT9PJDKFVG)" 複製代碼
# -fs 是 -f -s 的縮寫 codesign -fs 證書ID xxx.dylib 複製代碼
codesign -fs 證書ID --entitlements entitlements.plist xxx.app
複製代碼
使用Xcode編譯本身的項目,咱們知道源碼,因此知道怎麼修改Mach-O文件,可是若是咱們在逆向別人的App時,是不知作別人的源碼的,因此沒法直接修改Mach-O文件。
以前的文章中學習了Theos,知道了怎麼經過建立Tweak項目來修改App的行爲,具體流程能夠查看iOS逆向學習之六(Theos實戰演練)這篇文章。
建立了Tweak項目以後,經過Cydia安裝到越獄手機上,而後就能夠改變App的行爲。具體是怎麼實現的呢?
Tweak項目本質上是生成動態庫,並且動態庫不是存放在.app目錄下,因此,想要將咱們逆向過的App安裝到別人的手機上,首先須要作的就是將Tweak項目生成的動態庫注入到App中的可執行文件中,也就是Mach-O文件中。
可使用insert_dylib庫來將動態庫注入到Mach-O文件中,能夠經過insert_dylib庫主頁下載insert_dylib工具。在Release環境下編譯,獲得命令行工具,將命令行工具放在/usr/local/bin目錄下。
insert_dylib的本質其實就是往Mach-O文件的Load Commands中添加了一個LC_LOAD_DYLIB或者LC_LOAD_WEAK_DYLIB。具體注入方法以下:
insert_dylib 動態庫加載路徑 Mach-O文件 --all-yes --weak
複製代碼
查看動態庫依賴信息兩種方式
otool -L Mach-O文件
複製代碼
在向Mach-O文件中注入動態庫以後,須要更改Mach-O文件中動態庫的加載地址,不然在App運行時,會由於找不到動態庫報錯。
可使用install_name_tool指令來修改Mach-O文件中動態庫的加載地址:
install_name_tool -change 舊地址 新地址 Mach-O文件
複製代碼
須要注意的是,上述指令中的新地址,必須填寫全路徑地址,可是咱們不知道App安裝到手機上後dylib存放的具體地址,所以,可使用如下兩個經常使用的環境變量:
能夠點擊下載iReSign源碼,運行裏面的Mac應用,提供.app包的路徑、entitlements.plist路徑和embedded.mobileprovision的路徑,就能夠對.app進行重簽名,而後打包生成ipa文件。
能夠點擊下載iOS App Signer源碼,選擇Release環境進行編譯,拿到編譯後的Mac應用,就能夠直接使用。只需提供.app包的路徑和embedded.mobileprovision的路徑
如今咱們就來使用Xcode生成.app包,而後一步一步實現重簽名的過程。
#import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UILabel *labelA; @property (weak, nonatomic) IBOutlet UILabel *labelB; @property (weak, nonatomic) IBOutlet UILabel *labelResult; @end @implementation ViewController int a = 10; int b = 20; - (void)viewDidLoad { [super viewDidLoad]; self.labelA.text = [NSString stringWithFormat:@"%d",a]; self.labelB.text = [NSString stringWithFormat:@"%d",b]; self.labelResult.text = [NSString stringWithFormat:@"%d",a + b]; } @end 複製代碼
<font color=red>0A</font>轉換成10進制就是10,對應着全局變量a,<font color=red>14</font>轉換成10進制就是20,對應着全局變量b。
複製代碼
直接修改Mach-O文件,將全局變量a的值修改爲14,也就是將a的值改成20。
從新壓縮生成.ipa文件,使用iFunBox將ipa安裝到同一臺手機上,會出現安裝失敗提示,緣由是.app中的Mach-O文件已經被篡改,它的簽名也將會失效。因此安裝在iPhone上時對App的簽名驗證也會失敗,因此會致使安裝失敗。此時就須要對.app進行重簽名。
拿到TestSign.app包中的embedded.mobileprovision文件,從embedded.mobileprovision文件中提取出entitlements.plist文件,指令以下:
// 首先從embedded.mobileprovision文件中導出權限信息,存放到temp.plist中 security cms -D -i embedded.mobileprovision > temp.plist # 而後使用PlistBuddy工具將temp.plist轉換成Entitlements格式的文件entitlements.plist /usr/libexec/PlistBuddy -x -c 'Print :Entitlements' temp.plist > entitlements.plist 複製代碼
security find-identity -v -p codesigning
複製代碼
codesign -fs 1BEA2FE8783A297CF30B7728849EB225231D67E8 --entitlements entitlements.plist TestSign.app
複製代碼
出現上圖效果,代表重簽名成功,此時,從新壓縮TestSign.app文件,獲得ipa,安裝到以前的手機上就能夠安裝成功,同時,由於全局變量a的值被咱們改爲了20,因此界面上展現的是20 + 20 = 40。至此,重簽名操做完成。
下面爲騰訊視頻開發Theos插件,而後注入到騰訊視頻App,而且從新生成ipa,安裝到非越獄手機上,
@interface QLHomeController - (id)presentViewController:(id)controller animated:(BOOL)animated completion:(id)completion; @end %hook QLHomeController - (void)viewDidAppear:(BOOL)animated{ %orig; UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:@"提示框" message:@"測試Theos插件" preferredStyle:UIAlertControllerStyleAlert]; [alertVc addAction:[UIAlertAction actionWithTitle:@"關閉" style:UIAlertActionStyleCancel handler:nil]]; [self presentViewController:alertVc animated:YES completion:nil]; } %end 複製代碼
獲取如下簽名須要的一些文件
將test_live.dylib、CydiaSubstrate和embedded.mobileprovision文件複製到live4iphone.app包中。
向live4iphone.app包中的可執行文件中注入動態庫
insert_dylib @executable_path/test_live.dylib live4iphone --all-yes --weak live4iphone
複製代碼
出現如下結果代表注入成功:
➜ live4iphone.app insert_dylib @executable_path/test_live.dylib live4iphone --all-yes --weak 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 複製代碼
使用otool指令或者MachOView查看騰訊視頻的可執行文件,能夠發現動態庫已經注入到Mach-O文件當中
- 此時發現<font color=red>CydiaSubstrate</font>的路徑是<font color=red>/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate</font>,可是在非越獄手機上是沒有這個路徑的,因此須要經過install_name_tool指令來改變更態庫的加載路徑。
```
install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @loader_path/CydiaSubstrate test_live.dylib
```
再次查看<font color=red>test_live.dylib</font>的依賴庫信息,會發現<font color=red>CydiaSubstrate</font>庫的路徑變成了<font color=red>@loader_path/CydiaSubstrate</font>
複製代碼
➜ live4iphone.app codesign -fs 1BEA2FE8783A297CF30B7728849EB225231D67E8 test_live.dylib
test_live.dylib: replacing existing signature
➜ live4iphone.app codesign -fs 1BEA2FE8783A297CF30B7728849EB225231D67E8 CydiaSubstrate
CydiaSubstrate: replacing existing signature
➜ live4iphone.app
複製代碼