編輯:關於Android編程
要逆向分析並修改一個Android應用,首先是對APK進行解包和打包,這一部分網上資料鋪天蓋地,不再贅述了。值得一提的一點就是,如果apktool無法解包或打包的話,可以嘗試國人在apktool基礎上開發的ShakaApktool,另外也可以使用AndroidKiller這個工具,當然AndroidKiller內部是使用ShakaApktool來進行解包打包。
關於如何解包和打包、反編譯為JAVA代碼、修改smali代碼的資料很多,按部就班做起來也比較簡單。dex2jar、JD-GUI獲得了反編譯的JAVA代碼,但如何分析這些代碼,找到關鍵之處進行修改,才是重中之重,也是難點所在。我最近需要分析的一個APK反編譯後純JAVA代碼的體積居然達到了100多MB,如何從這100多MB的代碼中找到關鍵之處並修改,實在是一個很頭疼的事情。
查閱書籍和網上資料,分析代碼的方法大概有這麼幾種:
1.使用Android SDK中的LogCat工具查看APP運行時的日志。
要在LogCat中看到APP輸出的日志,需要具備以下兩個條件中的任意一個。
①你所用的手機的Android系統的根目錄下的/default.prop文件中的ro.debuggable值為1,如果這個值為1,你可以在DDMS中看到手機上的所有進程,並可以調試它們或查看它們輸出的日志。但一般的手機都不會打開這個調試開關,當然也許你會說直接修改這個/default.prop文件不就行了。不行,因為修改了要重啟才會生效,但是一重啟,/default.prop就會恢復原始狀態,因為/default.prop是保存在boot.img的ramdisk中,它每次重啟都會重新從rom中加載,所以要達到目就必須修改boot.img中的ramdisk並重新刷到手機中。具體步驟可以網上搜一下,由於太麻煩就留給喜歡折騰的人去折騰了。當然也可以把手機刷上小米的MIUI開發版ROM,它的/default.prop文件中的ro.debuggable默認為1,可以方便的調試程序。
②你要分析的這個Android應用的APK中的AndroidManifest.xml中有一句android:debuggable=true。但幾乎所有發布出來的應用都不會把這個調試開關打開。當然你可以用apktool解包,修改AndroidManifest.xml,重新打包。但是有的應用做了特殊處理,無法用apktool解包或打包,或者是做了防打包處理,打包後一運行就閃退或不允許你登錄賬號。對於這種情況,在解決防打包問題之前,可以先不對它重打包。而是使用Android模擬器,大部分PC上的Android模擬器都默認根目錄下的/default.prop文件中的ro.debuggable值為1,可以調試安裝在上面的所有應用。用於開發的最佳模擬器當屬Genymotion,其次是Android SDK自帶的模擬器,但有時候你要分析的應用可能無法在這兩個模擬器上運行,原因你懂的,有些應用的開發者不希望你在模擬器上運行它們的應用,做了簡單處理,這個時候可以嘗試一下BlueStacks之類的模擬器,這些模擬器模擬得更像真實的手機,應用不易察覺。
好了,現在可以在LogCat中看到你想分析的應用輸出的日志了,但問題來了,很多應用都不會直接用android.util.Log輸出它的所有日志。輸到什麼地方,鬼也不知道,也許是某個文件,也許是發到它的服務器。但在反編譯出的代碼中找到日志的輸出代碼並不難。找到以後通過修改它的smali代碼或用Xposed來Hook相關的日志輸出函數,並將日志重定向到android.util.Log,接下來就可以在LogCat中看到它的全部日志了。這樣一來可以看到不少有用的信息。
2.使用TraceView查看調用了哪些方法。
TraceView是Android SDK中的一個性能分析工具,正如其名,它是性能分析工具,不是逆向分析工具,所以用起來是很不如意的。你可以在DDMS中開始性能分析,然後到Android應用中點一下,然後在DDMS中停止性能分析。就可以看到這段時間內所有的方法調用和耗時,但你看到的是鋪天蓋地的系統函數,看不出調用順序也看不出調用堆棧,還得在鋪天蓋地的系統函數中找到應用自身代碼的函數,簡直奔潰。你也可以把android.os.Debug.startMethodTracing()和android.os.Debug.stopMethodTracing()這兩行代碼對應的smali代碼插入到你想分析的某個函數的調用前和調用後,然後再來查看生成的性能分析文件。不過效果仍然令人沮喪。當然你可以用dmtracedump和graphviz來根據性能分析文件生成代碼的調用關系視圖。不然依然收效甚微,裡面充斥著大量的系統函數,十分難看。這方面可以參考《Android安全技術解密與防范》或在網上查找資料。
2.抓包。
很多Android應用(游戲、單機應用除外)都是通過HTTP協議與服務器通信,如果能抓到數據包,無疑對逆向分析很有幫助。不過很多應用與服務器的通信都是HTTPS通信,用wireshark和tcpdump之類的工具無法抓到明文。不過根據網上資料顯示,使用Fiddler可以抓到HTTPS的包,試了一下,果然如此,不過只是少部分,我想要的關鍵性數據沒有抓到。
抓包大法中效果最好的大法當屬Hook大法,使用Xposed並編寫Hook模塊,Hook目標應用使用的HTTP Client庫的API,可以抓到所有明文數據。不過需要先查看該應用的代碼,了解它是用的是什麼HTTP Client庫,用了該庫的哪些API,然後再編寫Hook模塊。需要下些功夫,花不少時間,但效果是很好的。
3.調試。
無源碼調試Android應用的方法和工具有很多。在把網上資料都翻遍,幾乎所有調試方法都試過來之後,總結出兩種相對較好用的調試方法。
①IDA Pro
優點:調試時smali代碼單步走走得很准,一步是一步,不會亂走,斷點命中也很准。
缺點:局部變量、寄存器內容顯示效果太差,總所周知,很多發布出來的應用代碼都做過處理,不會留下局部變量的變量名,調試時除了this,其它變量全部是寄存器v0 v1 v2等,在這種情況下你用IDA Pro調試,除了this,一個變量的值都看不到。效果如上圖,除了this,所有的寄存器都是Bad type。也就是說你用IDA Pro來調試,基本上只能看看執行流程,看不到任何數據,這是什麼鬼!
不過別急,在仔細閱讀IDA pro的官方文檔後發現,寄存器內容並非不能顯示,而是它不知道裡面是什麼類型,需要你手動告訴它!你得打開Watch View窗口,每單步走一步,就要先看看Locals裡有多少個寄存器,它們的序號是什麼,然後到Watch View中添加它們並告訴它這是什麼類型。那你又怎麼知道是什麼類型?你可以在JD-GUI裡看它反編譯的JAVA代碼,然後再告訴IDA Pro。由於寄存器隨時在變,你在調試過程中每走一步就需要看一下JAVA代碼,然後告訴IDA Pro一下寄存器的類型,才能看到變量的值。可想而知,調試起來有多麼辛苦,而且這個調試器還不穩定,隨時都會卡死、奔潰,你需要有足夠的耐心來折騰它。
IDA pro官方文檔:
https://www.hex-rays.com/products/ida/support/idadoc/1669.shtmlhttps://www.hex-rays.com/products/ida/support/tutorials/debugging_dalvik.pdf
②smalidea
簡直是神器!它是去年(2015年)下半年才面世的,如果很早之前就有這款神器,那麼如今其它無源碼Android調試工具應該早就被拋棄了。它是開發smali/baksmali的團隊開發出來的一款IntelliJ IDEA/Android Studio插件,可以讓你在你喜愛的Android Studio或IntelliJ IDEA中直接調試smali代碼!雖然目前它的版本為V0.03,但已經很好用了。最為關鍵的一點是只要你在Watches中添加了寄存器監視,單步調試每走一步,它都會自動識別類型並顯示內容。當我看到這個效果時,立馬神清氣爽,跑出去買了一瓶冰雪碧,摩拳擦掌准備大搞一番的時候,問題來了。
每次調試,必須先手動運行APP,然後在IDEA裡附加到進程調試,如果我想調試APP啟動時的代碼,就不好搞了。不過查閱資料,才知道可以用adb來啟動一個應用並讓它等待調試器。只需在原本用於啟動應用的命令adb shell am start再加上一個參數-D即可。最後使用python寫了一段腳本,先用adb shell am start -D啟動APP,然後用adb shell ps獲得所有進程id,從中檢索出目標APP的進程id,最後用adb forward tcp:8700 jdwp: 進程id映射到8700端口。這樣一來我在IntelliJ IDEA上只需固定設置調試端口為8700端口,每次我要調試APP時只需運行一下腳本,然後就可以在IntelliJ IDEA點擊開始調試了,非常方便和暢快。
不過這都是小問題,最大的問題是使用smalidea進行調試時,單步走走得很不准,感覺大部分時候都對不上行,有時候亂跳,明明只走到函數中間的一半,並沒有什麼跳轉語句,但是點擊下一步時,函數就結束了,實在奔潰。不知道是我調試的代碼做過混淆處理還是怎麼說,總是開心愉快的心情一下子就跌入了谷底。
smalidea下載地址和使用說明:https://github.com/JesusFreke/smali/wiki/smalidea
adb資料:https://developer.android.com/studio/command-line/adb.html
其它調試方法,比如AndBug由於本人覺得更不好用,就沒有深入了解了。最後結合IDA pro單步走位准的優點和smalidea變量顯示准的優點,最終我選擇兩個一起用!先用IDA pro看走位,看代碼執行流程,到了疑似關鍵的地方就用smalidea直接下斷點斷在那裡看變量值。當然你最好准備兩台電腦,一台用IDA pro,一台用smalidea。調試的時候IDA pro這邊先探路,探明了道路,直接到smalidea這邊下斷點,查看道路(變量)細節。
如果你覺得這樣調試還是不爽,請看下一篇文章,在下一篇文章中,我們將使用一個巧妙的辦法,舒舒服服的躺在床上把APP的執行流程盡收眼底。
本節引言: 最近一段時間因為工作上的事以及面試等等,耽誤了博客的更新,這裡道歉下~ 今天下午去追夢網絡面試了一趟,全齊大神給小弟我上了一課,增長了
硬件平台:S3C6410 操作系統:Ubuntu、windows 板子系統:Android 開發工具:jdk,ndk,eclipse 本次測試從linux內核模塊編譯開始
一、繼承listActivity、使用arrayAdapter使用ListView和arrayAdapter布局,是ListView布局中最為簡單的一種,首先我們會建立一
Android與JS之間跨平台異步調用 為什麼突然要搞這個問題呢? 在開發浏覽器的時候遇到這個狗血的問題,花了將近1天的時間才想到這個解決方案,Androi