OS X Anti-Debugging and Anti-Anti-Debugging

  • 3419
  • 0

摘要:OS X Anti-Debugging and Anti-Anti-Debugging

1. ptrace方法

示例代码如下:


ptrace(PT_DENY_ATTACH,0,0,0);
printf("Hello, World!\n");

执行效果如下:

 

$ ./DebugMe 
Hello, World!
 
$ lldb ./DebugMe 
Current executable set to './DebugMe' (x86_64).
(lldb) r
Process 1526 launched: '/.../Build/Products/Debug/DebugMe' (x86_64)
Process 1526 exited with status = 45 (0x0000002d) 

 

破解方法:

$ ./DebugMe 
Hello, World!
$ lldb ./DebugMe 
Current executable set to './DebugMe' (x86_64).
(lldb) b ptrace
breakpoint set --name 'ptrace'
Breakpoint created: 1: name = 'ptrace', locations = 1
(lldb) r
Process 1539 launched: '/.../Build/Products/Debug/DebugMe' (x86_64)
Process 1539 stopped
* thread #1: tid = 0x1c03, 0x00007fff8b68c244 libsystem_kernel.dylib`__ptrace, stop reason = breakpoint 1.1
    frame #0: 0x00007fff8b68c244 libsystem_kernel.dylib`__ptrace
libsystem_kernel.dylib`__ptrace:
-> 0x7fff8b68c244:  xorq   %rax, %rax
 
libsystem_kernel.dylib`ptrace + 3:
   0x7fff8b68c247:  leaq   49154(%rip), %r11
   0x7fff8b68c24e:  movl   %eax, (%r11)
   0x7fff8b68c251:  movl   $33554458, %eax
(lldb) re r -f d
General Purpose Registers:
       rax = 31
       rbx = 0
       rcx = 0
       rdx = 0
       rdi = 31
(lldb) re w rdi 0
(lldb) c
Process 1955 resuming
Hello, World!

Process 1955 exited with status = 0 (0x00000000)

2. sysctl

示例代码如下:


static int is_debugger_present(void)
{
    int name[4];
    struct kinfo_proc info;
    size_t info_size = sizeof(info);

    info.kp_proc.p_flag = 0;
 
    name[0] = CTL_KERN;
    name[1] = KERN_PROC;
    name[2] = KERN_PROC_PID;
    name[3] = getpid();
 
    if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {
        perror("sysctl");
        exit(-1);
    }
    return ((info.kp_proc.p_flag & P_TRACED) != 0);
}


if (is_debugger_present()) {
        return 0;
 }
 printf("Hello, World!\n");

效果如下:

 

$ lldb ./DebugMe 
Current executable set to './DebugMe' (x86_64).
(lldb) r
Process 2132 launched: '/.../Build/Products/Debug/DebugMe' (x86_64)
Process 2132 exited with status = 0 (0x00000000) 

 

破解方法:

直接修改该函数返回值:


0000000100000d76 E845000000                      call       _is_debugger_present_100000dc0
0000000100000d7b 3D00000000                      cmp        eax, 0x0

 

$ lldb ./DebugMe 
Current executable set to './DebugMe' (x86_64).
(lldb) b 0x100000d7B
breakpoint set --address 0x100000d7B
Breakpoint created: 1: address = 0x0000000100000d7b, locations = 1
(lldb) r
Process 2260 launched: '/.../Build/Products/Debug/DebugMe' (x86_64)
Process 2260 stopped
* thread #1: tid = 0x1c03, 0x0000000100000d7b DebugMe`main + 27 at main.c:50, stop reason = breakpoint 1.1
......
(lldb) re r -f B rax
     rax = true
(lldb) re w rax 0
(lldb) c
Process 2260 resuming
Hello, World!
Process 2260 exited with status = 0 (0x00000000) 

 

3. GDB/LLDB进程检查

直接简单粗暴一点:


static void stop_debugger_running(void)
{
    system("killall lldb");
    system("killall gdb");
}

    stop_debugger_running();
    printf("Hello, World!\n");

效果如下:

 

$ lldb ./DebugMe 
Current executable set to './DebugMe' (x86_64).
(lldb) r
Process 2518 launched: '/.../Build/Products/Debug/DebugMe' (x86_64)
Terminated: 15

 

 

------------------------------

文章的授權使用CC BY-ND2.5協議。凡是標示“轉載”的文章,均來源於網絡並儘可能標註作者。如果有侵犯您的權益,請及時聯繫刪除或者署名、授權。


Gtalk/Email: cmd4shell  [at]  gmail.com