安卓應用加固之反動態調試技術總結

0x00 前言android

動態調試是比靜態分析更爲高效地一種破解手段。所以在破解安卓應用以前,通常會先對應用進行動態調試,瞭解應用大體運行流程和各個類之間的邏輯關係。算法

反動態調試能夠從如下兩個個方向着手:安全

1.運行環境檢測:檢測應用的運行環境是否安全,是否可能存在被調試的風險架構

2.動態調試指令檢測:檢測應用的運行過程當中是否受到動態調試指令的控制函數

 

本文徹底參考自網友  愛吃菠菜  的反調試總結,因爲個人資料是pdf文檔,已經找不到出處,在此對網友 愛吃菠菜 說一聲抱歉。加密

 

0x01 運行環境檢測spa

1.調試端口檢測線程

不一樣調試器默認使用不一樣的調試端口,且這些端口默認值每每不被修改。調試

 

2.調試器進程檢測server

不一樣調試器會在系統中建立不一樣進程對應用進行劫持以達到動態調試目的。

 

3.父進程名檢測

針對so文件,破解者能夠本身編寫一個APK對so庫進行調試。

(1)正常啓動的apk程序:父進程是zygote
(2)調試啓動的apk程序:在AS中用LLDB調試發現父進程仍是zygote
(3)附加調試的apk程序:父進程是zygote
(4)vs遠程調試 用可執行文件加載so:父進程名爲gdbserver
父進程名非zygote的,斷定爲調試狀態。
 

4.自身進程名檢測

原理同上條。正常的APK進程名通常爲入口類的目錄。形如:com.xxx.xxx.xxxx.xxxMainActivity。在開發時,該值是已知的,所以可對該值進行檢測。

 

5.apk線程檢測

正常APK運行時通常會有多個線程在運行,能夠在開發階段分析本身的源碼,正常運行時至少會有多少線程同時運行。針對若是破解者還是本身編寫APK調用so庫調試分析的狀況,此時的APK中通常只有一條線程。

 

6.apk進程fd文件檢測

分析系統中/ proc/pid/fd路徑下的文件差別進行判斷。

1)APK自己啓動的進程和非APK啓動的進程,fd數量不同

2)APK正常啓動和APK動態調試啓動,進程fd數量也不同

 

7.安卓系統自帶的動態調試檢測函數

android.os.Debug.isDebuggerConnected();

 

8.tracepid

/proc/pid/status文件中有一個tracepid字段,若進程被調試,則tracepid值不爲0,不然爲0。能夠對該值進行檢測以判斷該進程是否被調試。

能夠將statue字段寫爲t,中止調試

 

10.stat

若是是被調試狀態,則

/proc/pid/stat

/proc/pid/task/pid/stat

第二個字段是t(T)

 

11.wchan

/proc/pid/wchan

/proc/pid/task/pid/wchan

ptrace_stop

 

12.ptrace

每一個進程同一時刻只能被一個進程ptrace。

能夠主動ptrace本身,讓別的進程沒法對本身ptrace;也能夠寫多個進程,讓其互相之間ptrace以避免被調試器ptrace

 

13.代碼執行時間間隔檢測

在兩段不一樣代碼處插入時間函數,獲取當前時間。對兩個時間差進行檢測,若是差值過大,則說明兩段代碼運行時間間隔過長,多是被單步調試。

 

14.mem、pagemap監測

第三代殼技術原理:一般殼會在程序運行前完成對text的解密,因此脫殼能夠經過dd與gdb_gcore來dump  /proc/pid/mem或/proc/pid/pagemap,獲取到解密後的代碼內容。針對這種運行時解密再加密的殼,有的脫殼技術須要用到動態調試來dump內存中的數據。
能夠經過Inotify系列的API來監控mem或pagemap的打開或訪問事件,一旦發生就結束進程來阻止dump。

 

 

0x02  動態調試中檢測

 

1.斷點指令檢測

若是函數被下軟件斷點,則斷點地址會被改寫爲bkpt指令,能夠在函數體中搜索bkpt指令來檢測軟件斷電。

 

2.函數hash值檢測

so文件中函數的指令是固定,可是若是被下了軟件斷點,指令就會發生改變(斷點地址被改寫爲bkpt斷點指令),能夠計算內存中一段指令的hash值進行校驗,檢測函數是否被修改或被下斷點。

 

3.單步調試陷阱

調試器從下斷點到執行斷點的過程分析:
1)保存:保存目標處指令
2)替換:目標處指令替換爲斷點指令
3)命中斷點:命中斷點指令(引起中斷 或者說發出信號)
4)收到信號:調試器收到信號後,執行調試器註冊的信號處理函數。
5 )恢復:調試器處理函數恢復保存的指令
6)回退:回退PC寄存器
7 )控制權迴歸程序.
 
主動設置斷點指令/註冊信號處理函數的反調試方案:
1)在函數中寫入斷點指令
2)在代碼中註冊斷點信號處理函數
3)程序執行到斷點指令,發出信號,分兩種狀況:
  (1)非調試狀態
  進入本身註冊的函數,NOP指令替換斷點指令,回退PC後正常指令。
  (執行斷點發出信號—進入處理信號函數—NOP替換斷點—退回PC)
  (2)調試狀態
  進入調試器的斷點處理流程,他會恢復目標處指令失敗,而後回退PC,進入死循環。
 

4.利用IDA先截獲信號的特性進行檢測

IDA會首先截獲信號,致使進程沒法接收到信號,致使不會執行信號處理函數。將關鍵流程放在信號處理函數中,若是沒有執行,就是被調試狀態。

 

5.利用IDA解析缺陷攻擊IDA調試器

IDA調試器原理:IDA採用遞歸降低算法來反彙編指令,而該算法最大的缺點在於它沒法處理間接代碼路徑,沒法識別動態算出來的跳轉。而arm架構下因爲存在arm和thumb指令集,就涉及到指令集切換,IDA在某些狀況下沒法智能識別arm和thumb指令,進一步致使沒法進行僞代碼還原。

在IDA動態調試時,仍然存在該問題,若在指令識別錯誤的地點寫入斷點,有可能使得調試器崩潰。
 
 
待更.....以後我會把相應反調試技術的實現代碼補充上
相關文章
相關標籤/搜索