天天看點

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

本文轉載自:http://blog.csdn.net/jiangwei0910410003/article/details/50083649

一、前言

從這篇文章開始我們開始我們的破解之路,之前的幾篇文章中我們是如何講解怎麼加強我們的Apk,防止被别人破解,那麼現在我們要開始破解我們的Apk,針對于之前的加密方式采用相對應的破解技術,Android中的破解其實大體上可以分為靜态分析和動态分析,對于這兩種方式又可以細分為Java層(smail和dex)和native層(so)。是以我們今天主要來講解如何通過靜态分析來破解我們的apk,這篇文章我們會通過破解Java層和native層的例子來講解。

二、準備工作

在開始今天的文章之前,我們需要準備點東西,

第一、首先是基本知識:

1、了解Android中的Apk檔案的結構。

2、了解Smail文法和dex檔案格式

3、apk的簽名機制

關于這三個知識點,這裡就不做詳細介紹了,不了解的同學可以自行網上學習,有很多資料講解的。

第二、再者就是幾個重要的工具

1、apktool:反編譯的利器

2、dex2jar:将dex轉化成jar

3、jd-gui:很好的檢視jar檔案的工具

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

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

額外:上面四個工具是最基本的,但是現在網上也有一些更好的工具:JEB,GDA等。但是這些工具就是豐富了上面四個工具,是以說我們隻要上面的四個工具就足夠了。IDA工具我專門給了一個下載下傳位址,其他的工具在我們提供的案例中。

三、技術原理

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

Android中的破解的靜态分析說重要,也不重要,為什麼這麼說呢?

因為我們到後面會介紹動态分析,那時候我們在破解一個Apk的時候,發現靜态分析的方式幾乎毫無用途,因為現在的程式加強的越來越進階,靜态分析幾乎失效,是以動态分析是必須的,但是要是說靜态分析沒有用,那麼也錯了,因為我們在有些場景下,隻有靜态分析能夠開始破解之門,沒有靜态分析之後的結果,動态分析是無法開展的。這個下面會舉例說明。是以說在破解的過程中,靜态分析和動态分析一定會結合在一起的,隻有這樣我們才會勇往直前。下面就來看看我們如何通過靜态分析來破解apk.

第一、靜态分析的流程

1、使用apktool來反編譯apk

在這個過程中,我們會發現有些apk很輕易的被反編譯了,但是有些apk每次反編譯都會報各種錯誤,這個也是正常的,因為加強了嗎。現在網上有很多對apk加密的方式,直接讓反編譯就通不過,比如Androidmanifest檔案,dex檔案等,因為apktool他需要解析這些重要的資源,一旦這些檔案加密了那麼就會終止,是以這裡我們暫且都認為apk都能反編譯的,因為我們今天是主要介紹怎麼通過靜态分析來破解,關于這裡的反編譯失敗的問題,我後面會在用一篇文章詳細介紹,到時候會列舉一些反編譯錯誤的例子。

2、得到程式的smail源碼和AndroidManifest.xml檔案

我們知道一個Android的程式入口資訊都會在AndroidManifest.xml中,比如Application和入口Activity,是以我們肯定會先來分析這個檔案,找到我們想要的資訊,當然這裡還有一個常用的指令需要記住:

adb shell dumpsys activity top

能夠擷取到目前程式的Activity資訊

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

3、直接解壓apk檔案得到classes.dex檔案,然後用dex2jar工具得到jar,用jd-gui工具檢視

這裡我們主要很容易的檢視代碼,因為我們在第二步中得到了smail源碼,就可以分析程式了,但是我們知道雖然smail文法不是很複雜,至少比彙編簡單,但是怎麼看着都是不友善的,還是看java代碼比較友善,是以我們借助jd-gui工具檢視代碼邏輯,然後在smail代碼中進行修改即可,上面說到的JEB工具,就加強了jd-gui工具的功能,它可以直接将smail源碼翻譯成java代碼,這樣我們就不需要先用jd-gui工具檢視,再去smail源碼中修改了,借助JEB即可。

4、如果程式中有涉及到native層的話,我們可以用IDA打開指定的so檔案。我們還是需要先看java代碼,找到指定的so檔案,在用IDA來靜态分析so檔案。

