上一章我們講到了在非越獄的iOS上進行App Hook。利用這個技術,你可以在非越獄的iOS系統上實現各種hook功能(e.g., 微信自動搶紅包,自動聊天機器人,游戲外掛等)。但因為篇幅原因,有一些細節并沒有講的非常清楚。沒想到閱讀量非常大,很多人都來私信問我一些hook中遇到的問題,并且問的問題都很類似。于是我專門寫了一篇答疑的文章來幫助大家解決一些常見的問題,順便介紹一下如何在iOS 9上進行app 砸殼 (Dumpdecrypted)。另外想看主線劇情的讀者也不要著急,下一篇就會給大家帶來如何過沙盒的文章。
《iOS冰與火之歌》系列的目錄如下:
另外文中涉及代碼可在我的github下載:
https://github.com/zhengmin1989/iOS_ICE_AND_FIRE
很多人私信給我提到hook.dylib無法編譯成功,這個問題大多是因為沒有安裝Command Line Tools和越獄開發環境iOSOpenDev造成的,這兩個工具都是搞iOS安全必備的環境,可以按照以下步驟進行安裝:
Command Line Tools 是Xcode的一個命令行工具插件,安裝方法有兩種:
(1) 打開終端,輸入:
#!bash
xcode-select --install
(2) 去蘋果官網下載安裝包
https://developer.apple.com/downloads/
iOSOpenDev里提供了很多越獄開發的模板,可以在http://iosopendev.com/download/下載到。安裝完iOSOpenDev后就可以在Xcode里通過新建一個project看到我們進行非越獄Hook的時候需要用的CaptainHook了。
我們開發時的app默認是沒有加密的,但App Store上下載的app卻被加了密。如果我們想要進行hook以及重打包的話,我們需要拿到解密后的app才行,否則的話,就算hook成功,簽名成功,安裝成功,app還是會閃退。
(1) 查看app是否加密:
首先用file來看一下ipa解壓后的二進制文件包含哪些架構(e.g., armv7, arm64)。如果有多個架構的話,最好是把所有的架構都解密了。但理論上只要把最老的架構解密就可以了,因為新的cpu會兼容老的架構。比如我們拿微博作為例子,可以看到weibo的客戶端包含了armv7和arm64這兩個架構。
隨后我們可以通過”otool –l
”來輸出app的load commands,隨后再查看cryptid這個標志位來判斷app是否被加密了。如果是1的話代表加密了,如果是0的話代表解密了。
從上圖可以看到,weibo的armv7架構的代碼被加密了,arm64架構卻是解密的,原因是我已經通過dumpdecrypted對arm64架構的代碼砸過殼了。如果沒有解密的話,用ida打開app會看到加密的提示:
(2) dumpdecrypted砸殼:
如果需要解密的話,我們就需要用工具進行砸殼。最有名的砸殼工具就是dumpdecrypted了。他的原理是讓app預先加載一個解密的dumpdecrypted.dylib,然后在程序運行后,將代碼動態解密,最后在內存中dump出來整個程序。這個工具可以在: https://github.com/stefanesser/dumpdecrypted下載到。但下載完的只是源碼,我們還需要編譯一下,這里我會放一份編譯好后的dumpdecrypted.dylib到我的github上。
雖然hook可以在越獄的環境下實現,但是想要砸殼的話,必須具備越獄的環境,比如這篇文就使用的越獄后的iOS 9。用ssh連接上iOS設備后,我們打開想要砸殼的app。然后輸入ps ax
,就可以在進程中找到這個app的二進制文件的地址:
因為每個app目錄下都有一個Info.plist。我們可以通過這個Info.plist得到app的Bundle ID:
#!bash
cat /var/mobile/Containers/Bundle/Application/19A9AE5E-22DC-449A-A530-C793D88ACB24/Weibo.app/Info.plist
比如Weibo的Bundle ID就是:com.sina.weibo。得到BundleID后我們下一步要知道app的data目錄,原因是app的運行會受到沙盒的限制,因此dump出來的app只能保存在自己的data目錄下,這里我們可以通過Bundle ID和一個private API得到data目錄的位置:
代碼如下:
#!objc
NSString* bundleID = [[NSString alloc] init];
bundleID = @"com.sina.weibo";
id dataID = [[NSClassFromString(@"LSApplicationProxy") applicationProxyForIdentifier:bundleID] dataContainerURL];
NSLog(@"%@",dataID);
得到data目錄的地址后,我們將dumpdecrypted.dylib 拷貝到data的tmp目錄下,然后在tmp目錄下執行DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/19A9AE5E-22DC-449A-A530-C793D88ACB24/Weibo.app/Weibo
進行砸殼。
然后在目錄下就可以得到砸殼后的二進制文件了,要注意的是我們砸殼后的app只能解密砸殼運行時的架構,所以我建議找個armv7架構的iOS設備進行砸殼,然后執行:
#!bash
lipo app -thin armv7 -output app_armv7
就可以把app的armv7架構抽取出來。這樣的話,就可以保證app只在armv7的模式下運行了。
(3) 越獄市場下載:
當然,除了利用dumpdecrypted獲取解密后的app還可以直接在PP助手的越獄市場上下載到,這些越獄應用都是解密后的app。但不能保證下載到AppStore上所有的app。
有人會問如何獲取embedded.mobileprovision這個文件,因為自己開發的app默認會有embedded.mobileprovision,但從AppStore上下載app并沒有。其實,除了在developer center上通過錄入device的UDID,然后下載embedded.mobileprovision之外,我們還可以利用xcode自動生成embedded.mobileprovision。比如我們想要重打包微博這個app,只要新建一個app(為了確保萬無一失,可以把app的Bundle ID也起為com.sina.weibo),然后把手機連接上電腦,編譯并在手機上運行這個app。然后只要去app的目錄下拷貝embedded.mobileprovision就可以了。這樣獲取的embedded.mobileprovision可以保證能夠適配重打包的app。如下圖所示:
簽名的時候我們需要提供entitlement的信息,這個entitlement是什么呢?其實這個entitlement是用來做iOS權限管理的,通過聲明不同的entitlement就能得到不同的權限。并且這個信息已經保存到了二進制文件里。比如我們可以通過”ldid –e
”來查看一個二進制文件的entitlement。比如Weibo的entitlement為:
理論上需要給app簽上原app對應的所有entitlement才行。
另外,除了app本身需要簽名以外,app的PlugIn,WatchNative App,WatchNative App的PlugIn如果有的話,都需要簽名才行,拿WeChat舉例,我們要對如下的內容都簽名才可以:
#!bash
codesign -f -s "iPhone Developer: [email protected] (**********)" WeChat.app/Watch/WeChatWatchNative.app/PlugIns/WeChatWatchNativeExtension.appex
codesign -f -s "iPhone Developer: [email protected] (**********)" WeChat.app/Watch/WeChatWatchNative.app
codesign -f -s "iPhone Developer: [email protected] (**********)" WeChat.app/PlugIns/WeChatShareExtensionNew.appex
codesign -f -s "iPhone Developer: [email protected] (**********)" WeChat.app/hook2.dylib
codesign -f -s "iPhone Developer: [email protected] (**********)" --entitlements Entitlements.plist WeChat.app
上一篇中介紹了一種利用libimobiledevice來安裝ipa的方法。但我在嘗試安裝特別大的ipa的時候(大于50M),經常會失敗,需要嘗試多次才行。這里有個小技巧,如果有條件的話,可以使用windows下的itools來輔助我們安裝,基本上一次就能搞定了。
這篇文章基本上解決了app hook過程中遇到的常見問題,還介紹了iOS 9上砸殼的技術。如果還遇到問題的話,大家可以通過xcode里的log來分析原因,然后嘗試解決問題。至此,iOS app的安全(番外篇)就告一段落了。下一章將會進入主線劇情,給大家帶來app過沙盒的技術,敬請期待。