給大家介紹一下反調(diào)試匯總的原理及實(shí)現(xiàn)方式,以及各種反調(diào)試的擴(kuò)展

反調(diào)試匯總:
針對于一些大型apk 反調(diào)試不一定是讓你不能調(diào)試 -> 讓你得到一個(gè)錯(cuò)誤的結(jié)果
逆向某一個(gè)算法 傳參 中間會根據(jù)一些數(shù)據(jù)運(yùn)算 如果檢測到反調(diào)試 計(jì)算錯(cuò)誤
1.IDA調(diào)試端口檢測
監(jiān)測android_server文件端口信息 默認(rèn)的23946(5D8A)
更改端口 31927 -> 過掉此反調(diào)試
2.調(diào)試器進(jìn)程名檢測
監(jiān)測android_server gdbserver gdb等進(jìn)程
通過ps命令來監(jiān)測有沒有相應(yīng)的進(jìn)程信息 android_server as
更改android_server文件名 -> 過掉反調(diào)試
3.父進(jìn)程名檢測
app應(yīng)用的進(jìn)程都是由zygote fork 而來 也包括系統(tǒng)應(yīng)用
vs遠(yuǎn)程調(diào)試 用可執(zhí)行文件加載so:父進(jìn)程名為gdbserver
4.自身進(jìn)程名檢測
多用于單獨(dú)調(diào)用so 包括 apk來調(diào)用so 可執(zhí)行文件調(diào)用so
apk來調(diào)用so -> 包名與原apk的包名一致
LoadLibrary()函數(shù)加載so文件 僅有這種情況 除非它是自定義linker加載so文件(360殼)
5.apk線程數(shù)量檢測
比如說:我們寫了一個(gè)demo apk 來調(diào)用so文件(要調(diào)試的apk比較大 環(huán)境比較復(fù)雜 調(diào)試的時(shí)候容易跑蹦)
demo apk線程數(shù)量一般 不是很多,相較于原apk
找到檢測點(diǎn) nop掉
6.apk進(jìn)程fd文件檢測
類似于apk線程數(shù)量檢測
/proc/pid/fd/文件個(gè)數(shù)差異
檢測apk是否以debug模式啟動 即使進(jìn)行ida調(diào)試了 程序的大部分功能依然沒有運(yùn)行 所以fd文件較正常偏少
找到檢測點(diǎn) nop掉
7.安卓系統(tǒng)自帶調(diào)試檢測函數(shù)
android.os.Debug.isDebuggerConnected()? 當(dāng)程序被調(diào)試時(shí) 返回值為 true
根據(jù)全局變量 DebuggerActive來判斷
特征: 在java層 搜索 isDebuggerConnected 函數(shù)名
動態(tài)調(diào)試時(shí)在libart.so 中 _ZN3art3Dbg15gDebuggerActiveE函數(shù)下斷 讓其函數(shù)值為 0 或者直接在內(nèi)存窗口
修改全局變量
8.ptrace檢測
IDA gdb 都要附加
一個(gè)app只能被附加一次
在自己app中開一個(gè)線程 然后附加本應(yīng)用 如果附加失敗 證明應(yīng)用被調(diào)試
先于別的附加 自己附加自己 那么本應(yīng)用就不能被附加 從而避免被調(diào)試
可以在ptrace函數(shù)做手腳 hook函數(shù) ida動態(tài)調(diào)試時(shí)打斷點(diǎn)做處理 或者直接干掉反調(diào)試
以debug模式啟動
分界線 理論上以上調(diào)試都是直接跑蹦 一下有特殊情況
9.函數(shù)hash值檢測
為什么ida中打了斷點(diǎn) 程序會斷在此位置? 軟件斷點(diǎn) 不唯一 int 3 調(diào)試異常 bkpt斷點(diǎn)指令
根據(jù)這個(gè)原理 來檢測一段指令的hash值時(shí)候發(fā)生變化 變化了就說明存在軟件斷點(diǎn)
沒有創(chuàng)建線程 掃了一下 -> 會在調(diào)試點(diǎn)直接崩潰
創(chuàng)建線程 循環(huán)比較函數(shù)hash值是否相等 若不等 則kill
可以從 創(chuàng)建線程api出發(fā) 同時(shí),此調(diào)試點(diǎn)肯定在指令被檢測之前運(yùn)行 之后是不可能的
可以試試 ctrl +f7 即 回溯
10.斷點(diǎn)指令檢測
和上面其實(shí)并沒有本質(zhì)區(qū)別
11.系統(tǒng)源碼修改檢測
tracePid檢測 _ZN3art3Dbg15gDebuggerActiveE函數(shù)
查看 /proc/pid/status 目錄下的 tracePid 是否為0 若為0 則未被調(diào)試 若不為0 則被調(diào)試
解決辦法:可以修改系統(tǒng)源碼實(shí)現(xiàn) tracePid 恒為0 不論是否被調(diào)試
動態(tài)調(diào)試的反調(diào)試檢測點(diǎn)
程序直接掛掉 直接可以nop掉或者fopen函數(shù)下斷 打開/proc/pid/status目錄時(shí) 修改內(nèi)存中 tracePid的值
可以自己附加自己 查看tracePid是否為0 若為0 則修改了系統(tǒng)源碼 kill進(jìn)程 若不為0 則為修改
12.單步調(diào)試陷阱
可以模擬IDA打下斷點(diǎn),即修改相應(yīng)指令的二進(jìn)制 將其改為bkpt指令 需要修改內(nèi)存也屬性 mprotect()
自己注冊斷點(diǎn)處理函數(shù) 做什么事?
把斷點(diǎn)處指令 恢復(fù)成正常的指令 等一些列工作
如果IDA動態(tài)調(diào)試走到此斷點(diǎn)處 IDA會正常的處理此斷定指令 但是我們的信號處理函數(shù)已經(jīng)將此指令處理完畢
IDA做了重復(fù)性的工作 -> 程序崩潰
崩潰特點(diǎn):立即崩潰 程序一般不會被kill 會指令走不動 f8 f9 一直彈信號
借助于IDA調(diào)試缺陷來設(shè)置的反調(diào)試
反調(diào)試設(shè)置的地方可能不在這個(gè)指令崩潰的附近 反調(diào)試點(diǎn)不太好找
內(nèi)聯(lián)匯編 __asm__{}; 有可能在內(nèi)聯(lián)匯編中做此反調(diào)試 反調(diào)試設(shè)置的地方在其周圍
13.基于信號的檢測
signal() raise() 發(fā)送信號
利用IDA先截獲信號特性的檢測
IDA總是先于我們的應(yīng)用程序截獲信號
signal(SIGTRAP, myhandler); SIGTRAP:調(diào)試信號 myhandler:信號處理函數(shù)(自己實(shí)現(xiàn)的)
信號處理函數(shù) 可以設(shè)置一個(gè)全局變量
終止進(jìn)程方式可以kill進(jìn)程 或者 sleep()
先給程序設(shè)置signal 并實(shí)現(xiàn)信號處理函數(shù)
在關(guān)鍵函數(shù)里或者開一個(gè)線程 隔時(shí) 發(fā)送信號 即 raise()
若信號未收到 則程序被調(diào)試
信號 消息機(jī)制 被捕獲就會消失 一次性
14.利用IDA解析缺陷反調(diào)試
BLX BX 跳轉(zhuǎn)指令 可切換指令集
X帶指令切換 L帶鏈接
IDA解析 是Thumb指令還是Arm指令時(shí)可能出錯(cuò) 遞歸下降算法來反匯編指令
這種情況多發(fā)生于靜態(tài)分析 動態(tài)調(diào)試指令執(zhí)行基本不會出現(xiàn)
__asm __volatile{"","memory"} asm 前綴 從這里開始指令為匯編指令
volatile 會面的匯編指令不要給我優(yōu)化 按我的執(zhí)行
讓IDA 指令識別錯(cuò)誤 即Arm Thumb指令 錯(cuò)誤識別類型 -> 導(dǎo)致程序無法正常運(yùn)行
nop掉
15.時(shí)間反調(diào)試
gettimeofday() time() 常用
通過獲取兩個(gè)時(shí)間 來計(jì)算出時(shí)間間隔 從而確定時(shí)候被反調(diào)試
如果我們進(jìn)行調(diào)試時(shí) 不f8單步 或者不停留 那么這種反調(diào)試是無用的
關(guān)鍵算法 或者程序比較靠前的地方
在gettimeofday函數(shù)下斷 最近的兩次調(diào)用 將其返回值改成一樣的
直接找到反調(diào)試設(shè)置的地方 然后給nop
time()函數(shù) time_t結(jié)構(gòu)體 clock()函數(shù) clock_t結(jié)構(gòu)體 gettimeofday()函數(shù)
timeval結(jié)構(gòu) timezone結(jié)構(gòu) clock_gettime()函數(shù) timespec結(jié)構(gòu) getrusage()函數(shù) rusage結(jié)構(gòu)
16. Inotify事件監(jiān)控dump
防dump文件
Inotify系列api來監(jiān)控mem或pagemap的打開或訪問事件 自己設(shè)置要監(jiān)測的文件
當(dāng)然,除此之外 還有別的反調(diào)試 比較多的就是這個(gè)環(huán)境問題