來了,調試器檢測。總結如下,多多指教:
檢測app 是否被附加調試:
原理就是檢測父進程是否 launchd啟動,在OS X和iOS 系統中,用戶環境始于launchd,為用戶態出現的第一個進程,為所有的進程的祖先,launchd 的進程PID = 1,
正常情況下,app的啟動都是launchd來啟動的。當app 被調試的時候,PID 的值則變成了調試器的PID,不等于 1
下面是檢測TikTok app 是否被附加調試三種方法,
1.是通過 sysctl函數調用
2.通過getppid 函數調用
3.利用匯編代碼svc 調用
檢測和反檢測都是一目了然的,矛和盾的關系都是平等的。
//非Debug狀態,返回值為1,Debug狀態返回Debugserver進程id
//首先,它檢查父進程 id (ppid) 是否與 /sbin/launchd 相同,后者為 1。不相等則為調試狀態
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | + (pid_t)GetParentPidByProc { ???? int ?name[ 4 ]; ???? name[ 0 ]? = ?CTL_KERN; ???? name[ 1 ]? = ?KERN_PROC; ???? name[ 2 ]? = ?KERN_PROC_PID; ???? name[ 3 ]? = ?getpid(); ???? struct kinfo_proc info; ???? size_t info_size? = ?sizeof(info); ???? info.kp_proc.p_flag? = ?0 ; ???? / * 查詢成功返回 0 * / ???? int ?error? = ?sysctl(name, sizeof(name)? / ?sizeof( * name), &info, &info_size, NULL,? 0 ); ???? if ?(error? = = ?0 ) { ???????? return ??info.kp_eproc.e_ppid; ???? } ???? return ?0 ; } |
//非Debug狀態,返回值為1,Debug狀態返回Debugserver進程id
//首先,它檢查父進程 id (ppid) 是否與 /sbin/launchd 相同,后者為 1。不相等則為調試狀態
1 2 3 4 5 6 7 8 9 10 | + (pid_t) GetParentPid{ ???? bool ?bRet? = ?false; ???? pid_t LAUNCHD_PID? = ?1 ; ???? ? ???? pid_t ppid? = ?getppid(); ???? if ?(ppid? = = ?LAUNCHD_PID) { ???????? bRet? = ?true; ???? } ???? return ?ppid; } |
//通過svc 匯編代碼來調用,非Debug狀態,返回值為1,Debug狀態返回Debugserver進程id
1 2 3 4 5 6 7 8 9 10 11 12 | + (pid_t) GetParentPidBySvc{ ???? NSInteger ppid? = ?0 ; ???? __asm__ volatile( ????????????????????? "mov x16,#39\t\n" ????????????????????? "svc 0x80\t\n" ????????????????????? "mov %0,x0\t\n" ????????????????????? : "=r" (ppid) ????????????????????? : ????????????????????? : ????????????????????? ); ???? return ?(pid_t)ppid; } |