[轉]很重要的方法論 Android逆向之旅---靜態分析技術來破解Apk

分類:
 
 

1、前言

從這篇文章開始咱們開始咱們的破解之路,以前的幾篇文章中咱們是如何講解怎麼加固咱們的Apk,防止被別人破解,那麼如今咱們要開始破解咱們的Apk,針對於以前的加密方式採用相對應的破解技術,Android中的破解其實大致上能夠分爲靜態分析和動態分析,對於這兩種方式又能夠細分爲Java層(smail和dex)和native層(so)。因此咱們今天主要來說解如何經過靜態分析來破解咱們的apk,這篇文章咱們會經過破解Java層和native層的例子來說解。android

 

2、準備工做

在開始今天的文章以前,咱們須要準備點東西,程序員

第1、首先是基本知識:算法

一、瞭解android中的Apk文件的結構。shell

二、瞭解Smail語法和dex文件格式安全

三、apk的簽名機制微信

關於這三個知識點,這裏就不作詳細介紹了,不理解的同窗能夠自行網上學習,有不少資料講解的。數據結構

第2、再者就是幾個重要的工具微信開發

一、apktool:反編譯的利器

二、dex2jar:將dex轉化成jar

三、jd-gui:很好的查看jar文件的工具

四、IDA:收費的最全破解利器(分析dex和so均可以)

下載地址:http://pan.baidu.com/s/1hqBC7Es

額外:上面四個工具是最基本的,可是如今網上也有一些更好的工具:JEB,GDA等。可是這些工具就是豐富了上面四個工具,因此說咱們只要上面的四個工具就足夠了。IDA工具我專門給了一個下載地址,其餘的工具在咱們提供的案例中。

 

3、技術原理

準備工做完了,下面就來看一下今天的破解方式介紹:

Android中的破解的靜態分析說重要,也不重要,爲何這麼說呢?

由於咱們到後面會介紹動態分析,那時候咱們在破解一個Apk的時候,發現靜態分析的方式幾乎毫無用途,由於如今的程序加固的愈來愈高級,靜態分析幾乎失效,因此動態分析是必須的,可是要是說靜態分析沒有用,那麼也錯了,由於咱們在有些場景下,只有靜態分析可以開始破解之門,沒有靜態分析以後的結果,動態分析是沒法開展的。這個下面會舉例說明。因此說在破解的過程當中,靜態分析和動態分析必定會結合在一塊兒的,只有這樣咱們纔會一往無前。下面就來看看咱們如何經過靜態分析來破解apk.

第1、靜態分析的流程

一、使用apktool來反編譯apk

在這個過程當中,咱們會發現有些apk很輕易的被反編譯了,可是有些apk每次反編譯都會報各類錯誤,這個也是正常的,由於加固了嗎。如今網上有不少對apk加密的方式,直接讓反編譯就通不過,好比Androidmanifest文件,dex文件等,由於apktool他須要解析這些重要的資源,一旦這些文件加密了那麼就會終止,因此這裏咱們暫且都認爲apk都能反編譯的,由於咱們今天是主要介紹怎麼經過靜態分析來破解,關於這裏的反編譯失敗的問題,我後面會在用一篇文章詳細介紹,到時候會列舉一些反編譯錯誤的例子。

 

二、獲得程序的smail源碼和AndroidManifest.xml文件

咱們知道一個Android的程序入口信息都會在AndroidManifest.xml中,好比Application和入口Activity,因此咱們確定會先來分析這個文件,找到咱們想要的信息,固然這裏還有一個經常使用的命令須要記住:

adb shell dumpsys activity top

可以獲取到當前程序的Activity信息

而後咱們會分析smail代碼,進行代碼邏輯的修改

 

三、直接解壓apk文件獲得classes.dex文件,而後用dex2jar工具獲得jar,用jd-gui工具查看

