安卓逆向_21 --- Java层和so层的反调试( IDA 动态调试 JNI_OnLoad、init_array下断)
?
1. 安卓程序動態調試條件
?
安卓程序動態調試條件 ( 2個滿足1個即可 ):
- 1. 在 AndroidMainfest.xml ---> application 標簽下,設置或者添加屬性?android:debuggable="true"
- 2. 系統默認模式,在 build.prop(boot.img),ro.debuggable=1
Android SDK 中有 android.os.debug 類提供了一個 isDebuggerConnected方法,用于判斷 JDWP 調試器是否正在工作
?
?
2. Java層 的 反調試
?
示例:手動繞過百度加固 Debug.isDebuggerConnected 反調試的方法:
https://blog.csdn.net/QQ1084283172/article/details/78237571
?
**************************************************************************************************************
? ? AndroidStudio調試smali 和 java 都是用的 jdwp 進行轉發, IDA調試 so 用的是 tcp 轉發?
**************************************************************************************************************
?
JDWP 協議介紹
JDWP 是 Java Debug Wire Protocol 的縮寫,它定義了調試器(debugger)和 被調試的 Java 虛擬機(target vm)之間的通信協議。JDWP 協議可以?遠程 動態調試 Java 程序。
JVM 自帶有對這個協議相應的支持,通過命令?java -agentlib:jdwp=help 可以查看help文檔。
說明一下 debugger 和 target vm
- Target vm 中運行著我們想要調試的程序,它與一般運行的 Java 虛擬機沒有什么區別,只是在啟動時加載了 Agent JDWP 從而具備了調試功能。
- debugger 就是我們熟知的調試器,它向運行中的 target vm 發送命令來獲取 target vm 運行時的狀態和控制 Java 程序的執行。
- Debugger 和 target vm 分別在各自的進程中運行,他們之間的通信協議就是 JDWP。
JDWP 與其他許多協議不同,它僅僅定義了數據傳輸的格式,但并沒有指定具體的傳輸方式。這就意味著一個 JDWP 的實現可以不需要做任何修改就正常工作在不同的傳輸方式上(在 JDWP 傳輸接口中會做詳細介紹)。
JDWP 是語言無關的。理論上我們可以選用任意語言實現 JDWP。然而我們注意到,在 JDWP 的兩端分別是 target vm 和 debugger。Target vm 端,JDWP 模塊必須以 Agent library 的形式在 Java 虛擬機啟動時加載,并且它必須通過 Java 虛擬機提供的 JVMTI 接口實現各種 debug 的功能,所以必須使用 C/C++ 語言編寫。而 debugger 端就沒有這樣的限制,可以使用任意語言編寫,只要遵守 JDWP 規范即可。JDI(Java Debug Interface)就包含了一個 Java 的 JDWP debugger 端的實現(JDI 將在該系列的下一篇文章中介紹),JDK 中調試工具 jdb 也是使用 JDI 完成其調試功能的。
JDWP agent 在調試中扮演的角色
使用 JDWP 遠程調試 java 程序:https://www.jianshu.com/p/4b322505087f
使用 JDWP 進行遠程調試:https://blog.csdn.net/renfufei/article/details/52756556
?
?
3. so層 的 反調試(? JNI_OnLoad?)
?
拿到一個?apk 分析步驟:首先先分析有沒有加殼,如果沒有加殼,使用?jadx-gui?打開自動反編譯,并進行分析,如果有加殼,需要先脫殼,然后在進行分析。找到 入口點 或者 入口頁面?進去查看分析。
IDA Pro 分析 so 庫 JNI_OnLoad:https://www.bilibili.com/video/BV1UE411A7rW?p=69
AntiDebug 源碼:https://github.com/weikaizhi/AntiDebug?。
github 下載完直接編譯報錯 ,所以使用?AndroidStudio 打開項目后需要做如下修改
- 在 antidebug.cpp 中添加?#include <pthread.h>?
- AndroidManifest.xml 的?application 節點添加?android:debuggable=true
然后編譯生成 apk,但是生成的 apk 是沒有簽名的,沒法安裝到手機或者模擬器上。
可以使用 AndroidStudio、apk上上簽、AndroidKiller、安卓逆向助手等進行簽名。這里使用 AndroidKiller 進行簽名。。。
簽名后就可以在手機或者模擬器上安裝 apk 了。。。
源碼中的反調試函數( 可以看到只檢測了三個:狀態、IsHookByXPosed、isBeDebug?)
//反調試檢測 MACRO_HIDE_SYMBOL void* AntiDebug::antiDebugCallback(void *arg) {if(arg == NULL)return NULL;AntiDebug* pAntiDebug = (AntiDebug*)arg;while (true){try{bool bRet1 = pAntiDebug->readStatus();bool bRet2 = pAntiDebug->IsHookByXPosed();bool bRet3 = pAntiDebug->isBeDebug();if(bRet1 || bRet2 || bRet3){if(g_callbackRef != 0 && g_MethodCallback != 0){JNIEnv* env = GetEnv();if(env != NULL){env->CallVoidMethod(g_callbackRef, g_MethodCallback);}}}} catch (...){}sleep(1);} }當反調試被觸發時,會出現一個彈窗,如圖所示:
?
?
靜態分析
下面使用 IDA Pro 進行 so 庫的分析,解壓 apk ,找到 so 文件
使用 IDA 打開,首先 Ctrl + s 搜索 段,看下 init_array 里面有沒有函數,發現沒什么有用的東東,繼續在?Exports 里面搜索 java_ 和 jni,分析后發現 java_ 開頭的靜態注冊函數也沒有啥東東,所以分析 JNI_OnLoad 函數
源碼中 JNI_OnLoad 函數
繼續分析 sub_9C9C 這個函數。。。
?
方法 2:通過 IDA Pro 的 String 查看,看看有沒有可疑的字符串。這種方法信息量比較多,還是推薦直接分析 JNI_OnLoad
源碼中的反調試函數( 可以看到只檢測了三個:狀態、IsHookByXPosed、isBeDebug?)
可以參看源碼 和 so 理解反調試。。。。。
?
?
動態分析
?
參考:安卓逆向_17 --- 動態調試【 環境搭建、so庫調試【動態普通、動態debug模式】、JNI_OnLoad調試分析、java_ 開頭函數分析】:https://blog.csdn.net/freeking101/article/details/106701908
?
?
4. 示例
?
4.1 FindTracer.apk 過反調試 (? 動態調試 JNI_OnLoad?)
?
反調試:https://www.bilibili.com/video/BV1UE411A7rW?p=70
FindTracer 破解反調試:https://www.jianshu.com/p/a2b3517d4815
安裝 apk,然后打開 app,沒有被調試時,顯示 Everything fine?。
首先看下 Java 層,使用 jadx-gui 反編譯 apk,看下 Java 代碼,查看 入口點、入口頁面
可以看到 FindTracer.getInstance().findTracer()? 就是檢測反調試的代碼,雙擊 findTracer() 函數,進入查看函數
可以看到是 native 函數,所以需要從 so 庫入手。。。
IDA 打開 so 后(?init_array 執行時間比 JNI_OnLoad?早,所以先分析?init_array,再分析 java_ 或者?jni_onload):
- Ctrl + s ,找到 init_array,看下 init_array 里面有沒有檢測函數 ( 本例沒有?)
- 搜索 java_ 和 jni_onload,進行分析
?
?
4.2?自毀程序密碼.apk (? 動態調試 JNI_OnLoad?)
?
APK文件下載鏈接:?http://pan.baidu.com/s/1ntiKXg1?密碼: 37xw
其中??AliCrackme_2.apk?是原安裝包,?signed.apk?是包含修改后so文件的安裝包。
自毀程序密碼(第二題)》分析( IDA 動態調試so ):https://www.pd521.com/thread-291-1-1.html
:https://www.bilibili.com/video/BV1UE411A7rW?p=71
安裝 apk,然后打開 app 如圖所示:
打開 app 后,直接出現如上圖界面,這個就是?"入口頁面"。首先還是從?Java 層開始,使用 jadx-gui 反編譯 apk,看下 Java 代碼,查看 入口點、入口頁面。
入口頁面代碼:
可以看到如果 if 條件滿足,則直接打開 ResultActivity 頁面,通過查看?ResultActivity 頁面的代碼可知這個是成功后的頁面
如果不滿足,則彈出 "驗證碼校驗失敗",所以 if 里面的 securityCheck 函數就是檢測反調試的。securityCheck 函數被 native 修飾,所以是在 so 里面實現的。同時 securityCheck 沒有被 static 修飾。
?
使用 IDA 打開?crackme.so ---> Exports ---> 搜索 java_ 和 jni_onload ---> 分析C++ 函數
?
搜索 java_?
securityCheck 函數只有一個 String 類型的參數,所以securityCheck對應的 java_ 開頭的函數的第三個參數類型修改為 jstring
通過分析,沒找到有用的東東,然后再 分析 jni_onload
搜索 jni_onload,發現也看不出什么有用的東東,
所以 動態調試 看下。(自毀程序密碼:( IDA 動態調試so ):https://www.pd521.com/thread-291-1-1.html)
?
?
4.3 crackme?(??動態調試?JNI_OnLoad?)
分析類似 4.2 ,導入 jni.h 識別函數
:https://www.bilibili.com/video/BV1UE411A7rW?p=72
?
?
5. init_array 下斷
?
:https://www.bilibili.com/video/BV1UE411A7rW?p=74
?
?
?
?
總結
以上是生活随笔為你收集整理的安卓逆向_21 --- Java层和so层的反调试( IDA 动态调试 JNI_OnLoad、init_array下断)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python之socket编程
- 下一篇: java美元兑换,(Java实现) 美元