- ptrace PTRACE_ATTACH可以附加到目标进程上,对其进行调试。
- 反调试的方式
跟踪自己:因为,一个进程在同一时间只能被一个进程跟踪。如果进程在启动时,就调用ptrace PTRACE_TRACEME跟踪了自己。那么这个进程将无法被其他进程附加。
如果对方调用的是exec()的时候,暂停你的程序呢。这个时候调用ptrace跟踪。也就是在你调用ptrace之前。
- 这种情况很好解决,通过调用ptrace(PTRACE_TRACEME, 0);如果返回值为小于0的值,也就是调用失败,这说明当前进程正在被跟踪,那么这时退出进程即可。代码如下。
if (ptrace(PTRACE_TRACEME, 0) < 0) {
printf("This process is being traced!");
exit(-1);
}
如果,对方劫持你的链接库呢,修改你调用的ptrace函数。
- 这也简单,自己封装一个ptrace系统调用即可。
ptrace系统调用编号:
32位:26
64位:101 (64位代码如下)
static __always_inline volatile long ptrace(
enum __ptrace_request request,
pid_t pid,
void *addr,
void *data)
{
__asm__ volatile(
"mov %0, %%rdi\n"
"mov %1, %%rsi\n"
"mov %2, %%rdx\n"
"mov %3, %%r10\n"
"mov $0x65, %%rax\n"
"syscall"
:
: "g"(request), "g"(pid), "g"(addr), "g"(data));
asm("mov %%rax, %0"
: "=r"(ret));
return (void *)ret;
}
当然以上的方式能成功防御反调试,是必须保证,可执行文件没被修改的情况下有效的。如果可执行文件被静态反汇编。找到ptrace系统调用的代码将其替换成无效指令。那反调试策略将失效,所以,这样的保护还是得基于,可执行代码的加密。比如Ryan O’Neill的一个项目中可执行代码保护方式,将静态代码加密,执行时,动态的解析没一个调用的函数的二进制代码,调用完成后,又进行加密。这样大大的增大了解密难度。
Ryan O’Neill是《Linux 二进制分析》的作者。也是我的第一本安全学习书。