關於手遊反調試的事

Android 經常使用反調試方法

  1. TracerPid:/proc/self/status 的 TracerPid 字段,非調試狀態下的數值爲 0,調試狀態下的數值爲調試器的進程 pid
  2. 子進程調試:子進程對父進程進行調試,佔用調試名額,防止其它調試器附加
  3. rtld_db_dlactivity:Linker 符號 rtld_db_dlactivity ,函數指針,非調試狀態下爲空指針,調試狀態下指向斷點;非導出函數,遍歷內存中的 /system/bin/linker 的符號表得到符號地址
  4. Debug 類:執行 Android 系統函數 android.os.Debug.isDebuggerConnected() ,返回當前的調試器的附加狀態
方法 效果
TracerPid 得到調試器PID
子進程調試 佔據調試名額,防止非法調試器附加
rtld_db_dlactivity 得到調試器附加狀態
Debug 類 得到調試器附加狀態

理論上這幾種反調試單獨使用都能取得不錯的效果,但容易被繞過。因此通常狀況下都是聯合使用,增長反反調試的成本,同時還能夠應對不一樣的場景。android

如使用 SDK 方式分發安全模塊,則不能影響手遊項目的正向開發。正常的開發環境下,調試器和遊戲進程在同一個用戶組中,這種狀況下只能使用檢測 TracerPid 的方式。取出調試器的 GID 和遊戲進程的 GID 看是否在同一個用戶組中,便可判斷出是否爲合法調試器。xcode

iOS 經常使用反調試方法

  1. 禁止附加:經過 ptrace(PT_DENY_ATTACH,0,0,0) 來禁止調試器附加,ptrace 函數在 iOS 下沒有對應的頭文件函數聲明,須要經過 dlsymextern int ptrace(int,pid_t,cadrr_t,int)的形式得到
  2. 檢測跟蹤標識:使用 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指針

相關文章
相關標籤/搜索