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