在我們通過(guò)將代碼重新簽名(如果對(duì)第三方app重簽名不太熟悉的,請(qǐng)參考iOS逆向安全之代碼重簽名)能夠讓我們?cè)诒镜赝ㄟ^(guò)Xcode進(jìn)行代碼調(diào)試后,我們一般會(huì)進(jìn)行我們想要進(jìn)行的操作,比如對(duì)對(duì)方APP包進(jìn)行動(dòng)態(tài)分析,或者進(jìn)行篡改.這個(gè)時(shí)候我們?nèi)绻獙?duì)第三方app進(jìn)行我們自己的修改,我們就會(huì)考慮將代碼注入到第三方app中.此時(shí)我們就要進(jìn)行代碼注入了.
代碼注入:
在iOS中一般通行的注入手段是通過(guò)Framework注入或者dylib注入.
Framework注入:
1.添加framework.?
首先我們?cè)谝呀?jīng)重簽名的項(xiàng)目中添加一個(gè)我們用于注入的framework.并在該framework中添加我們的注入類.
2.編寫(xiě)注入代碼.
在能夠確保執(zhí)行的接口中編寫(xiě)我們需要注入的代碼進(jìn)行自己想要的操作.一般為了保證我們注入的代碼能夠執(zhí)行,我們通常是在load方法中編寫(xiě).該方法會(huì)在我們的注入類被加載的時(shí)候調(diào)起.
3.將framework注入到MachO.
此時(shí)進(jìn)行運(yùn)行,framework會(huì)被我們的Xcode進(jìn)行打包到App的framework文件夾中,但是依舊不會(huì)被加載運(yùn)行,因?yàn)闆Q定一個(gè)framework是否被加載,是dyld根據(jù)MachO文件load_commands下的LC_load_dylib字段中是否包含這個(gè)framework而定.所以我們需要將這個(gè)framework注冊(cè)到第三方app的MachO文件里.
3.1 我們通過(guò)yololib(這個(gè)工具可以修改MachO文件)進(jìn)行framework的注入操作.先將yololib放到/user/local/bin路徑下.然后解壓咱們需要注入的app包.(注意一定要確保app是原始的app包!否則會(huì)被每次運(yùn)行時(shí)候的重簽名操作給覆蓋!)
3.2 在終端中通過(guò)命令yololib(空格)MachO文件路徑(空格)庫(kù)路徑 來(lái)將MachO文件里添加我們的framework.
此時(shí)我們就會(huì)在MachO中發(fā)現(xiàn)LC_LOAD_DYLIB中多出了我們的framework.具體可以自行用MachOView查看.
3.3 重新打包已經(jīng)更改后的app成ipa包.
4.用新的ipa包進(jìn)行運(yùn)行調(diào)試,確定是否注入成功.
此時(shí)我們就可以用新的ipa包進(jìn)行重簽名并運(yùn)行查看注入效果了.
跳坑感受:
才開(kāi)始做注入時(shí)候,一直在簽名那里報(bào)錯(cuò),最典型的一個(gè)坑是簽名失效的錯(cuò)誤,卡了我?guī)滋?錯(cuò)誤樣式如下:
我曾經(jīng)一度以為是我在簽名時(shí)候的Shell腳本寫(xiě)錯(cuò)了,或者是我的證書(shū)過(guò)期,或者是我用于簽名的權(quán)限文件沒(méi)有給app包打上.在一系列的排查,甚至去手動(dòng)配置項(xiàng)目的framework上面的簽名信息(一般是直接勾選簽名自動(dòng)管理automaticlly manage signing).結(jié)果還是沒(méi)用.后來(lái)最終才發(fā)現(xiàn),原來(lái)是framework在引入到我們的項(xiàng)目時(shí)候,它的開(kāi)發(fā)版本是最新的,但是我們的設(shè)備版本卻一般比較低,一般開(kāi)發(fā)人員只會(huì)在target那里設(shè)置低開(kāi)發(fā)版本,framework不會(huì)在引入的時(shí)候自動(dòng)匹配你的target版本.(實(shí)在是郁悶...),這也是導(dǎo)致簽名失效的原因.所以我們千萬(wàn)不要忘了將framework在引入的時(shí)候手動(dòng)將其調(diào)整到與target保持一致(低于設(shè)備的系統(tǒng)版本)
DyLib注入:
1.添加一個(gè)Dylib.
1.1修改它的環(huán)境屬性.
由于dylib是mac環(huán)境下的,所以無(wú)法用于在iOS環(huán)境下,需要修改lib的BaseSDK.將其由macOS改為iOS.
再將其的簽名識(shí)別修改為iOSDeveloper.
2.為dylib設(shè)置依賴
由于dylib是Xcode在早期時(shí)候引入的,舊版本的Xcode在將文件打包遷移時(shí)需要設(shè)置依賴,dylib也是如此.需要我們手動(dòng)設(shè)置依賴,以確保,我們的dylib為打包進(jìn)app包的framework文件夾中
2.1配置依賴
3.在dylib中編寫(xiě)我們的注入代碼.
4.使用yololib將dylib注冊(cè)進(jìn)MatchO中.
值得注意的是,dylib直接就是一個(gè)文件,并非一個(gè)文件夾,所以路徑到dylib包為止并不需要再指向它內(nèi)部的可執(zhí)行文件中.
下面的步驟跟上面的Framework一致,最終運(yùn)行查看結(jié)果即可.
跳坑感受:
最初在做dylib進(jìn)行注入時(shí)候,總是報(bào)image refrence from的錯(cuò)誤,dyld在加載時(shí)候在路徑下找不到我們的dylib,通過(guò)查看app路徑下的framework中確實(shí)這個(gè)dylib沒(méi)有被打包進(jìn)framework文件夾中.我反復(fù)檢查了我的步驟似乎沒(méi)有什么問(wèn)題,不知道是否是因?yàn)槲业捻?xiàng)目framework和dylib同時(shí)都引進(jìn)去的原因互相影響還是什么關(guān)系,說(shuō)一下我的解決方案:我當(dāng)時(shí)是直接舍棄Xcode打包操作.將文件的引用關(guān)系給干掉
這樣X(jué)code就不會(huì)將我們的包給打進(jìn)Framework里,然后在編譯路徑下,運(yùn)行編譯后的lib和framework給直接拷貝進(jìn)我們目標(biāo)App的framework中.
然后我們?cè)僦匦聦⑦@個(gè)app打包成ipa,按照正常的編譯,yololib進(jìn)行注入MatchO,直接運(yùn)行,這樣編譯器就不會(huì)找不到我們的lib以及framework的路徑了.
但是這個(gè)解決方案有個(gè)致命的弊端就是雖然能夠解決這個(gè)問(wèn)題,但是每次我們修改了我們的注入庫(kù)代碼,要重新運(yùn)行的時(shí)候又得重新拷貝編譯結(jié)果,重新打包運(yùn)行.所以很麻煩,當(dāng)然逆向的工程本來(lái)就坑點(diǎn)重重,不管如何解決,只要能解決就成,哈哈哈.
MonkeyDev工具注入:
其實(shí),最好用的注入方式還是使用MonkeyDev工具.將可以省卻從簽名,到配置注入前期的所有事情,MokeyDev的安裝請(qǐng)參考官方文檔:MonkeyDev-WiKi
按照好MonkeyDev后,我們只需要?jiǎng)?chuàng)建一個(gè)MonkeyApp就可以了,如果在創(chuàng)建工程時(shí)候沒(méi)有顯示圖中最后一行的代表MonkeyDev插件沒(méi)有安裝成功.
通過(guò)MonkeyDev創(chuàng)建工具進(jìn)行重簽非常簡(jiǎn)單,只需要在項(xiàng)目工程目錄里的TargetApp中放入需要重簽的ipa或者app包(當(dāng)然所有這些ipa包和app包都需要已經(jīng)砸殼過(guò)的)然后直接運(yùn)行項(xiàng)目就可以了.
MonkeyApp集成了很多Hook的工具類例如常用的fishHook,Cydia substract等.也支持用Logos語(yǔ)法.使用者可以直接用它所提供的已經(jīng)注入的dylib進(jìn)行注入.具體使用方法直接參考上面提供的官方文檔就可以了.