脫掉“愛加密”家的殼

一、案例分析

第一步:反編譯解壓apk得到的classes.dex文件,得到java源碼。
這裏寫圖片描述
看到,這裏只有Application的殼,而且這個是愛加密加固之後的特點,都是這兩個Application的。

第二步:使用apktool反編譯apk,獲取資源文件信息

這裏寫圖片描述
在application中加上這一句“android:name=’com.shell.SuperApplication’”原來就跑到自己加的類中去了,就變成“入口類了”!
分析一下加密流程:

愛加密把我們的源程序進行加密操作然後隱藏到了一個地方,在之前破解加固apk的那篇文章中也說過了,隱藏的地方就那麼幾個:assets目錄、libs目錄、自己的dex文件中。

我們在AndroidManifest.xml中看到了入口的Application類,先來看這個類
下面我們來分析一下這個SuperApplication類:

這裏寫圖片描述
注意:Application裏面attachBaseContext和onCreate函數調用順序

Application-> attachBaseContext ();

ContentProvider:onCreate()

Application:onCreate()

這裏一般都是在attachBaseContext這個方法中進行操作的,這裏的時機比較早,我們看到首先會調用loadLibs方法進行加載libs:
這裏寫圖片描述
這裏區分不同的平臺,然後進行拷貝不同的so文件,繼續看copyLib方法:
這裏寫圖片描述
這裏我們可以看到了,從assets目錄下把愛加密增加的兩個so文件:libexec.so和libexecmain.so拷貝到應用程序的files目錄下。

到這裏loadLibs方法就執行完了,下面就開始調用NativeApplication的load方法進行加載數據,繼續看NativeApplication類:
這裏寫圖片描述
這裏會開始從應用程序的files目錄中加載這兩個so文件,而且load方法也是一個native方法,我們繼續看看這兩個so文件內容:
我們首先用IDA打開libexecmain.so文件,但是發現,他裏面並沒有什麼重要信息,連JNI_OnLoad函數都沒有東東
這裏寫圖片描述
我們繼續再查看libexec.so文件:
這裏寫圖片描述
提示格式錯誤,可能被加密了,ELF格式改了,那麼我們yes強制打開,再使用ctrl+s查看so的各個段信息:
這裏寫圖片描述
現在可以百分百的確定,這個so文件被處理了,段格式被修改了。我們沒辦法分析so文件了,當然這裏我們可以在dump出內存中的so文件,然後在分析的,但是這個不是今天講解的重點。我們先分析到這裏,也知道了愛加密的大體加密流程。
這裏寫圖片描述

注意:
理解:就是說application是用來保存全局變量的,並且是在package創建的時候就跟着存在了。所以當我們需要創建全局變量的時候,不需 要再像j2se那樣需要創建public權限的static變量,而直接在application中去實現。只需要調用Context的getApplicationContext或者Activity的getApplication方法來獲得一個application對象,再做出相應 的處理。創建自己的類時,繼承即可。
android系統會爲每個程序運行時創建一個Application類的對象且僅創建一個,所以Application可以說是單例 (singleton)模式的一個類.且application對象的生命週期是整個程序中最長的,它的生命週期就等於這個程序的生命週期。因爲它是全局 的單例的,所以在不同的Activity,Service中獲得的對象都是同一個對象。所以通過Application來進行一些,數據傳遞,數據共享 等,數據緩存等操作。
二、破解脫殼
那麼還是開始說到的,脫殼的核心就一個:給dvmDexFileOpenPartial函數下斷點,dump出內存的dex文件即可。
過程:
第一步,啓動設備中的Android_server,然後進行端口轉發。
第二步,debug模式啓動程序
第三步,雙開IDA,一個用於靜態分析libdvm.so,一個用於動態調試。
第四步:使用jdb命令attach上調試器。
第五步:對dvmDexFileOpenPartial函數下斷點。
第六步:設置Debugger Options選項。

再次點擊任何一個按鈕,都會退出了調試頁面:

這裏寫圖片描述
三、反調試檢測
當時我們也是遇到這個情況,在沒有運行到我們下的斷點處,就退出了調試頁面,其實這個是現在加固平臺必要選擇的一種方式,其實反調試原理很簡單,就是在程序運行最早的時機比如so加載的時候即:JNI_OnLoad方法中,讀取本進程的status文件,查看TracerPid字段是否爲0,如果不爲0,那麼就表示自己的進程被別人跟蹤了,也就是attach了,那麼這時候立馬退出程序,下面我們使用IDA在attach進程成功之後,查看本進程的status信息。

首先我們上面分析了反調試的原理,一般在native代碼去做檢測的話,都是用fopen系統函數打開status文件,然後用fgets函數讀取一行的內容,這個是國際慣例的,操作文件都是用的fopen函數的。

既然反調試肯定用到了fopen和fgets這兩個函數,那麼我們直接像給dvmDexFileOpenPartial下斷點的方式一樣,給這兩個函數下斷點,然後運行到fgets斷點處的時候,發現如果是讀取TracerPid這行內容的時候,就開始修改內存內容,把TracerPid字段的值改成0,或者修改R0寄存器的內容,跳過反調試檢測。

四、還原應用apk
我們得到了內存中的dex數據之後,可以使用baksmali工具轉化成smali源碼,查看代碼邏輯即可,這裏不再演示了。

然後最後還有一步:還原apk

首先我們修改反編譯之後的AndroidManifest.xml中:

android:name=”com.shell.SuperApplication”

把這段內容刪除,如果有自己的Application的話,就改成自己的Application即可,同時刪除assets目錄下面的文件(入口activity不管嗎?難道使用的是磨人的?!)。

然後使用apktool進行回編譯,這時候,先不要着急簽名apk,而是替換classes.dex:

我們把上面得到的dump.dex改成classes.dex然後直接用壓縮軟件,替換未簽名的apk中的dex文件即可

最後在進行簽名操作,完成還原apk工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章