之前我有問過同事(RocketChild)火箭鬧鐘的長后臺,點擊home鍵后,app一直長活,她提示他們是反編譯了”怪物鬧鐘"得到的啟發(fā),然而在沒有去反編譯怪物鬧鐘的時候我猜測是播放靜音文件,抓包看過沒有voip的長連接。接下來我反編譯過后得出的結(jié)論印證了我的猜測。
App常見的后臺長活處理
- Voip voip實現(xiàn)長連接
XMPPFramework 有個屬性就是開啟后臺長活的 - 后臺下載(Server push notification iOS7+)
- 定位服務(wù)(顯著位置更新)
- 播放靜音文件 (相比之前實現(xiàn)成本較低,通過合理設(shè)置audio的聲音通道不會污染其他聲音源)
播放靜音文件 實現(xiàn)iOS應(yīng)用在進(jìn)入到后臺之后,依舊可以執(zhí)行任務(wù),并不受時間的限制
思路:
- 使用UIApplication對象的beginBackgroundTaskWithExpirationHandler申請后臺執(zhí)行任務(wù),該任務(wù)只有大概3分鐘的運行時間
- 應(yīng)用申請到后臺執(zhí)行任務(wù)后,使用NSTimer開啟一個定時任務(wù),主要負(fù)責(zé)監(jiān)控應(yīng)用剩余的后臺可執(zhí)行時間,當(dāng)可用的時間少于一個值時,播放一段默聲音樂,然后調(diào)用UIApplication對象的endBackgroundTask方法將之前申請的后臺執(zhí)行任務(wù)結(jié)束掉,最后再重新申請一個后臺執(zhí)行任務(wù),這樣就可以實現(xiàn)后臺不限時執(zhí)行任務(wù)了
- 應(yīng)用在后臺播放音樂,需要開啟Background Modes,然后勾選Audio and AirPlay即可
注:應(yīng)用在后臺運行的過程中重新申請后臺執(zhí)行任務(wù)是無效的,通過在網(wǎng)上查找資料,播放音樂可以讓應(yīng)用進(jìn)入到一個假前臺的狀態(tài),此時重新申請后臺執(zhí)行任務(wù)是有效的,如此循環(huán)n次,就可以獲得大約3n的后臺執(zhí)行時間,從而達(dá)到后臺無限時執(zhí)行任務(wù)
Show me the code(oc)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error];
[NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(tik) userInfo:nil repeats:YES];
// Override point for customization after application launch.
return YES;
}
在tik方法中判斷下后臺保留的時間是多少秒,這里為了穩(wěn)妥,設(shè)置為61s。
- (void)tik{
if ([[UIApplication sharedApplication] backgroundTimeRemaining] < 61.0)
{
[self longTimeTask];
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
}
}
如何避免上架過程中被reject掉,鬧鐘類App中有播放聲音文件的需求,可以在App的plist主動聲明。
那么如果我們一開始沒有猜中開頭和結(jié)尾常規(guī)的方法就是沿用套路。
套路
-
UI層分析
在日常開發(fā)中我們可以用Xcode自帶的工具進(jìn)行視圖層次的摸索,這里省略。那么如何去分析別人家的app,我們需要借助的工具Reveal。
Reveal如何在越獄設(shè)備上調(diào)試
-
網(wǎng)絡(luò)層分析
青花瓷大法:Charles用來抓網(wǎng)絡(luò)傳輸數(shù)據(jù)包,如絲般順滑?;A(chǔ)功能這里也不用介紹了,值得注意的地方這里列舉兩個
1.如果要抓取https的包,我們需要配置SSL設(shè)置

2.上面那步驟完成后,有小伙伴說在真機(jī)上面還是不能抓取https的數(shù)據(jù),要么你的Charles版本有點老,在iOS9中是有開啟ATS功能的,普通的App為了向下兼容都是默認(rèn)關(guān)閉了,在舊版本的Charles中對開啟ATS功能的app確實無法抓包,在目前的版本中已經(jīng)突破了這個限制。
Charles抓包的原理
本質(zhì)還是"中間人"攻擊。需要抓取https的包你的設(shè)備上還需要信任由Charles下發(fā)的證書。