這裏咱們主要很容易的查看代碼,由於咱們在第二步中獲得了smail源碼,就能夠分析程序了,可是咱們知道雖然smail語法不是很複雜,至少比彙編簡單,可是怎麼看着都是不方便的,仍是看java代碼比較方便,因此咱們藉助jd-gui工具查看代碼邏輯,而後在smail代碼中進行修改便可,上面說到的JEB工具,就增強了jd-gui工具的功能,它能夠直接將smail源碼翻譯成java代碼,這樣咱們就不須要先用jd-gui工具查看,再去smail源碼中修改了,藉助JEB便可。

四、若是程序中有涉及到native層的話,咱們能夠用IDA打開指定的so文件。咱們仍是須要先看java代碼,找到指定的so文件,在用IDA來靜態分析so文件。

 

第2、用到的技術

上面介紹了靜態分析的流程,下面來看一下靜態分析的幾個技術,咱們在靜態分析破解Apk的時候,首先須要找到突破點,找到關鍵的類和方法,固然這裏就須要經驗了,不是有方法可循的。可是咱們會藉助一些技術來加快破解。

一、全局查找關鍵字符串和日誌信息

這個技術徹底靠眼,咱們在運行程序以後,會看到程序中出現的字符串,好比文本框,按鈕上的文本,toast顯示的信息等,均可能是重要信息,而後咱們能夠在jd-gui工具中全局搜索這個字符串,這樣就會很快的定位到咱們想要找的邏輯地方:


固然咱們還有一個重要點就是Android中的Log信息,由於在一個大的項目中,會有多人開發,因此每一個模塊每一個人開發,每一個人都會調試信息,因此就會添加一些log信息,可是不是全部的人都會記得在項目發佈的時候關閉項目中的全部log信息,這個也是咱們在項目開發的過程當中很差的習慣。這時候咱們就能夠經過程序運行起來以後,會打印一些log信息,那麼咱們能夠經過這些信息獲取突破點,Android中的log能夠根據一個應用來進行過濾的,或者咱們能夠經過log信息中的字符串在jd-gui中進行全局搜索也是能夠的。

 

二、代碼的注入技術

在第一種方式中咱們經過全局搜索一些關鍵的字符串來找突破點,可是這招有時候很差使,因此這時候咱們須要加一些代碼了來觀察信息了,這裏有一個通用的方法就是加入咱們本身的log代碼,來追蹤代碼的執行邏輯,由於這裏講的是靜態分析技術,因此就用代碼注入技術來跟蹤執行邏輯,後面介紹了動態分析技術以後,那就簡單了,咱們能夠隨意的打斷點來進行調試。這裏的添加代碼,就是修改smail代碼,添加咱們的日誌信息便可,在下面咱們會用例子來進行講解,這個也是咱們最經常使用的一種技術。

 

三、使用系統的Hook技術,注入破解程序進程,獲取關鍵方法的執行邏輯

關於Android中的進程注入和Hook技術,這裏就不作詳細介紹了,不瞭解這些技術的同窗能夠轉戰:

注入技術:http://blog.csdn.net/jiangwei0910410003/article/details/39292117

Hook技術:http://blog.csdn.net/jiangwei0910410003/article/details/41941393

這兩篇文章介紹了這兩項技術,可是咱們在實際操做過程當中不用這兩篇文章中用到的方式,由於這兩篇文章只是介紹原理,技術還不是很成熟,關於這兩個技術,網上有兩個框架很成熟,也很實用,就是人們熟知的:Cydia和Xposed,關於這兩個框架的話,網上的資料太多了,並且用起來也很容易,這裏就不作太多的詳細介紹了。

咱們在實際的破解的過程當中,這種方式用的有點少,由於這種方式效率有點低,因此只有在特定的場景下會使用。

 

四、使用IDA來靜態分析so文件

這裏終於用到了IDA工具了,本人是感受這個工具太強大了,他能夠查看so中的代碼邏輯,咱們看到的的多是彙編指令,因此這裏就有一個問題了,破解so的時候,咱們還必須掌握一項技能,就是能看懂彙編指令,否則用IDA來破解程序,會很費經的,關於彙編指令,大學的時候,咱們接觸過了,可是咱們當時感受這東西又難,並且用的地方也不多,因此就沒太在乎,其實否則呀,真正懂彙編的人才是好的程序員:


看到些彙編指令,頭立馬就大了,不過這個用多了,破解多了,仍是能夠的。咱們能夠看到左邊欄中有咱們的函數,咱們能夠找到指定函數的定義的地方進行查看便可。其實IDA最強大的地方是在於他動態調試so文件,下一篇文章會介紹怎麼動態調試so文件。固然IDA可也是能夠直接查看apk文件的:


能夠查看apk文件中的全部文件,咱們能夠選擇classes.dex文件:


可是這裏咱們可能會遇到一個問題,就是若是應用程序太大的話,這個打開的過程當中會很慢的,有可能IDA中止工做,因此要慢慢等啦:


打開以後,咱們能夠看到咱們的類和方法名,這裏還能夠支持搜索類名和方法名Ctrl+F,也能夠查看字符串內容(Shirt+F12):


咱們發現IDA也是一個分析Java代碼的好手,因此說這個工具太強大了啦啦~~

 

4、案例分析

上面講解了靜態分析的破解技術,那麼下面就開始使用一個例子來看看靜態分析的技術。

第1、靜態分析Java(smail)代碼

首先咱們拿到咱們須要破解的Apk,使用apktool.jar工具來反編譯:

java -jar apktool.jar d xxx.apk


這個apk非常容易就被反編譯了,看來並無進行任何的加固。那就好辦了,咱們這裏來改一下他的AndroidManifest.xml中的信息,改爲可調式模式,這個是咱們後面進行動態調試的前提,一個正式的apk,在AndroidManifest.xml中這個值是false的。

咱們看看他的AndroidManifest.xml文件:


咱們把這個值改爲true.在回編譯,這時候咱們就能夠動態調試這個apk了,因此在這點上咱們能夠看到,靜態分析是動態分析的前提,這個值不修改的話,咱們是辦法進行後續的動態調試的。

修改爲功以後,咱們進行回編譯:

cd C:\Users\jiangwei\Desktop\靜態分析\apktool_2.0.0rc4
del debug.sig.apk
java -jar apktool.jar b -d 123 -o debug.apk
java -jar .\sign\signapk.jar .\sign\testkey.x509.pem .\sign\testkey.pk8 debug.apk debug.sig.apk
del debug.apk
adb uninstall com.shuqi.controller
adb install debug.sig.apk
adb shell am start -n com.shuqi.controller/.Loading
pause

這裏是爲了簡單,寫了一個批處理,首先進入到目錄,而後使用命令進行回編譯:

java -jar apktool.jar b -d sq -o debug.apk

sq是以前反編譯的目錄,debug.apk是回編譯以後的文件

這時候,debug.apk是不能安裝運行的,由於沒有簽名,Android中是不容許安裝一個沒有簽名的apk

下面還要繼續簽名,咱們用系統自帶的簽名文件便可簽名:

java -jar .\sign\signapk.jar .\sign\testkey.x509.pem .\sign\testkey.pk8 debug.apk debug.sig.apk

注:其實咱們在用IDE工具開發android項目的時候,工具就是用這個簽名文件進行簽名的,只是這個過程IDE幫咱們作了。

後面就是直接安裝這個apk,而後運行這個Apk。這個過程當中咱們只須要知道應用的包名和入口Activity名稱便可,這個信息咱們在AndroidManifest.xml中也是能夠獲取到的,固然咱們用:adb shell dumpsys activity top 命令也能夠獲得:


回編譯以後,咱們運行程序,發現有問題,就是點擊程序的icon,沒反應,運行不起來,咱們在查看log中的異常信息,發現也沒有拋出任何異常,那麼這時候,咱們就判斷,他內部確定作了什麼校驗工做,這個通常回編譯以後的程序運行不起來的話,那就是內部作校驗了,通常作校驗的話,有兩種:

