rtld_db_dlactivity
,函數指針,非調試狀態下爲空指針,調試狀態下指向斷點;非導出函數,遍歷內存中的 /system/bin/linker
的符號表得到符號地址android.os.Debug.isDebuggerConnected()
,返回當前的調試器的附加狀態方法 | 效果 |
---|---|
TracerPid | 得到調試器PID |
子進程調試 | 佔據調試名額,防止非法調試器附加 |
rtld_db_dlactivity | 得到調試器附加狀態 |
Debug 類 | 得到調試器附加狀態 |
理論上這幾種反調試單獨使用都能取得不錯的效果,但容易被繞過。因此通常狀況下都是聯合使用,增長反反調試的成本,同時還能夠應對不一樣的場景。android
如使用 SDK 方式分發安全模塊,則不能影響手遊項目的正向開發。正常的開發環境下,調試器和遊戲進程在同一個用戶組中,這種狀況下只能使用檢測 TracerPid 的方式。取出調試器的 GID 和遊戲進程的 GID 看是否在同一個用戶組中,便可判斷出是否爲合法調試器。xcode
ptrace(PT_DENY_ATTACH,0,0,0)
來禁止調試器附加,ptrace
函數在 iOS 下沒有對應的頭文件函數聲明,須要經過 dlsym
或 extern int ptrace(int,pid_t,cadrr_t,int)
的形式得到sysctl
查詢當前進程是否有 P_TRACED
標識,該標誌存在則標識進程正在被調試// 禁止附加 extern int ptrace(int, pid_t, caddr_t, int); void DisablePtrace() { ptrace(PT_DENY_ATTACH, 0, 0, 0); }
// 檢測跟蹤標識 int IsPflagExist() { size_t size = sizeof(struct kinfo_proc); struct kinfo_proc info; int name[4]; memset(&info, 0, sizeof(struct kinfo_proc)); name[0] = CTL_KERN; name[1] = KERN_PROC; name[2] = KERN_PROC_PID; name[3] = getpid(); if (!sysctl(name, 4, &info, &size, NULL, 0)) { return (info.kp_proc.p_flag & P_TRACED) ? 1 : 0; } return 0; }
在 App 發佈時使用這兩段代碼能夠有效阻止攻擊者進行調試。iOS 的反調試功能應由項目組添加,不應由第三方模塊提供。安全
### 禁止注入(已過期)iOS 下的注入大多數是經過環境變量 DYLD_INSERT_LIBRARIES
來實現,如 Cydia Substrate、Cycript 和 dumpdecrypted 等等。若是 App 的 Mach-O 文件中存在 函數Section(__RESTRICT/__restrict)
,那麼在 App 啓動時,dyld
會和忽略加載 DYLD_INSERT_LIBRARIES
環境變量指向的動態庫。使得攻擊者沒法直接使用 dumpdecrypted
進行脫殼。
方法:在 xcode 的 指針Other Linker Flags
中添加參數 -Wl,-sectcreate,__RESTRICT,__restrict,/dev/null