android 反逆向保護

地址:https://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=2653580160&idx=1&sn=ae96bf7a9576e76e69d97bd22c3ac1e0&chksm=84b3b987b3c43091e256655b14e0be250cb670341c8133340bec1069bc992873e94ef1ddee36&scene=0&xtrack=1#rd
Android app反調試與代碼保護的一些基本方案
原創: jackycao 騰訊Bugly 今天
| 導語 本文介紹Android app代碼(java + ndk)的反調試的方法和保護代碼增加逆向難度的一些基本方法。

ps:反調試並不能完全阻止逆向行爲,只是在長期的攻防戰中給破解人員不斷的增加逆向難度。

Java:
(1)Proguard
藉助Android studio的proguard工具,對Java代碼分別進行壓縮(Shrink)、優化(Optimize)、混淆(Obfuscate)、檢查(Veirfy)。

壓縮(Shrink):去掉代碼中無用的類、函數方法和字段。

優化(Optimize):對Android的可執行文件dex進行優化,去掉無用指令。

混淆(Obfuscate):用毫無意義的字段對代碼的類名、函數名、變量名重命名,比如用a, b, c這種。

檢查(Veirfy):對混淆後的代碼進行檢查。

經過Proguard後,代碼程序依然可以重新組織和處理,處理後的程序邏輯與之前完全一致,而混淆後的代碼即便反編譯後依然很難閱讀。同時,在混淆過程中對於一些不影響正常運行的信息將永久丟失,這些信息的丟失使得程序更加難以理解。

同時,Proguard還可以控制對某個類混淆,以及對某個類的某些函數方法混淆。

下圖是一張混淆前和混淆後的對比圖:

混淆前:

混淆後:

(2)isDebuggerConnected
Android Debug類提供isDebuggerConnected函數,函數原型如下:

在VMDebug類裏的isDebuggerConnected的具體實現在ndk程序裏。

在這裏插入圖片描述

這裏暫且不跟進該函數,總之,isDebuggerConnected函數用於檢測此刻是否有調試器掛載到程序上,如果返回值爲true則表示此刻被調試中。用法很簡單,如下:

(3)android:debuggable屬性
在Android的AndroidManifest.xml清單文件的application節點下加入android:debuggable="false"屬性,使程序不能被調試。在Java程序代碼裏也可檢測該屬性的值,如下:

在這裏插入圖片描述

NDK:

(1)ptrace函數
Linux內核的ptrace函數原型:

ptrace可以允許A進程控制B進程,並且A進程可以檢查和修改B進程的內存和寄存器。但是一個進程只能被一個進程調試,所以根據這個特點,可以讓進程自己ptrace自己,傳入的request設置爲PTRACE_TRACEME,程序被自己附加調試後,其他的調試操作就會失敗了。

(2)文件節點檢測
一旦程序處於被調試狀態,Linux會向進程的節點寫入數據,比如/proc//status內容中的TracePid會寫入調試進程的pid,如果TracePid的值不爲0,就表明進程處於被調試狀態了。

此外,通用的檢測邏輯還有檢測調試的端口號,Linux的文件節點/proc/net/tcp會記錄着正在運行的進程的本地的端口號,調試工具IDA的默認的調試端口是23946,通過讀取/proc/net/tcp內容,檢測是否有23946,如果找到了就表明進程處於被調試狀態了。

(3)Inotify
Linux的Inotify用於檢測文件系統變化。它可以檢測單個文件,也可以檢測整個目錄。

逆向最常做的一件事就是dump 內存,使用dd命令(或者如果使用gdb的話爲gcore命令),dump掉/proc//mem或/proc//mpas或/proc//pagemap的內容。

這裏,就可以使用Inotify API對上述三個文件監控,如果有發現打開、讀寫操作,極大概率就是進程正在被破解。

(4)so文件hash值檢測
so文件在被JNI_Onload加載後,so文件的函數的指令是固定的,若被調試器掛載,下了斷點後指令會發生改變(斷點地址會被改寫爲bkpt指令),計算內存中加載的so的hash值,進行校驗檢測函數是否被修改或被下斷點即可判斷出是否被調試狀態。

(5)時間差檢測
一個取巧的方法,正常情況下,一段程序在兩條代碼之間的時間差是很短的,而對於調試程序來說,單步調試中的程序兩條代碼之間的時間差會比較大,檢測兩條代碼之間的時間差,可以大概率判斷程序是否被調試。

Resource資源文件:
Android資源文件經常被惡意篡改,植入各種廣告,插件,嚴重影響了Android app生態平衡。

APK簽名檢測
Android SDK中有apk 簽名檢測的方法,Framework的PackageManager類提供了getPackageInfo()函數,函數原型:

第二個參數傳入GET_SIGNATURES時,返回對象的signature字段就是簽名信息,計算其hash值,前後對比hash值。實際可用的兩種方案:

(1)在本地Java代碼裏進行校驗,不一致則強退應用;

(2)把簽名信息發到服務器後臺,服務器後臺記錄着正確的簽名信息,比對後不一致則返回一個錯誤給錯誤。

上述即爲對於Android app的反調試,代碼保護的一些基本策略。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章