Linux 系統gdb等調試器,都是通過ptrace系統調用實現。Android加固中,ptrace自身防止調試器附加是一種常用的反調試手段。
調試時一般需要手工在ptrace處下斷點,通過修改ptrace返回值過掉反調試。下面提供另一種思路,降低手工操作復雜度:
測試代碼(反調試程序):
#include <stdio.h>
#include <stdlib.h>
#include <sys/ptrace.h>
void a()
{
if (ptrace(PTRACE_TRACEME, 0, 1, 0) == -1)
{
printf("don't trace me !!\n");
exit(1);
}
// normal execution
puts("hello girl.");
}
int main()
{
a();
return 0;
}
編寫輔助庫:
/* Type of the REQUEST argument to `ptrace.' */
enum __ptrace_request
{
PTRACE_TRACEME = 0,
#define PT_TRACE_ME PTRACE_TRACEME
};
long ptrace(enum __ptrace_request request, unsigned long pid,
void *addr, void *data)
{
return 0;
}
gcc -shared -fPIC helper.c -o helper.so 編譯動態庫。
設置環境變量:
export LD_PRELOAD=$PWD/helper.so
測試:
(gdb) r
Starting program: /home/kiiim/lab/a.out
hello girl.
During startup program exited normally.
以上,將helper.so放到APP的libs目錄,並設置LD_PRELOAD環境變量,即可繞過所有ptrace的反調試。
也可以patch一些其它函數,如open函數我們需要patch后不影響其正常功能:
#define _GNU_SOURCE
#include <dlfcn.h>
typedef int (*_open)(const char *pathname, int flags);
int open(const char *pathname, int flags, ...)
{
/* Some evil injected code goes here. */
_open fake_open;
fake_open = (_open)dlsym(RTLD_NEXT,"open");
return fake_open(pathname,flags);
}