1. 程式人生 > >Android安全/應用逆向--29--在JNI_onload函式處下斷點避開針對IDA的反除錯

Android安全/應用逆向--29--在JNI_onload函式處下斷點避開針對IDA的反除錯

7-6、在JNI_onload函式處下斷點避開針對IDA的反除錯

為了防止apk中的so檔案被動態除錯,開發者往往會使用一些反除錯手段來干擾黑客的動態除錯。其中最常見的就是在so檔案中檢測TracerPid值。通過在JNI_onload下斷點即可避開反除錯。

反除錯原理:

1、ptrace:是系統呼叫的一個方法,該方法使一個程式(追蹤者)可以觀察和控制另外一個程式(被追蹤者)的執行,並檢查和改變被追蹤者的記憶體及暫存器。主要用於實現斷點除錯和追蹤系統呼叫。

2、Android中如果一個程序被另一個程序ptrace了之後,在它的status檔案中有一個欄位TracerPid可以標識它是被哪個程序ptrace了。可以使用命令檢視:

adb shell
ps \ grep 包名                //檢視對應的程序號
cat /proc/程序號/status       //檢視TracePid值
ps | grep Trace值            //檢視TracePid值對應哪個程序

3、在底層做一個迴圈檢測這個欄位值是不是0,如果不為0則代表自己的程序被別人Ptrace,如此則直接停止退出程式。注意這個檢測程式執行要非常早

對應辦法:

1、最早的兩個時機是:.init_array和JNI_OnLoad。 .init_array是一個so最先載入的一段資訊,時機最早,一般的so解密操作都是在這裡做的。 JNI_OnLoad是so被System.loadLibrary呼叫的時候執行,它的時機要早於那些native方法執行,但是沒有.init_array早

2、繞過JNI_OnLoad時機的方法: IDA提供了在so檔案Load的時機,在:debuger–DebuggerOptions,左邊勾選345(前期步驟有描述)

3、繞過.init_array即static時機的方法: 在System.loadLibrary方法之前加入waitForDebugger程式碼,然後回編譯即可。如此程式將停在載入so檔案之前

4、另一個方法: 使用am命令啟動一個程式:

adb shell am start -D -n 包名/.類名

啟動完成後,再次使用IDA進行程序的附加,同時設定DebuggerOption選項,再定位到JNI_OnLoad函式的絕對地址。使用jdb去attach等待的程式:

jdb -connect com.sun.jdi.SocketAttach:port=8700,hostname=localhost
除錯步驟:

1、找到的要除錯的程式下,繼續尋找我們需要下斷點的函式處。此時so已經載入進來,先獲取JNI_OnLoad函式的絕對地址。Ctrl+s即可找到基地址,靜態搜尋關鍵字JNI_Onload即可得到先相對地址,相加即可得到絕對地址,然後跳轉到該絕對地址即可。

2、在JNI_Onload函式下斷點(即剛才的絕對地址)

3、在/data/local/tmp下:

./android_server

4、新建命令列:

adb forward tcp:23946 tcp:23946

5、在debug模式下啟動apk應用:

am start –D –n <包名>/<包名.MainActivity>(包名/啟動頁面)

6、IDA附加程序:debugger-process options,配置除錯資訊,此處只需要配置hostname為localhost,其餘的保持預設設定即可。

7、單擊Debugger -> Attach to process進行附加程序的操作,選擇包

8、此時開啟DDMS,正常的話包名前是有蜘蛛的

後續進行:

1、輸入命令:

jdb -connect com.sun.jdi.SocketAttach:port=8700,hostname=localhost
//新建命令執行,進行jdb除錯

2、彈出的視窗一律點選取消。(此處有一鍵取消所有,不用逐個取消)

3、點選執行(執行完命令1,一般IDA 會停止),彈出debugger warning,選擇same

4、繼續執行,觸發之前的JNI_Onload處的斷點

5、F8逐步執行,找到跳轉到反除錯的地方

6、將跳轉反除錯的這一行在hex框中改為0,重新附加除錯,繞過加殼保護(也就是所說的nop掉),儲存修改掉之後的so檔案,並替換原來的so檔案

7、重新編譯,簽名安裝,正常查詢除錯程式碼