1. 程式人生 > >脫掉“愛加密”家的殼

脫掉“愛加密”家的殼

一、案例分析

第一步:反編譯解壓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工作。