其實說白了就是AndroidStudio動態(tài)調試Smali,一直在用的方法,挺有效的逆向分析方法。把apk反編譯成Smali然后倒入AndroidStudio中,然后通過jdwp調試相關進程。
基本技能
工具
- AndroidStudio 最好是最新版本,我用的是2.3 最近好像3.0的正式版出來了
- smaliidea-x.x.x.zip這個是AndroidStudio的插件,從這個鏈接的列表中下載那個,最新版本的zip文件插件的官網
- apktool 反編譯apk->Smali 并且重新打包修改后的Smali到apk
- jadx 用了查看Smali對應的java代碼,增加可讀性
插件安裝:上面那個zip包下載完成后,打開AndroidStudio選擇
Android Studio -> Preferences -> Plugins -> Install plugin from disk -> 選擇 smalidea.x.x.x.zip 插件 ->重啟 -> 插件就安裝好了。
動態(tài)調試Smali文件
1. 調試的前提條件 使app可調試
開發(fā)過Android的都知道,要想調試一個apk的前提是這個apk是可調式,一般我們發(fā)版的時候,會發(fā)release版。(在一開始的時候,我們開發(fā)Android是沒有gradle的,那時候發(fā)release版不像現(xiàn)在在gradle配置好就行了,是直接操作AndroidManifest.xml文件中 <application>標簽的 屬性 android:debuggable="true")因為在一般的手機上,release版本的應用是不可以被調試的,相對來說起到了保護app的作用。
上面說了是在一般的手機上,從上面來看,可以在AndroidManifest文件中設置debuggable開關,那么這個開關是被誰來驗證的呢?答案是系統(tǒng),Android系統(tǒng)會通過debuggable 驗證一個app是不是可以調試??梢圆豢梢躁P掉系統(tǒng)的驗證?答案是可以的。不過很麻煩,據(jù)說有兩種方式可以修改,一種是重新刷入boot.img 修改方法,另一種是通過xpost修改。
而我們平常用的最多的就是,修改AndroidManifest.xml 中的android:debuggable="true",然后重新打包apk。
逆向工程不是普通的反編譯,一般來說逆向都是帶有目的的。我們拿最近我用到的WPS 的Android版(WPSOffice_206.apk)來測試,在這里不討論逆向的目的。我們來處理這個apk,使它可以被被debug。
- 首先 通過
apktool d WPSOffice_206.apk來反編譯 - 然后 在生成的目錄中找到
AndroidManifest.xml,用AS或者文本編輯器打開修改里面的<application>標簽,如果有debuggable屬性,修改為true,如果沒有,給<application>標簽添加android:debuggable="true" - 最后
apktool b WPSOffice_206這時候會在./WPSOffice_206/dist目錄下生成重新打包好的apk。(注意這個地方會出現(xiàn)重新打包的錯誤,文章最后給出解決方法)然后要給這個apk簽名。文章開始給出的相應的文章。 - 然后我們把這個自簽名后的apk安裝到手機就可以了
2. 導入Smail源碼到AndroidStudio中
打開as后,通過File-->Open ...選擇我們剛才反編譯處理的那個目錄,WPSOffice_206,然后等待as建立完索引。
注意左側選擇Project視圖,如下所示:

然后右鍵工程主目錄:Mark Directory As -> Sources Root

然后設置sdk,最后和測試手機的系統(tǒng)版本一致:項目目錄-->右鍵-->Open ModuleSettings:

3. Android Studio 的配置
接下來配置:Run/Debug Configurations里面的配置文件:

打開后我們點擊上面的+符合,然后選擇Remote,添加一個遠程調試如下圖:

然后配置遠程調試的端口和一些其他信息,如下圖:

注意,上面的Name可以隨便寫,因為每一個Remote配置都對應手機app上的一個進程,每一個手機app可能有多個進程,所有名字上我們做下區(qū)分。另一個需要配置的地方是Port,這個port也可以隨便寫,只要當前電腦上沒有是用這個端口就好,如果要同時調試手機上的某個app的多個進程,這個每次配置Remote的時候,port不能一樣。我們這里是用默認的5005。
4. 打通AndroidStudio和可調試apk之間的通道
手機上已經安裝了我們前面重新打包的可調試的wps的apk。運行它
4.1 查看wps的所有的進程信息
然后命令行運行adb shell ps | grep cn.wps.moffice_eng

