IOS 逆向工程 APP破解
提要 :
經(jīng)過一個(gè)月斷斷續(xù)續(xù)對(duì)APP逆向工程的研究,這篇文章算是對(duì)逆向工程知識(shí)邁出了第一步,如果你對(duì)iOS逆向工程感興趣的話,建議你還是按照這篇文章的思路,在你的越獄手機(jī)上完整的實(shí)踐一遍,這樣你就會(huì)對(duì)那些基礎(chǔ)的越獄工具有了一個(gè)淺顯的了解。
如果不喜歡這個(gè)排版,可以訪問我的另一個(gè)博客網(wǎng)址
作業(yè)部落博客地址
準(zhǔn)備工作
- 越獄手機(jī)(例如我的:iPhone 5s,系統(tǒng)8.3)
- 越獄手機(jī)上的Cydia中安裝Cycript,OpenSSH
- 電腦端上安裝iFunBox,xCode,Hopper Disassembler,Sublime Text
- 電腦終端命令行中安裝Class Dump,Theos,Dumpdecrypted
工具作用介紹
OpenSSH:
Mac連接手機(jī),通過Mac的終端命令操作手機(jī)。
Cycript
獲取手機(jī)中某一個(gè)運(yùn)行的進(jìn)程,并可以獲取APP進(jìn)程后用oc代碼獲取反編譯APP的Documents目錄路徑。
iFunBox
Mac端的連接手機(jī)后的圖形界面,比較方便的把砸殼后的文件直接導(dǎo)出到Mac上。
xCode
這個(gè)就不作說明了
Hopper Disassembler
這個(gè)是進(jìn)行反匯編的工具,可以反匯編、反編譯并且調(diào)試你的應(yīng)用,我們可以通過這個(gè)工具查看偽代碼的方法名和變量,還原函數(shù)體的具體邏輯。
Class Dump
對(duì)APP可執(zhí)行文件獲取其頭文件,這樣我們可以根據(jù)頭文件中暴露的方法名去猜測(cè)其APP的編寫邏輯。然后利用上述的反編譯工具對(duì)某一文件進(jìn)行函數(shù)的具體編寫邏輯。
Theos
創(chuàng)建一個(gè)Tweak工程,通過定制工程文件,再通過指定的bundle id,編譯+打包+安裝,從而向手機(jī)上的APP注入代碼,進(jìn)而實(shí)現(xiàn)對(duì)某個(gè)APP中的功能的破解(例如會(huì)員去廣告功能,搶紅包功能,過濾好友列表功能)
Dumpdecrypted
俗稱:“砸殼”,dumpdecrypted是個(gè)出色的app脫殼開源工具,它的原理是:將應(yīng)用程序運(yùn)行起來(iOS系統(tǒng)會(huì)先解密程序再啟動(dòng)),然后將內(nèi)存中的解密結(jié)果dump寫入文件中,得到一個(gè)新的可執(zhí)行程序文件。
Sublime Text
打開后面要用到的Makefile文件
說了這些工具的用途之后,我們接下來開始我們的破解工作。
需要掌握的命令行
- 查看當(dāng)前xcode的sdk路徑:xcrun --sdk iphoneos --show-sdk-path
- 修改當(dāng)前xcode的默認(rèn)sdk: sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
- 文件夾中顯示和隱藏文件:defaults write com.apple.finder AppleShowAllFiles -bool false/true之后得重新啟動(dòng)Finder
- ps -e 獲取手機(jī)所有進(jìn)程
- ps -A|grep mobile 抓取手機(jī)上運(yùn)行的APP進(jìn)程
- cycript -p WeChat
實(shí)現(xiàn)目標(biāo)
我們打開微信APP后(在App Store中下載的軟件),自動(dòng)彈出一個(gè)警告框。
當(dāng)然這只是一個(gè)很簡(jiǎn)單的一步,我之前也是參考前人的文章。
參考文章iOS逆向工程
不過這篇文章是16年的,在實(shí)現(xiàn)的過程中還是碰到了幾個(gè)坑。
- 獲取可執(zhí)行程序文件WeChat.decrypted出錯(cuò)
- 在創(chuàng)建 Theos 工程后編譯(make)操作總是提示
ld: framework not found CydiaSubstrate- 在make成功后 make package時(shí)提示:
Can't locate IO/Compress/Lzma.pm in @INC (you may need to install the IO::Compress::Lzma module) (@INC contains: /Library/Perl/5.18/darwin-thread-multi-2level /Library/Perl/5.18 /Network/Library/Perl/5.18/darwin-thread-multi-2level /Network/Library/Perl/5.18 /Library/Perl/Updates/5.18.2 /System/Library/Perl/5.18/darwin-thread-multi-2level /System/Library/Perl/5.18 /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level /System/Library/Perl/Extras/5.18 .) at /opt/theos/bin/dm.pl line 12.
BEGIN failed--compilation aborted at /opt/theos/bin/dm.pl line 12.
make: [internal-package] Error 2
實(shí)現(xiàn)流程
1.生成砸殼用的dumpdecrypted.dylib
OpenSSH命令的使用:
前提:保證手機(jī)和Mac在同一個(gè)網(wǎng)段上。
登錄成功后就可以使用終端命行操作iPhone
退出登錄命令是exit
ps -e 獲取手機(jī)中所有的當(dāng)前運(yùn)行的進(jìn)程
ps -A|grep mobile 抓取手機(jī)上運(yùn)行的APP進(jìn)程
這兒有兩個(gè)路徑
/var/mobile/Containers/Bundle/Application/下的是我們要找的可執(zhí)行文件
/var/mobile/Containers/Data/Application
得到Documents路徑,也就是APP所在的沙盒路徑,而我們之后要生成解密后文件的命令行得需要在APP真正的路徑下執(zhí)行。
Cycript命令行:
沙盒路徑的獲取: [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]
踩坑點(diǎn):當(dāng)命令行中輸入cycript -p WeChat后并沒有出現(xiàn)下面的cy#這一行時(shí),你最好用數(shù)據(jù)線連接手機(jī)(這樣你會(huì)發(fā)現(xiàn)輸入命令不卡),之后打開微信程序后,這時(shí)候cy#這一行就出現(xiàn)了,同樣獲取沙盒路徑也得打開程序,不然不會(huì)出現(xiàn)你想要的結(jié)果,退出cyscript命令環(huán)境control+z。
這一階段的目的:制作砸殼的“錘頭”,因?yàn)椴煌琲OS系統(tǒng)下的dumpdecrypted.dylib(錘頭)是不同的。
如果你的手機(jī)系統(tǒng)是8.0的可以直接下載我上傳GitHub上的文件,那么你可不用看生成“錘頭”的部分。
開始生成“錘頭”
用Sublime Text打開下載的dumpdecrypted文件夾里面的Makefile,配置里面的參數(shù)
GCC_UNIVERSAL=$(GCC_BASE) -arch armv7 -arch armv7s -arch arm64
如果是7.0以下的設(shè)備我們還需要改些東西,我們要將上圖的第二行修改為
GCC_UNIVERSAL=$(GCC_BASE) -arch armv7 -arch armv7s
還要將dumpdecrypted文件夾里的dumpdecrypted.c文件的第76行
if (lc->cmd == LC_ENCRYPTION_INFO || lc->cmd ==LC_ENCRYPTION_INFO_64)
改為
if(lc->cmd == LC_ENCRYPTION_INFO)
到相應(yīng)的目錄下(cd dirc),
執(zhí)行命令行:make
完成后dumpdecrypted.dylib文件出現(xiàn)在當(dāng)前目錄下,這個(gè)就是我們?cè)覛び玫腻N頭。
踩坑點(diǎn):如果你的手機(jī)是ios8.3的系統(tǒng),就需要下載xcode6.3的版本,這兒是下載鏈接,并且需要切換你的默認(rèn)xcode路徑,首先看看你默認(rèn)的xcode是iosSDK是多少的。
命令行:xcrun --sdk iphoneos --show-sdk-path //查看iosSDK版本路徑
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
修改默認(rèn)的iosSDK
獲取“錘頭”完成
砸殼獲取解密后的可執(zhí)行文件
- 將dumpdecrypted.dylib拷貝到Documents路徑下
1 命令行:scp
dumpdecrypted.dylib路徑
root@設(shè)備IP:Documents路徑
;
2 利用iFunBox
- cd Documents路徑 //到APP的Documents路徑下執(zhí)行命令
DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib 可執(zhí)行文件路徑
建議用第二種方法
DE6B36FA-2578-4C5F-BA36-15DCC046B206.png
利用iFunBox到APP的Documents路徑
命令行成功,APP的Documents路徑會(huì)生成APP的解密后的可執(zhí)行文件
最后我們把.decrypted文件拷到Mac上
2.反編譯靜態(tài)分析(Hopper Disassembler登場(chǎng))
把.decrypted丟進(jìn)去,你會(huì)看到很炫酷的界面。至于這個(gè)軟件的下載,
具體的操作你可以看看這篇文章,這個(gè)是在比較小的demo上去介紹Hopper Disassembler的原理的。
Hopper Disassembler的反編譯的基礎(chǔ)demo
如果你把上篇簡(jiǎn)書中的文章照著實(shí)現(xiàn)了一遍的話,你就會(huì)對(duì)Hopper Disassembler有了自己的了解了。
3.Tweak與Theos
簡(jiǎn)介:tweak的實(shí)質(zhì)就是ios平臺(tái)的動(dòng)態(tài)庫(kù)。IOS平臺(tái)上有兩種形勢(shì)的動(dòng)態(tài)庫(kù),dylib與framework。Framework這種開發(fā)者用的比較多,而dylib這種就相對(duì)比較少一點(diǎn),比如libsqlite.dylib,libz.dylib等。而tweak用的正是dylib這種形勢(shì)的動(dòng)態(tài)庫(kù)。我們可以在/Library/MobileSubstrate/DynamicLibraries目錄下查看手機(jī)上存在著的所有tweak。這個(gè)目錄下除dylib外還存在著plist與bundle兩種格式的文件,plist文件是用來標(biāo)識(shí)該tweak的作用范圍,而bundle是tweak所用到的資源文件。
與正常的APP開發(fā)使用xcode不同,Tweak的開發(fā)環(huán)境是theos或者iosopendev。iosopendev是在theos的基礎(chǔ)上實(shí)現(xiàn)的基于xcode的開發(fā)環(huán)境。而theos是一種命令行式的開發(fā)編譯環(huán)境,與c/c++的命令行編譯形式很相象。
這里的概述摘自簡(jiǎn)友的這篇文章,感興趣的可以看看,個(gè)人認(rèn)為總結(jié)的還是很全面的。
Mac的環(huán)境下載,網(wǎng)上有很多關(guān)于Theos的下載及配置的博客,但有些是很早的資料,這里我是參考這篇文章的。
創(chuàng)建theos工程(package name 只能包含小寫的字母還有數(shù)字)
踩坑點(diǎn):nic.pl命令行并沒有反應(yīng),這是你沒有配置環(huán)境路徑
export THEOS=/opt/theos
export PATH=/opt/theos/bin/:$PATH
主要需要注意的地方
- Theos 要求我們輸入 MobileSubstrate Bundle filter,也就是 tweak 作用對(duì)象的 bundle identifier,這里我們填上微信的 id(com.tencent.xin),可以在解壓后的 ipa 包中的 plist 文件中找到。
- 最后我們需要輸入指定 tweak 安裝完成之后需要重啟的應(yīng)用,以 bundle identifier 來表示,這里還是填上微信。
到這里工程便創(chuàng)建完成了,會(huì)在當(dāng)前目錄下生成工程文件夾。
接下來就是定制工程文件了
編輯 MakeFile
編寫 tweak 源碼
方便懶人
%hook MicroMessengerAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"成功注入代碼" message:@"IOS 逆向工程" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:nil];
[alertView show];
#pragma clang diagnostic pop
return %orig;
}
%end
定制完畢
接下來就是激動(dòng)人心的make操作了
這是說找不到ios8.3的SDK,那么這時(shí)候你得切換默認(rèn)的iosSDK路徑了。
sudo xcode-select -s /Applications/Xcode6.3.app/Contents/Developer
這是什么??!!!怎么辦,很慌。
找各種帖子資料
最后的解決辦法(MakeFile文件中配置)
TARGET = iphone::9.2:8.3
Clang actually supports it as of Xcode 7.0 (iOS SDK 9.0), but enable it only if you're using iOS SDK 8.4+. I wasn't too sure how it would work out when I implemented it so I restrained it to the latest SDK at the time. It certainly could be dropped back to 9.0+.
就是說Clang在ios9.0上才支持,所以我們的TARGET是包含9.0的,當(dāng)然你手機(jī)如果是9.0的系統(tǒng)就不會(huì)報(bào)錯(cuò)了。(哦咪頭佛)
make一下(雙手合十,賜予我力量吧!!!)
這樣我們離成功又進(jìn)了一步了
題外話:筆者在解決這個(gè)問題時(shí),可謂生不如死啊,查閱各種資料,建議各位還是在Google下查閱資料,中間因?yàn)檫@個(gè)問題還擱置了對(duì)逆向工程的研究。
之后make package
Can't locate IO/Compress/Lzma.pm in @INC (you may need to install the IO::Compress::Lzma module)
可能出現(xiàn)這個(gè)問題,這時(shí)候執(zhí)行
sudo cpan -I IO::Compress::Lzma
安裝
最后,要將這個(gè) deb 文件安裝到 iOS 中去,采用了命令行的安裝方法。
這個(gè)錯(cuò)誤是因?yàn)槲艺`將 Makefile 中需要 kill 的進(jìn)程名稱填成了 bundle identifier,將它改成 WeChat 就好了:killall -9 WeChat
打開手機(jī)的微信后,你會(huì)看到這個(gè)效果。
文章到此結(jié)束!!!
特別說明:寫這篇博客個(gè)人參考的前人博客