第二、用到的技術

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

1、全局查找關鍵字元串和日志資訊

這個技術完全靠眼,我們在運作程式之後,會看到程式中出現的字元串,比如文本框,按鈕上的文本,toast顯示的資訊等,都可能是重要資訊,然後我們可以在jd-gui工具中全局搜尋這個字元串,這樣就會很快的定位到我們想要找的邏輯地方:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

當然我們還有一個重要點就是Android中的Log資訊,因為在一個大的項目中,會有多人開發,是以每個子產品每個人開發,每個人都會調試資訊,是以就會添加一些log資訊,但是不是所有的人都會記得在項目釋出的時候關閉項目中的所有log資訊,這個也是我們在項目開發的過程中不好的習慣。這時候我們就可以通過程式運作起來之後,會列印一些log資訊,那麼我們可以通過這些資訊擷取突破點,Android中的log可以根據一個應用來進行過濾的,或者我們可以通過log資訊中的字元串在jd-gui中進行全局搜尋也是可以的。

2、代碼的注入技術

在第一種方式中我們通過全局搜尋一些關鍵的字元串來找突破點,但是這招有時候不好使,是以這時候我們需要加一些代碼了來觀察資訊了,這裡有一個通用的方法就是加入我們自己的log代碼,來追蹤代碼的執行邏輯,因為這裡講的是靜态分析技術,是以就用代碼注入技術來跟蹤執行邏輯,後面介紹了動态分析技術之後,那就簡單了,我們可以随意的打斷點來進行調試。這裡的添加代碼,就是修改smail代碼,添加我們的日志資訊即可,在下面我們會用例子來進行講解,這個也是我們最常用的一種技術。

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

關于Android中的程序注入和Hook技術,這裡就不做詳細介紹了,不了解這些技術的同學可以轉戰:

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

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

這兩篇文章介紹了這兩項技術,但是我們在實際操作過程中不用這兩篇文章中用到的方式,因為這兩篇文章隻是介紹原理,技術還不是很成熟,關于這兩個技術,網上有兩個架構很成熟,也很實用,就是人們熟知的:Cydia和Xposed,關于這兩個架構的話,網上的資料太多了,而且用起來也很容易,這裡就不做太多的詳細介紹了。

我們在實際的破解的過程中,這種方式用的有點少,因為這種方式效率有點低,是以隻有在特定的場景下會使用。

4、使用IDA來靜态分析so檔案

這裡終于用到了IDA工具了,本人是感覺這個工具太強大了,他可以檢視so中的代碼邏輯,我們看到的的可能是彙編指令,是以這裡就有一個問題了,破解so的時候,我們還必須掌握一項技能,就是能看懂彙編指令,不然用IDA來破解程式,會很費經的,關于彙編指令,大學的時候,我們接觸過了,但是我們當時感覺這東西又難,而且用的地方也很少,是以就沒太在意,其實不然呀,真正懂彙編的人才是好的程式員:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

看到些彙編指令,頭立馬就大了,不過這個用多了,破解多了,還是可以的。我們可以看到左邊欄中有我們的函數,我們可以找到指定函數的定義的地方進行檢視即可。其實IDA最強大的地方是在于他動态調試so檔案,下一篇文章會介紹怎麼動态調試so檔案。當然IDA可也是可以直接檢視apk檔案的:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

可以檢視apk檔案中的所有檔案,我們可以選擇classes.dex檔案:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

但是這裡我們可能會遇到一個問題,就是如果應用程式太大的話,這個打開的過程中會很慢的,有可能IDA停止工作,是以要慢慢等啦:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

打開之後,我們可以看到我們的類和方法名,這裡還可以支援搜尋類名和方法名Ctrl+F,也可以檢視字元串内容(Shirt+F12):

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

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

四、案例分析

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

第一、靜态分析Java(smail)代碼

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

java -jar apktool.jar d xxx.apk

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

這個apk很是容易就被反編譯了,看來并沒有進行任何的加強。那就好辦了,我們這裡來改一下他的AndroidManifest.xml中的資訊,改成可調式模式,這個是我們後面進行動态調試的前提,一個正式的apk,在AndroidManifest.xml中這個值是false的。