4.2 判斷你要debug的那個頁面(Activity)在哪個進程里面
首先打開這個頁面,然后命令行運行:
adb shell dumpsys activity | grep mFocusedActivity
這會得到當前顯示的Activity的名字,然后去AndroidManifest.xml中去查看這個Activity的信息,里面會有進程信息。
4.3 端口映射
adb forward tcp:5005 jdwp:29685
設置端口轉發(fā),這條命令的含義可以認為是在本地5005端口與手機29685進程之間建立一條通道,當開始調試時,AS連接本地的5005端口,通過這條通道控制程序的運行。這個5005是前面(圖3.2)中配置的端口,這個29685是wps在手機上運行的一個進程的進程id。(圖4.1)中獲取的。
關于 adb (包括adbd,adb-Client adb-Server )中的端口映射的可以看這篇文章http://www.cnblogs.com/gordon0918/p/5570811.html,端口映射可以省略,在ddms中選中要調試的進程,ddms會附加一個8700端口。
4.4 下斷點
這個隨便下,和平常一樣,只要下到你想要程序暫停的地方就好,我們把斷點下到wps的首頁,通過adb shell dumpsys activity | grep mFocusedActivity這個命令可知道首頁叫cn.wps.moffice.main.local.HomeRootActivity。

注:這里把斷點下到了首頁的onResume方法中是為了測試用,因為onResume方法會被調用很多次,當我們按home鍵,然后在打開wps的時候這個方法就會被調用。不說了,如果連onResume的調用時機都不知道還搞什么逆向。
4.5 啟動debug

首先選擇要調試的配置,然后點擊那個調試按鈕。如果左下角出現(xiàn)下圖說明啟動成功:

試試打開個別的應用,然后再切回wps,這時候程序會停在斷點處。
5 舉個例子
舉個例子:以WPS的創(chuàng)建ppt為例,我們來把斷點打到創(chuàng)建ppt上,然后調試這個ppt的創(chuàng)建流程。
我們打開WPS后,右下角有個很大的紅色加號,點擊這個后會有創(chuàng)建選項,我們選中創(chuàng)建PPT,然后選擇新建空白文檔。會看到如下圖所示

這個時候我們運行adb shell dumpsys activity | grep mFocusedActivity
會得到
mFocusedActivity: ActivityRecord{50a4e0a u0 cn.wps.moffice_eng/cn.wps.moffice.presentation.multiactivity.Presentation1 t306}
還是截圖來看吧:

現(xiàn)在拿到這個Activity的名字了,我們再來看這個Activity在哪個進程里面,這就需要通過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的值了沒,就是這個Activity所在的進程。然后我們拿大這個進程號就可以調試了。
命令行運行adb shell ps | grep cn.wps.moffice_eng如下圖:

然后配置debug config

設置端口轉發(fā):
adb forward tcp:5006 jdwp:31333
然后運行debug:

運行成功視圖:

這是后在點擊創(chuàng)建一個ppt,然后程序就會在斷點處暫停如下圖:

剩下的調試面板的使用和普通的Android調試一樣,前面給出的文章已經有啦。通過這個調試面板可以跟蹤變量,查看調用堆棧,類之間的跳轉。等等非常有用。
最后一個bug處理
在修改完 wps的 AndroidManifest.xml 然后執(zhí)行apktool b WPSOffice_206的時候。apktool會拋出下面的錯誤:

可以看到打了一大堆亂七八糟的log,其實都沒用,只看第一行就行,說在 AndroidManifest.xml 的第61行有個不能被識別的資源標識符'resizeableActivity',打開AndroidManifest.xml 然后全局搜下這個字符串:

這玩意不知道有啥用,把這個屬性刪了就行,好像是為了簡單組織重打包的一個混淆操作。