一、對dex作校驗,防止修改dex的

二、對apk的簽名作校驗,防止從新打包

那咱們就須要重新看看他的代碼,來看看是否是作了校驗:

咱們在分析代碼的時候,確定先看看他有沒有本身定義Application,若是有定義的話,就須要看他本身的Application類,這裏咱們看到他定了本身的Application:com.shuqi.application.ShuqiApplication

咱們解壓apk,獲得dex,而後dex2jar進行轉化,獲得jar,再用jd-gui查看這個類:


這裏咱們看到他的代碼作混淆了,可是一些系統回調方法確定不能混淆的,好比onCreate方法,可是這裏咱們通常找的方法是:

一、首先看這個類有沒有靜態方法和靜態代碼塊,由於這類的代碼會在對象初始化以前運行,可能在這裏加載so文件,或者是加密校驗等操做

二、再看看這個類的構造方法

三、最後再看生命週期方法

咱們這裏看到他的核心代碼在onCreate中,調用了不少類的方法,猜測這裏的某個方法作工做了?

這時候咱們就來注入咱們的代碼來跟蹤是哪一個方法出現問題了,這裏有的同窗有疑問,其實就這幾個方法,直接一個一個看不就結了,哎,咱們這篇文章就是要介紹靜態分析技術,固然就須要作案例啦。

下面來看看咱們怎麼添加咱們的日誌信息,其實很簡單,就是添加日誌,須要修改smail文件,咱們在去查看smail源碼:


關於smail語法,本人認爲不是很難,因此你們本身網上去搜一些資料學習一下便可,這裏咱們能夠很清晰的看到調用了這些方法,那麼咱們就在每一個方法加上咱們的日誌信息,這裏加日誌有兩種方式,一種就是直接在這裏調用系統的log方法,可是有兩個問題:

一、須要導入包,在smail中修改

二、須要定義一個兩個參數,一個是tag,msg,才能正常的打印log出來

明顯這個方法有點麻煩,這裏咱們就本身定義一個MyLog類,而後反編譯,獲得MyLog的smail文件,添加到這個ShuqiApplication.smail的root目錄下,而後在代碼中直接調用便可,至於爲什麼要放到root目錄下,這樣在代碼中調用就不須要導入包了,好比SuqiApplication.smail中的一些靜態方法調用:


編寫日誌類MyLog,這裏就不粘貼代碼了,咱們新建一個項目以後,反編譯獲得MyLog.smail文件,放到目錄中:


咱們獲得這個文件的時候,必定要注意,把MyLog.smail的包名信息刪除,由於咱們放到root目錄下的,意味着這個MyLog類是沒有任何包名的,這個須要注意,否則最後加的話,也是報錯的。

咱們在ShuqiApplication的onCreate方法中插入咱們的日誌方法:

invoke-static {}, LMyLog;->print()V


可是咱們在加代碼的時候,須要注意的是,要找對地方加,所謂找對地方,就是在上個方法調用完以後添加,好比:

invoke-virtual,invoke-static等,並且這些指令後面不能有:move-result-object,由於這個指令是獲取方法的返回值,因此咱們通常是這麼加代碼的:

一、在invoke-static/invoke-virtual指令他的返回類型是V以後能夠加入

二、在invoke-static/invoke-virtual指令返回類型不是V,以後的move-result-object命令以後能夠加入

 

加好了咱們的日誌代碼以後,下面咱們就回編譯執行,在這個過程可能會遇到samil語法錯誤,這個就對應指定的文件修改就能夠了,咱們獲得回編譯的apk以後,能夠在反編譯一下,看看他的java代碼:


咱們看到了,咱們添加的代碼,在每一個方法以後打印信息。

下面咱們運行程序,同時開啓咱們的log的tag:adb logcat -s JW


看到咱們打印的日誌了,咱們發現打印了三個log,這裏須要注意的是,這裏雖然打印了三個log,可是都是在不一樣的進程中,因此說一個進程中的log的話,只打印了一個,因此咱們判斷,問題出如今VR.h這個方法

