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、重新編譯,簽名安裝,正常查詢除錯程式碼