我們看看他的AndroidManifest.xml檔案:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

我們把這個值改成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 指令也可以得到:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

回編譯之後,我們運作程式,發現有問題,就是點選程式的icon,沒反應,運作不起來,我們在檢視log中的異常資訊,發現也沒有抛出任何異常,那麼這時候,我們就判斷,他内部肯定做了什麼校驗工作,這個一般回編譯之後的程式運作不起來的話,那就是内部做校驗了,一般做校驗的話,有兩種:

1、對dex做校驗,防止修改dex的

2、對apk的簽名做校驗,防止重新打包

那我們就需要從新看看他的代碼,來看看是不是做了校驗:

我們在分析代碼的時候,肯定先看看他有沒有自己定義Application,如果有定義的話,就需要看他自己的Application類,這裡我們看到他定了自己的Application:com.shuqi.application.ShuqiApplication

我們解壓apk,得到dex,然後dex2jar進行轉化,得到jar,再用jd-gui檢視這個類:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

這裡我們看到他的代碼做混淆了,但是一些系統回調方法肯定不能混淆的,比如onCreate方法,但是這裡我們一般找的方法是:

1、首先看這個類有沒有靜态方法和靜态代碼塊,因為這類的代碼會在對象初始化之前運作,可能在這裡加載so檔案,或者是加密校驗等操作

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

3、最後再看生命周期方法

我們這裡看到他的核心代碼在onCreate中,調用了很多類的方法,猜想這裡的某個方法做工作了?

這時候我們就來注入我們的代碼來跟蹤是哪個方法出現問題了,這裡有的同學有疑問,其實就這幾個方法,直接一個一個看不就結了,哎,我們這篇文章就是要介紹靜态分析技術,當然就需要做案例啦。

下面來看看我們怎麼添加我們的日志資訊,其實很簡單,就是添加日志,需要修改smail檔案,我們在去檢視smail源碼:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

關于smail文法,本人認為不是很難,是以大家自己網上去搜一些資料學習一下即可,這裡我們可以很清晰的看到調用了這些方法,那麼我們就在每個方法加上我們的日志資訊,這裡加日志有兩種方式,一種就是直接在這裡調用系統的log方法,但是有兩個問題:

1、需要導入包,在smail中修改

2、需要定義一個兩個參數,一個是tag,msg,才能正常的列印log出來

明顯這個方法有點麻煩,這裡我們就自己定義一個MyLog類,然後反編譯,得到MyLog的smail檔案,添加到這個ShuqiApplication.smail的root目錄下,然後在代碼中直接調用即可,至于為何要放到root目錄下,這樣在代碼中調用就不需要導入包了,比如SuqiApplication.smail中的一些靜态方法調用:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

編寫日志類MyLog,這裡就不粘貼代碼了,我們建立一個項目之後,反編譯得到MyLog.smail檔案,放到目錄中:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

我們得到這個檔案的時候,一定要注意,把MyLog.smail的包名資訊删除,因為我們放到root目錄下的,意味着這個MyLog類是沒有任何包名的,這個需要注意,不然最後加的話,也是報錯的。

我們在ShuqiApplication的onCreate方法中插入我們的日志方法:

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

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

但是我們在加代碼的時候,需要注意的是,要找對地方加,所謂找對地方,就是在上個方法調用完之後添加,比如:

invoke-virtual,invoke-static等,而且這些指令後面不能有:move-result-object,因為這個指令是擷取方法的傳回值,是以我們一般是這麼加代碼的:

1、在invoke-static/invoke-virtual指令他的傳回類型是V之後可以加入

2、在invoke-static/invoke-virtual指令傳回類型不是V,之後的move-result-object指令之後可以加入

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

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

我們看到了,我們添加的代碼,在每個方法之後列印資訊。

下面我們運作程式,同時開啟我們的log的tag:adb logcat -s JW

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

看到我們列印的日志了,我們發現列印了三個log,這裡需要注意的是,這裡雖然列印了三個log,但是都是在不同的程序中,是以說一個程序中的log的話,隻列印了一個,是以我們判斷,問題出現在vr.h這個方法

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

我們檢視這個方法源碼:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