逆向套路
讓目標(biāo)程序破繭而出 -- dumpdecrypted
1.運行時分析 -- cycript
2.追蹤神器 -- logify
3.反匯編工具 -- hopper
4.斷點調(diào)試工具 -- lldb+debugserver
5.注入工具 -- insert_dylib + install_name_tool
-
砸殼
apple市場里面的應(yīng)用默認(rèn)就加了一道屏障,需要自備砸殼大法。
砸殼參考
*這樣豈不是太繁瑣了,有沒有舒爽的姿勢,有的! *
我會告訴你用pp助手下載越獄市場里面的app都是砸過殼的嗎?
-
砸殼后我們能干點什么(class-dump & 找線索)
class-dump 使用相信大家都比較熟悉,這里也略過。拿到.h文件后我們可以看下類中的方法以及成員變量;拿到的.h 文件為后面配置 theos的一個插件logify來自動生成Tweak.xm
keyword:mute.mp3 silent.wav 等
分析app的plist文件也可以獲得它有哪些聲明的文件
-
Cycript 運行時分析(這里參考微信讀書團(tuán)隊分享中的例子作為案列)
砸完殼之后,我們再 dump出頭文件,但是微信的類太多了,頭文件有幾百個,如此多的頭文件,讓人眼花繚亂,所以要找到突破口,我們得縮小范圍,我喜歡用的思路是從 ui入手,先找到微信對話界面的 controller,然后再追蹤 controller中對應(yīng)的消息處理函數(shù)。
這樣第二個工具 cycript 隆重出場了 ,它也是個手機(jī)端 的工具,用于查看 app運行時數(shù)據(jù),大伙兒可以通過 cydia安裝,安裝完之后,ssh到越獄手機(jī)的終端。
先找到微信的進(jìn)程id:ps aux | grep WeChat再執(zhí)行:cycript -p 微信的pid
1 找到當(dāng)前的進(jìn)程id
ps aux | grep Appname
2 cycript -p Target app pid
UIApp.keyWindow.recursiveDescription().toString()
打印的是當(dāng)前的ui樹,隨便找一個節(jié)點(樹的中間,為什么要在中間,大家可以思考下 ),copy它的內(nèi)存地址,例如 0x14da3f000
[#內(nèi)存地址 nextResponder]
直到找到一個ViewController,然后再去.h里面 找到對應(yīng)的類頭文件。
-
Hopper
然而真的要看到.h里面的方法實現(xiàn),我們還是得借助IDA類似的工具來進(jìn)行分析,簡單些的就使用Hopper進(jìn)行iOS包中的二進(jìn)制文件分析,在工具里面點擊if(b)f(x)可以查看,某個方法的偽代碼實現(xiàn),這里雖然是偽代碼,但是其實可以看見許多關(guān)鍵信息了,結(jié)合我們自己的經(jīng)驗基本可以得出想要模仿的 app的關(guān)鍵信息點了(如果對方寫法不按照規(guī)范來,不按照常理出牌,我們也沒法?。┤缫曨l播放某個app什么格式都能播放,我們主要分析其解碼用了什么框架,是否用了三方的東西,或者用了哪個三方的庫,基本可以構(gòu)面了,然后再模仿下就好了。
基于播放靜音文件的線索我在Hopper里面搜索下關(guān)鍵字,省去了我去用lldb+debugserver的步驟。其實這里只是一個拋磚引玉的過程,我覺得我們在做功能的同時如果能從反方向的角度來思考下問題。
寫在最后關(guān)于用Theos編寫、改寫tweak的時候要注意的地方有:
1,Tweak的control 里面的name 必須要和plist名字對應(yīng)
2,Tweak.plist的
3,Tweak.wx 加入了%new新方法你需要在你導(dǎo)入的類.h文件中添加你新加方法的聲明
4,Makefile的書寫,疑惑的地方是我自己創(chuàng)建了個theos的替身,執(zhí)行的時候報錯,我下載了個微信紅包的Tweak.xm替換自己的theos替身就好了,應(yīng)該是文件夾權(quán)限的問題。
THEOS_DEVICE_IP = 172.16.0.115
THEOS_DEVICE_PORT = 22
ARCHS = armv7 arm64
TARGET = iphone:latest:9.0
include theos/makefiles/common.mk
TWEAK_NAME = GodTest
GodTest_FILES = Tweak.xm
GodTest_FRAMEWORKS = UIKit Foundation
include $(THEOS_MAKE_PATH)/tweak.mk
after-install::
install.exec "killall -9 GodTest"
測試的Tweak工程和Xcode工程打包