碳基体

奋斗在产品安全第一线的安全妹子

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

<<O'Reilly.Hacking.and.Securing.iOS.Applications>>读书笔记


反调试:检查是否有debugger在trace游戏进程 (预防动态调试进程)

方法1: 检查进程的状态是否为 P_TRACED 

原理:当进程被调试的时候,内核自动设置进程选项为P_TRACED。因此可以通过检查该标记来确认是否被调试

  

例子1:check_debugger()

  

#include <unistd.h>

#include <sys/types.h>

#include <sys/sysctl.h>

#include <string.h>

static int check_debugger( ) __attribute__((always_inline));

  

int check_debugger( )

{

size_t size = sizeof(struct kinfo_proc);

struct kinfo_proc info;

int ret, 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 (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;

  

}

【注意】

1. 为了让程序以inline方式编译,需要设置编译器的优化选项,-0z(函数以inline方式编译),-fast(加快编译速度)

  

2. 为了避免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( ) {

ptrace(PT_DENY_ATTACH, 0, 0, 0);

  

...

}

iOS系统中

  

int main( ) {

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函数会提高应用的安全性


来源:碳基体

评论