果然,這個方法做了簽名驗證,不正确的話,直接退出程式。那麼我們現在要想正常的運作程式的話,很簡單了,直接注釋這行代碼:vr.h(this)

然後回編譯,在運作,果然不報錯了,這裡就不在示範了:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

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

第二、靜态分析Native代碼

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

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

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

看看這個代碼:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

擷取密碼的方法,是native的,我們就來看看那個getDbPassword方法,用IDA打開libpsProcess.so檔案:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

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

我們運作程式看起log看看,但是我們此時也可以在java層添加日志的:我們全局搜尋這個方法,在yi這個類中調用的

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

我們修改yi.smail代碼:

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

回編譯,在運作程式,開啟log:

adb logcat -s JW

adb logcat -s System.out.c

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

發現,傳回的密碼java層和native層是一樣的。說明我們靜态分析native還是有效的。

好了,到這裡我們今天的内容就介紹完了,當然還有很多靜态分析apk的方法,這裡隻是介紹了本人用到的技術。

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

案例中有個說明檔案,運作前請閱讀~~

五、未解決的問題

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

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

2、如何搞定讓一個Apk可以調試

我們在上面看到一個apk想要能調試的話,需要修改android:debug的值,但是有時候,我們會遇到修改失敗,導緻程式不能運作,後面會專門介紹有幾種方式來讓一個釋出後的apk可以調試

六、技術總結

這篇文章我們介紹了如何使用靜态方式去破解一個apk,我們在破解一個apk的時候,其實就是改點代碼,然後能夠運作起來,達到我們想要的功能,一般就是:

1、注釋特定功能,比如廣告展示等

2、得到方法的傳回值,比如擷取使用者的密碼

3、添加我們的代碼,比如加入我們自己的監測代碼和廣告等

我們在靜态分析代碼的時候,需要遵循的大體路線:

1、首先能夠反編譯,得到AndroidManifest.xml檔案,找到程式入口代碼

2、找到我們想要的代碼邏輯,一般會結合界面分析,比如我們想得讓使用者登入成功,我們肯定想要得到使用者登入界面Activity,這時候我們可以用adb shell dumpsys activity top指令得到Activity名稱,然後用Eclipse自帶的程式目前視圖分析工具:得到控件名稱,或者是在代碼中擷取layout布局檔案,一般是setContentView方法的調用地方,然後用布局檔案結合代碼得到使用者登入的邏輯,進行修改

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

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

5、對于有些apk中的源碼,可能他有自己的加密算法,這時候我們需要擷取到這個加密方法,如果加密方法比較複雜的話,我們就需要大批的測試資料來擷取這個加密方法的邏輯,一般是輸入和輸出作為一個測試用例,比如阿裡安全第一屆比賽的第一題就可以用靜态分析的方式破解,它内部就是一個加密算法,我們需要用測試資料來破解。

6、對于那些System.loadLibrary加載so檔案的代碼,我們隻需要找到這個so檔案,然後用IDA打開進行靜态分析,因為有些apk中把加密算法放到了so中了,這時候我們也可以通過測試資料來擷取加密算法。

7、通過上面的例子,我們可以總結一個方式,就是現在很多apk會做一些校驗工作,一般在代碼中包含:“signature”字元串資訊,是以我們可以全局搜尋一下,也許可以擷取一些重要資訊。

Android逆向之旅---靜态分析技術來破解Apk一、前言二、準備工作三、技術原理四、案例分析五、未解決的問題六、技術總結六、總結

六、總結

這篇文章總算是講解完了,其實早就想用寫破解的文章了,因為破解比加強有意思,至少破解成功了有成就感。這篇文章主要介紹了如何通過靜态分析方式破解,介紹了一些工具的時候,破解流程和破解技巧。最常用的就是代碼注入技術和全局搜尋關鍵字元串等方式,但是我們可以看到,現在市面上的很多apk,光通過靜态分析是無法滿足我們的破解需求了,是以動态分析方式就來了,而且動态方式破解難度會很大,需要掌握的東西也很多,我後面會分幾篇文章來一一介紹動态破解的技巧和常見的問題。但是靜态方式破解也是很重要的。當然也是動态分析的前提,是以我們既然玩破解,那麼這兩種技術都必須很好的掌握。