逆向App總體思路
UI分析
Cycript 、Reveal;
代碼分析
代碼在Mach-O 文件,所以要對(duì)Mach-O 文件進(jìn)行靜態(tài)分析;
MachOView、class-dump、Hopper Disassember、ida;
動(dòng)態(tài)調(diào)試
對(duì)運(yùn)行中App 進(jìn)行代碼調(diào)試
debugserver、LLDB;
代碼編寫
注入代碼到app中
必要時(shí)還可能需要重新簽名、打包ipa;
MonkeyDev安裝與使用
非越獄插件開(kāi)發(fā)集成神器
安裝
MonkeyDev下載地址:https://github.com/AloneMonkey/MonkeyDev
安裝步驟:
官方說(shuō)明文檔地址:https://github.com/AloneMonkey/MonkeyDev/wiki
使用
1、點(diǎn)擊File - New - Project...創(chuàng)建iOS項(xiàng)目,選擇MonkeyApp。
創(chuàng)建完成后,是這樣的一個(gè)工程;
MonkeyTestAppDylib這個(gè)是將被注入目標(biāo)App的動(dòng)態(tài)庫(kù),你自己要hook的代碼可以在MonkeyTestAppDylib.m文件里面寫,支持OC runtime的HOOK,C函數(shù)的fishhook。AntiAntiDebug這個(gè)里面是反反調(diào)試的代碼。
fishhook這個(gè)是自動(dòng)集成的fishhook模塊。MonkeyDev的Framewroks已經(jīng)自動(dòng)集成了RevealServer.framework和libcycript.dylib。如果選擇Release編譯的話是不會(huì)集成的。
2、準(zhǔn)備脫殼后的ipa文件,然后右鍵項(xiàng)目里面的TargetApp文件夾Show in Finder,把ipa文件拖入下面的位置。TargetApp文件夾下的put ipa or app here這個(gè)文件不要?jiǎng)h除。
3、注意事項(xiàng):
在Xcode 12上運(yùn)行會(huì)有2個(gè)錯(cuò)誤:
1、動(dòng)態(tài)庫(kù)證書錯(cuò)誤解決方法:在TARGETS的 Build Settings 下添加 CODE_SIGNING_ALLOWED 為NO
2、ld: file not found: /usr/lib/libstdc++.dylib 錯(cuò)誤
解決方法:
在MonkeyTestAppDylib 的 Build Settings 的Other Linker Flags 中移除掉 /usr/lib/libstdc++.dylib和-weak_library。
Reveal 安裝與使用
Reveal是一個(gè)很強(qiáng)大的UI分析工具,UI分析非常直觀,用來(lái)查看app的UI布局相當(dāng)方便。
安裝
關(guān)聯(lián)MonkeyDev,打開(kāi)Reveal 頁(yè)面,Help-Show Reveal Library in Finder -iOS Library 拷貝RevealServer.framework,然后前往 /opt/MonkeyDev/Frameworks 替換掉RevealServer.framework。
使用
在真機(jī)上運(yùn)行monkeyDev 工程,程序啟動(dòng)后,打開(kāi)Reveal ,選擇USB方式,點(diǎn)擊app的icon,進(jìn)入U(xiǎn)I分析頁(yè)。
class-dump的安裝和使用
class-dump主要用于提取Mach-O文件中的頭文件信息并生成.h文件,通過(guò)對(duì)生成的.h文件可分析對(duì)應(yīng)App實(shí)現(xiàn)的基本思路和一些重要的類對(duì)應(yīng)的功能,以便進(jìn)一步進(jìn)行逆向工作。
安裝
class-dump下載地址:http://stevenygard.com/projects/class-dump/
下載class-dump的dmg格式:class-dump-3.5.dmg
安裝操作:
1、 打開(kāi)終端輸入:open /usr/local/bin
2、把dmg文件中的class-dump文件復(fù)制到 /usr/local/bin
3、改權(quán)限,終端輸入: sudo chmod 777 /usr/local/bin/class-dump
使用
在終端通過(guò)命令可以導(dǎo)出文本格式頭文件,我們可以導(dǎo)出text文件格式:
class-dump -H iQiYiPhoneVideo -o IQIY
如需幫助則在終端輸入 :class-dump --help
Hopper Disassembler 介紹
Hopper Disassembler Mac版是一個(gè)強(qiáng)大的Mac反編譯神器,可以反匯編,反編譯和調(diào)試應(yīng)用程序。而且支持iOS逆向,可以把Mach-O文件的機(jī)器語(yǔ)言代碼反編譯成匯編代碼、OC或Swift的偽代碼。Hopper Disassembler 支持分解Mach-O、ARM和Windows二進(jìn)制文件,是程序員進(jìn)行拆開(kāi)代碼進(jìn)行調(diào)試或?qū)W習(xí)的神器。
Hopper Disassembler 官方下載地址:https://www.hopperapp.com/
Cycript 安裝和環(huán)境配置
Cycript是Objective-C++、ES6(JavaScript)、Java等語(yǔ)法的混合物,使用Cycript 可以動(dòng)態(tài)調(diào)試App。
安裝
Cycript 官方下載地址:http://www.cycript.org/
Cycript 官方學(xué)習(xí)文檔:http://www.cycript.org/manual/
從Cycript下載SDK,下載完成后解壓文件夾放到/opt目錄下。
配置環(huán)境變量
打開(kāi)終端輸入: open -e .bash_profile
在打開(kāi)的.bash_profile 文件內(nèi)添加Cycript環(huán)境變量地址:export PATH=/opt/cycript_0.9.594/:$PATH
安裝遇到的問(wèn)題
1、Cycript 需要依賴低版本的ruby2.0。
dyld: Library not loaded: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.2.0.0.dylib
Referenced from: /opt/cycript_0.9.594/./Cycript.lib/cycript-apl
Reason: image not found
zsh: abort ./cycript -r 10.19.80.176:6666
解決方法
查找到ruby 安裝所在目錄:拷貝出libruby.2.4.10.dylib ,并將動(dòng)態(tài)庫(kù)改成libruby.2.0.0.dylib,粘貼到/opt/cycript_0.9.594/Cycript.lib/目錄下。
使用
1、打開(kāi)終端進(jìn)入cycript_0.9.594 目錄: cd /opt/cycript_0.9.594 ;
2、在終端輸入電腦與真機(jī)必須同一局域網(wǎng)內(nèi)的IP地址:./cycript -r 10.19.80.176:6666
按enter 鍵出現(xiàn) cy#表示成功連接。
日志內(nèi)也可以查到可運(yùn)行的IP地址:
Download cycript(https://cydia.saurik.com/api/latest/3) then run: ./cycript -r 10.19.80.176:6666
3、control +D退出查看。
在cy#后面輸入:[[UIApp keyWindow]recursiveDescription].toString()
可以查看UI整體布局結(jié)構(gòu)。
查找根視圖
cy# UIApp.keyWindow.rootViewController
#"<RootViewController: 0x141150400>"
獲取對(duì)象的所有成員變量,使用(*對(duì)象)
cy# *UIApp.keyWindow.rootViewController
篩選出某種類型對(duì)象
choose(UIViewController)
choose(UITableViewCell)
使用遇到的問(wèn)題
*** _syscall(connect(socket_, info->ai_addr, info->ai_addrlen)):../Console.cpp(306):CYSocketRemote [errno=61]
MDCycriptManager.h 中的端口值換一下,#define PORT 6666換成端口為6688
代碼注入舉例
@interface MyViewController
@end
%hook MyViewController
\- (void)showLoginPopup{
NSLog(@"hook viewDidLoad method");
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"溫馨提示" message:@"我的第一個(gè)tweak工程創(chuàng)建成功了" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:@"取消",nil];
[alertView show];
UITableView* p = MSHookIvar<UITableView*>(self,"_tableView");
p.backgroundColor=[UIColor purpleColor];
}
\- (void)toLogin{
%orig;
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"溫馨提示" message:@"你過(guò)來(lái)呀??????????????" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:@"取消",nil];
[alertView show];
}
%end
總結(jié)
iOS逆向之路有坑有驚喜,需要了解并使用逆向中的各種工具,要求對(duì)匯編語(yǔ)言了解,熟悉各種腳本語(yǔ)言,對(duì)系統(tǒng)的底層知識(shí)的了解要求更高,越獄環(huán)境下的逆向自由度更高,非越獄環(huán)境下逆向依然充滿挑戰(zhàn)。在逆向別人app時(shí)候,也在提醒我們,開(kāi)發(fā)項(xiàng)目中涉及的核心代碼安全性很重要,避免被泄漏出去。