咱們查看這個方法源碼:


果真,這個方法作了簽名驗證,不正確的話,直接退出程序。那麼咱們如今要想正常的運行程序的話,很簡單了,直接註釋這行代碼:vr.h(this)

而後回編譯,在運行,果真不報錯了,這裏就不在演示了:


好了,上面就經過注入代碼,來跟蹤問題,這個方法是很經常使用,也是很實在的。

 

第2、靜態分析Native代碼

下面繼續來介紹一下,如何使用IDA來靜態分析native代碼,這裏必定要熟悉彙編指令,否則看起來很費勁的。

咱們在反編譯以後,看到他的onCreate方法中有一個加載so的代碼

看看這個代碼:

獲取密碼的方法,是native的,咱們就來看看那個getDbPassword方法,用IDA打開libpsProcess.so文件:


咱們看看這個函數的實現,咱們通常直接看BL/BLX等信息,跳轉邏輯,還有就是返回值,咱們在函數的最後部分,發現一個重點,就是:BL __android_log_print  這個是在native層調用log的函數,咱們在往上看,發現:tag是System.out.c

咱們運行程序看起log看看,可是咱們此時也能夠在java層添加日誌的:咱們全局搜索這個方法,在yi這個類中調用的


咱們修改yi.smail代碼:


回編譯,在運行程序,開啓log:

adb logcat -s JW

adb logcat -s System.out.c


發現,返回的密碼java層和native層是同樣的。說明咱們靜態分析native仍是有效的。

 

好了,到這裏咱們今天的內容就介紹完了,固然還有不少靜態分析apk的方法,這裏只是介紹了本人用到的技術。

 

案例下載:http://download.csdn.net/detail/jiangwei0910410003/9308217

案例中有個說明文件,運行前請閱讀~~

 

5、未解決的問題

一、如何搞定apktool工具反編譯出錯的問題

這個我在開始的時候也說了,這裏出錯的緣由大部分是apk進行加固了,因此後面我會專門介紹一下如何解決這樣的問題

二、如何搞定讓一個Apk能夠調試

咱們在上面看到一個apk想要能調試的話,須要修改android:debug的值,可是有時候,咱們會遇到修改失敗,致使程序不能運行,後面會專門介紹有幾種方式來讓一個發佈後的apk能夠調試

 

6、技術總結

這篇文章咱們介紹瞭如何使用靜態方式去破解一個apk,咱們在破解一個apk的時候,其實就是改點代碼,而後可以運行起來,達到咱們想要的功能,通常就是:

一、註釋特定功能,好比廣告展現等

二、獲得方法的返回值,好比獲取用戶的密碼

三、添加咱們的代碼,好比加入咱們本身的監測代碼和廣告等

咱們在靜態分析代碼的時候,須要遵循的大致路線:

一、首先可以反編譯,獲得AndroidManifest.xml文件,找到程序入口代碼

二、找到咱們想要的代碼邏輯,通常會結合界面分析,好比咱們想得讓用戶登陸成功,咱們確定想要獲得用戶登陸界面Activity,這時候咱們能夠用adb shell dumpsys activity top命令獲得Activity名稱,而後用Eclipse自帶的程序當前視圖分析工具:獲得控件名稱,或者是在代碼中獲取layout佈局文件,通常是setContentView方法的調用地方,而後用佈局文件結合代碼獲得用戶登陸的邏輯,進行修改

三、在關鍵的地方經過代碼注入技術來跟蹤代碼執行邏輯

四、注意方法的返回值,條件判斷等比較顯眼的代碼

五、對於有些apk中的源碼,可能他有本身的加密算法,這時候咱們須要獲取到這個加密方法,若是加密方法比較複雜的話,咱們就須要大批的測試數據來獲取這個加密方法的邏輯,通常是輸入和輸出做爲一個測試用例,好比阿里安全第一屆比賽的第一題就能夠用靜態分析的方式破解,它內部就是一個加密算法,咱們須要用測試數據來破解。

