其實(shí)說(shuō)白了就是AndroidStudio動(dòng)態(tài)調(diào)試Smali,一直在用的方法,挺有效的逆向分析方法。把a(bǔ)pk反編譯成Smali然后倒入AndroidStudio中剩盒,然后通過(guò)jdwp調(diào)試相關(guān)進(jìn)程。
基本技能
- 會(huì)使用AndroidStudio的debug的功能慨蛙,不會(huì)的看這里
- 能夠理解簡(jiǎn)單的Smali語(yǔ)法看這里
- 能夠使用apktool反編譯apk辽聊,并且重新打包,不會(huì)的看這里
工具
- AndroidStudio 最好是最新版本期贫,我用的是2.3 最近好像3.0的正式版出來(lái)了
- smaliidea-x.x.x.zip這個(gè)是AndroidStudio的插件跟匆,從這個(gè)鏈接的列表中下載那個(gè),最新版本的zip文件插件的官網(wǎng)
- apktool 反編譯apk->Smali 并且重新打包修改后的Smali到apk
- jadx 用了查看Smali對(duì)應(yīng)的java代碼,增加可讀性
插件安裝:上面那個(gè)zip包下載完成后通砍,打開(kāi)AndroidStudio選擇
Android Studio -> Preferences -> Plugins -> Install plugin from disk -> 選擇 smalidea.x.x.x.zip 插件 ->重啟 -> 插件就安裝好了玛臂。
動(dòng)態(tài)調(diào)試Smali文件
1. 調(diào)試的前提條件 使app可調(diào)試
開(kāi)發(fā)過(guò)Android的都知道烤蜕,要想調(diào)試一個(gè)apk的前提是這個(gè)apk是可調(diào)式,一般我們發(fā)版的時(shí)候迹冤,會(huì)發(fā)release版讽营。(在一開(kāi)始的時(shí)候,我們開(kāi)發(fā)Android是沒(méi)有g(shù)radle的泡徙,那時(shí)候發(fā)release版不像現(xiàn)在在gradle配置好就行了橱鹏,是直接操作AndroidManifest.xml
文件中 <application>
標(biāo)簽的 屬性 android:debuggable="true"
)因?yàn)樵?strong>一般的手機(jī)上,release版本的應(yīng)用是不可以被調(diào)試的堪藐,相對(duì)來(lái)說(shuō)起到了保護(hù)app的作用莉兰。
上面說(shuō)了是在一般的手機(jī)上,從上面來(lái)看庶橱,可以在AndroidManifest文件中設(shè)置debuggable開(kāi)關(guān)贮勃,那么這個(gè)開(kāi)關(guān)是被誰(shuí)來(lái)驗(yàn)證的呢?答案是系統(tǒng)苏章,Android系統(tǒng)會(huì)通過(guò)debuggable 驗(yàn)證一個(gè)app是不是可以調(diào)試寂嘉。可以不可以關(guān)掉系統(tǒng)的驗(yàn)證枫绅?答案是可以的泉孩。不過(guò)很麻煩,據(jù)說(shuō)有兩種方式可以修改并淋,一種是重新刷入boot.img 修改方法,另一種是通過(guò)xpost修改寓搬。
而我們平常用的最多的就是,修改AndroidManifest.xml 中的android:debuggable="true"
县耽,然后重新打包apk句喷。
逆向工程不是普通的反編譯,一般來(lái)說(shuō)逆向都是帶有目的的兔毙。我們拿最近我用到的WPS 的Android版(WPSOffice_206.apk)來(lái)測(cè)試唾琼,在這里不討論逆向的目的。我們來(lái)處理這個(gè)apk澎剥,使它可以被被debug锡溯。
- 首先 通過(guò)
apktool d WPSOffice_206.apk
來(lái)反編譯 - 然后 在生成的目錄中找到
AndroidManifest.xml
,用AS或者文本編輯器打開(kāi)修改里面的<application>
標(biāo)簽,如果有debuggable屬性哑姚,修改為true祭饭,如果沒(méi)有,給<application>
標(biāo)簽添加android:debuggable="true"
- 最后
apktool b WPSOffice_206
這時(shí)候會(huì)在./WPSOffice_206/dist
目錄下生成重新打包好的apk叙量。(注意這個(gè)地方會(huì)出現(xiàn)重新打包的錯(cuò)誤倡蝙,文章最后給出解決方法)然后要給這個(gè)apk簽名。文章開(kāi)始給出的相應(yīng)的文章宛乃。 - 然后我們把這個(gè)自簽名后的apk安裝到手機(jī)就可以了
2. 導(dǎo)入Smail源碼到AndroidStudio中
打開(kāi)as后悠咱,通過(guò)File-->Open ...
選擇我們剛才反編譯處理的那個(gè)目錄蒸辆,WPSOffice_206,然后等待as建立完索引析既。
注意左側(cè)選擇Project視圖躬贡,如下所示:
然后右鍵工程主目錄:Mark Directory As -> Sources Root
然后設(shè)置sdk,最后和測(cè)試手機(jī)的系統(tǒng)版本一致:項(xiàng)目目錄-->右鍵-->Open ModuleSettings:
3. Android Studio 的配置
接下來(lái)配置:Run/Debug Configurations
里面的配置文件:
打開(kāi)后我們點(diǎn)擊上面的+符合眼坏,然后選擇Remote拂玻,添加一個(gè)遠(yuǎn)程調(diào)試如下圖:
然后配置遠(yuǎn)程調(diào)試的端口和一些其他信息,如下圖:
注意宰译,上面的Name可以隨便寫檐蚜,因?yàn)槊恳粋€(gè)Remote配置都對(duì)應(yīng)手機(jī)app上的一個(gè)進(jìn)程,每一個(gè)手機(jī)app可能有多個(gè)進(jìn)程沿侈,所有名字上我們做下區(qū)分闯第。另一個(gè)需要配置的地方是Port,這個(gè)port也可以隨便寫缀拭,只要當(dāng)前電腦上沒(méi)有是用這個(gè)端口就好咳短,如果要同時(shí)調(diào)試手機(jī)上的某個(gè)app的多個(gè)進(jìn)程,這個(gè)每次配置Remote的時(shí)候蛛淋,port不能一樣咙好。我們這里是用默認(rèn)的5005。
4. 打通AndroidStudio和可調(diào)試apk之間的通道
手機(jī)上已經(jīng)安裝了我們前面重新打包的可調(diào)試的wps的apk褐荷。運(yùn)行它
4.1 查看wps的所有的進(jìn)程信息
然后命令行運(yùn)行adb shell ps | grep cn.wps.moffice_eng
4.2 判斷你要debug的那個(gè)頁(yè)面(Activity)在哪個(gè)進(jìn)程里面
首先打開(kāi)這個(gè)頁(yè)面勾效,然后命令行運(yùn)行:
adb shell dumpsys activity | grep mFocusedActivity
這會(huì)得到當(dāng)前顯示的Activity的名字,然后去AndroidManifest.xml
中去查看這個(gè)Activity的信息叛甫,里面會(huì)有進(jìn)程信息层宫。
4.3 端口映射
adb forward tcp:5005 jdwp:29685
設(shè)置端口轉(zhuǎn)發(fā),這條命令的含義可以認(rèn)為是在本地5005端口與手機(jī)29685進(jìn)程之間建立一條通道其监,當(dāng)開(kāi)始調(diào)試時(shí)卒密,AS連接本地的5005端口,通過(guò)這條通道控制程序的運(yùn)行棠赛。這個(gè)5005是前面(圖3.2)中配置的端口,這個(gè)29685是wps在手機(jī)上運(yùn)行的一個(gè)進(jìn)程的進(jìn)程id膛腐。(圖4.1)中獲取的睛约。
關(guān)于 adb (包括adbd,adb-Client adb-Server )中的端口映射的可以看這篇文章http://www.cnblogs.com/gordon0918/p/5570811.html哲身,端口映射可以省略辩涝,在ddms中選中要調(diào)試的進(jìn)程,ddms會(huì)附加一個(gè)8700端口勘天。
4.4 下斷點(diǎn)
這個(gè)隨便下怔揩,和平常一樣捉邢,只要下到你想要程序暫停的地方就好,我們把斷點(diǎn)下到wps的首頁(yè)商膊,通過(guò)adb shell dumpsys activity | grep mFocusedActivity
這個(gè)命令可知道首頁(yè)叫cn.wps.moffice.main.local.HomeRootActivity
伏伐。
注:這里把斷點(diǎn)下到了首頁(yè)的onResume方法中是為了測(cè)試用,因?yàn)閛nResume方法會(huì)被調(diào)用很多次晕拆,當(dāng)我們按home鍵藐翎,然后在打開(kāi)wps的時(shí)候這個(gè)方法就會(huì)被調(diào)用。不說(shuō)了实幕,如果連onResume的調(diào)用時(shí)機(jī)都不知道還搞什么逆向吝镣。
4.5 啟動(dòng)debug
首先選擇要調(diào)試的配置末贾,然后點(diǎn)擊那個(gè)調(diào)試按鈕掂为。如果左下角出現(xiàn)下圖說(shuō)明啟動(dòng)成功:
試試打開(kāi)個(gè)別的應(yīng)用欲诺,然后再切回wps蛹含,這時(shí)候程序會(huì)停在斷點(diǎn)處祠锣。
5 舉個(gè)例子
舉個(gè)例子:以WPS的創(chuàng)建ppt為例,我們來(lái)把斷點(diǎn)打到創(chuàng)建ppt上糕珊,然后調(diào)試這個(gè)ppt的創(chuàng)建流程留特。
我們打開(kāi)WPS后右核,右下角有個(gè)很大的紅色加號(hào)菱鸥,點(diǎn)擊這個(gè)后會(huì)有創(chuàng)建選項(xiàng)染苛,我們選中創(chuàng)建PPT躯概,然后選擇新建空白文檔姿锭。會(huì)看到如下圖所示
這個(gè)時(shí)候我們運(yùn)行adb shell dumpsys activity | grep mFocusedActivity
會(huì)得到
mFocusedActivity: ActivityRecord{50a4e0a u0 cn.wps.moffice_eng/cn.wps.moffice.presentation.multiactivity.Presentation1 t306}
還是截圖來(lái)看吧:
現(xiàn)在拿到這個(gè)Activity的名字了艾凯,我們?cè)賮?lái)看這個(gè)Activity在哪個(gè)進(jìn)程里面,這就需要通過(guò)AndroidManifest.xml了懂傀。
<activity android:name="cn.wps.moffice.presentation.multiactivity.Presentation1"
android:configChanges="fontScale|keyboard|keyboardHidden|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:hardwareAccelerated="true" android:icon="@drawable/public_icon_activity_ppt"
android:label="@string/activity_label_ppt" android:launchMode="singleTask"
android:process=":presentation1" android:taskAffinity="cn.wps.moffice_eng.presentation1"
android:theme="@style/PptTheme"
android:windowSoftInputMode="adjustNothing|stateHidden" />
看到android:process
的值了沒(méi)跃巡,就是這個(gè)Activity所在的進(jìn)程枣察。然后我們拿大這個(gè)進(jìn)程號(hào)就可以調(diào)試了笛粘。
命令行運(yùn)行adb shell ps | grep cn.wps.moffice_eng
如下圖:
然后配置debug config
設(shè)置端口轉(zhuǎn)發(fā):
adb forward tcp:5006 jdwp:31333
然后運(yùn)行debug:
運(yùn)行成功視圖:
這是后在點(diǎn)擊創(chuàng)建一個(gè)ppt外臂,然后程序就會(huì)在斷點(diǎn)處暫停如下圖:
剩下的調(diào)試面板的使用和普通的Android調(diào)試一樣,前面給出的文章已經(jīng)有啦犀斋。通過(guò)這個(gè)調(diào)試面板可以跟蹤變量贝乎,查看調(diào)用堆棧,類之間的跳轉(zhuǎn)叽粹。等等非常有用览效。
最后一個(gè)bug處理
在修改完 wps的 AndroidManifest.xml 然后執(zhí)行apktool b WPSOffice_206
的時(shí)候。apktool會(huì)拋出下面的錯(cuò)誤:
可以看到打了一大堆亂七八糟的log虫几,其實(shí)都沒(méi)用锤灿,只看第一行就行,說(shuō)在 AndroidManifest.xml 的第61行有個(gè)不能被識(shí)別的資源標(biāo)識(shí)符'resizeableActivity'辆脸,打開(kāi)AndroidManifest.xml 然后全局搜下這個(gè)字符串:
這玩意不知道有啥用但校,把這個(gè)屬性刪了就行,好像是為了簡(jiǎn)單組織重打包的一個(gè)混淆操作啡氢。