objective-c runtime安全措施之一:反调试

反调试:检查是否有debugger在trace进程 (预防动态调试进程)
方法1: 检查进程的状态是否为 P_TRACED
原理:当进程被调试的时候,内核自动设置进程选项为P_TRACED。因此可以通过检查该标记来确认是否被调试

#include <unistd.h>

#include <sys/types.h>

#include <sys/sysctl.h>

#include <string.h>

staticint check_debugger()__attribute__((always_inline));

int check_debugger()

{

   size_t size = sizeof(structkinfo_proc);

   struct kinfo_proc info;

   int ret, name[4];

   memset(&info, 0,sizeof(structkinfo_proc));

    name[0] =CTL_KERN;

    name[1] =KERN_PROC;

    name[2] =KERN_PROC_PID;

    name[3] =getpid();

   if ((ret = sysctl(name,4, &info, &size, NULL,0))) {

        return ret;/* sysctl() failed for some reason */

    }

   return (info.kp_proc.p_flag &P_TRACED) ? 1 :0;

}


【注意】  为了避免sysctl被替换,需要在调用该函数前验证其完整性(在思路二中会介绍如何验证sysctl函数完整性)
--------------------------------------------------------------------------------------------------------------------------------------------------
方法2:调用ptrace请求来检查进程是否被调试
原理,调用ptrace请求的PT_DENY_ATTACH方法。使用该方法后,下面两种情况都会导致调试器崩溃,应用退出。
(1)如果应用使用调试器来运行,调试器会崩溃;(下面以调试iTunes为例)
$ gdb -q /Applications/iTunes.app/Contents/MacOS/iTunes
Reading symbols for shared libraries .................................... done
(gdb) r
Starting program: /Applications/iTunes.app/Contents/MacOS/iTunes
Reading symbols for shared libraries ++++++++++++++++++++++++++++++....++++
+....................................................................................
............................................................... done
Program exited with code 055.
(gdb)
(2)如果应用运行中,使用调试器,调试器也会崩溃。
$ gdb -q -p 3933
Attaching to process 3933.
Segmentation fault: 11
 

Mac OS X系统

#include<sys/ptrace.h>

int main(int argc,char *argv[])

{

    ptrace(PT_DENY_ATTACH,0, 0,0);

    @autoreleasepool {

        returnUIApplicationMain(argc, argv, nil,NSStringFromClass([AppDelegateclass]));

    }

}


iOS系统中

int main(int argc,char *argv[])

{

    ptrace(31,0, 0,0);  //因为PT_DENY_ATTACH只存在于iOS模拟器头文件中,所以用31来代替

    ...

}


【注意】
1. ptrace方法可以通过打断点的方法绕过,如下所示:
# gdb ?1 ./main
Reading symbols for shared libraries . done
(gdb) b ptrace
Function "ptrace" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (ptrace) pending.
(gdb) commands
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>return
>continue
>end
(gdb) run
Starting program: /private/var/root/main
Reading symbols for shared libraries .............................. done
Breakpoint 1 at 0x342afa98
Pending breakpoint 1 - "ptrace" resolved
Breakpoint 1, 0x342afa98 in ptrace ()
I'm doing something really secure here!!
2.由于可能被攻击者绕过该方法的调用,在应用的多处增加ptrace函数会提高应用的安全性

你可能感兴趣的:(Objective-C)