六、對於那些System.loadLibrary加載so文件的代碼,咱們只須要找到這個so文件,而後用IDA打開進行靜態分析,由於有些apk中把加密算法放到了so中了,這時候咱們也能夠經過測試數據來獲取加密算法。

七、經過上面的例子,咱們能夠總結一個方式,就是如今不少apk會作一些校驗工做,通常在代碼中包含:「signature」字符串信息,因此咱們能夠全局搜索一下,也許能夠獲取一些重要信息。

 

6、總結

這篇文章總算是講解完了,其實早就想用寫破解的文章了,由於破解比加固有意思,至少破解成功了有成就感。這篇文章主要介紹瞭如何經過靜態分析方式破解,介紹了一些工具的時候,破解流程和破解技巧。最經常使用的就是代碼注入技術和全局搜索關鍵字符串等方式,可是咱們能夠看到,如今市面上的不少apk,光經過靜態分析是沒法知足咱們的破解需求了,因此動態分析方式就來了,並且動態方式破解難度會很大,須要掌握的東西也不少,我後面會分幾篇文章來一一介紹動態破解的技巧和常見的問題。可是靜態方式破解也是很重要的。固然也是動態分析的前提,因此咱們既然玩破解,那麼這兩種技術都必須很好的掌握。

 

 

PS: 關注微信,最新Android技術實時推送

 

 

 
11
0
 
 
 

 

 
猜你在找
【直播】機器學習&深度學習系統實戰(唐宇迪)
【直播】Kaggle 神器:XGBoost 從基礎到實戰(冒教授)
【直播回放】深度學習基礎與TensorFlow實踐(王琛)
【直播】計算機視覺原理及實戰(屈教授)
【直播】機器學習之凸優化(馬博士)
【直播】機器學習之矩陣(黃博士)
【直播】機器學習之機率與統計推斷(冒教授)
【直播】機器學習之數學基礎
【直播】TensorFlow實戰進階(智亮)
【直播】深度學習30天系統實訓(唐宇迪)

 

 

查看評論
9樓 老大魚頭 2016-01-09 18:00發表 [回覆]
受教了受教了。博主很是強大,已關注。
我補充一小點,IDA Pro其實還能夠再反編譯彙編代碼,生成C代碼,那樣能看得更加清楚一點。
反編譯單個函數是F5,反編譯整個文件是用File -> Produce File -> Create C File.須要安裝Hex-Rays Decomplier而且有受權。
8樓 XXOOYC 2015-12-25 23:59發表 [回覆]
能不能再順便往下講點如何修改so的文章
7樓 jltxgcy 2015-12-10 09:35發表 [回覆]
已投票,期待更多關於android破解,防破解,安全方面的文章!
Re: 尼古拉斯_趙四 2015-12-10 09:37發表 [回覆]
回覆jltxgcy:謝謝。。後續還有嘔心之做:動態分析技術破解
Re: jltxgcy 2015-12-12 09:19發表 [回覆]
回覆尼古拉斯_趙四:哈哈,加油,每日一票。
6樓 苗景磊 2015-12-03 14:58發表 [回覆]
很不錯,但願樓主多寫一些這類的博客
5樓 boy_nihao 2015-12-01 14:07發表 [回覆]
值得收藏
4樓 鄉下程序員 2015-11-30 23:25發表 [回覆]
屌屌的飛起來~
3樓 傻丫頭與科技 2015-11-30 19:24發表 [回覆]
感謝樓主的分享,學習了!!
2樓 taanniu1 2015-11-30 14:37發表 [回覆]
收藏了
1樓 牛遷遷 2015-11-28 18:56發表 [回覆]
高大上的博客,頂。
 
該文章已被禁止評論!
* 以上用戶言論只表明其我的觀點,不表明CSDN網站的觀點或立場
 
 
TOP
相關文章
相關標籤/搜索