SIG_IGN 不适用于 PTRACE_TRACEME?
SIG_IGN does not work with PTRACE_TRACEME?
我正在使用 ptrace
方法测试反调试解决方案
int main(int argc, char **argv) {
void *handle;
long (*go)(enum __ptrace_request request, pid_t pid);
// get a handle to the library that contains 'ptrace'
handle = dlopen ("libc.so", RTLD_LAZY);
// reference to the dynamically-resolved function 'ptrace'
go = dlsym(handle, "ptrace");
if (go(PTRACE_TRACEME, 0) < 0) {
puts("being traced");
exit(1);
}
puts("not being traced");
// cleanup
dlclose(handle);
return 0;
}
当我执行它时,我总是遇到停止错误,
# ./a.out
not being traced
[4]+ Stopped ./a.out
然后我尝试像这样添加 SIGSTOP 处理程序
int main(int argc, char **argv) {
signal(SIGSTOP, SIG_IGN);
它仍然遇到停止的错误,有什么想法吗?
这是正在发生的事情:
handle = dlopen ("libc.so", RTLD_LAZY)
将 NULL 分配给 handle
。 Dlopen 失败是因为在您的 GNU/Linux 发行版(和大多数其他现代发行版)上 lib.so
不是共享库 - 它是 GNU ld 脚本。
dlopen ("libc.so.6", RTLD_LAZY)
会成功。
go = dlsym(handle, "ptrace")
成功(!)。使用 glibc,可以将 NULL 指针作为句柄参数传递给 dlsym,因为 glibc 恰好将 ((void *) 0)
用作 RTLD_DEFAULT
。
这通常不适用于其他系统。 FreeBSD 的 dlsym 使用 ((void *) -2)
作为 RTLD_DEFAULT
,如果您使用 NULL 句柄调用 dlsym,它将在调用 dlsym 的可执行文件或共享库中查找符号。
go(PTRACE_TRACEME, 0)
成功。
dlclose(handle)
不能容忍 NULL 句柄,它会导致段错误,因此引发 SIGSEGV
信号。
由于正在跟踪进程,因此接收到信号会导致进程停止(挂起)。在 shell 中键入 jobs
将显示使进程停止的信号。
代码
signal(SIGSTOP, SIG_IGN);
不会真的做任何事情。 SIGSTOP
是无法捕捉、忽略或保留的信号之一。
我正在使用 ptrace
方法测试反调试解决方案
int main(int argc, char **argv) {
void *handle;
long (*go)(enum __ptrace_request request, pid_t pid);
// get a handle to the library that contains 'ptrace'
handle = dlopen ("libc.so", RTLD_LAZY);
// reference to the dynamically-resolved function 'ptrace'
go = dlsym(handle, "ptrace");
if (go(PTRACE_TRACEME, 0) < 0) {
puts("being traced");
exit(1);
}
puts("not being traced");
// cleanup
dlclose(handle);
return 0;
}
当我执行它时,我总是遇到停止错误,
# ./a.out
not being traced
[4]+ Stopped ./a.out
然后我尝试像这样添加 SIGSTOP 处理程序
int main(int argc, char **argv) {
signal(SIGSTOP, SIG_IGN);
它仍然遇到停止的错误,有什么想法吗?
这是正在发生的事情:
handle = dlopen ("libc.so", RTLD_LAZY)
将 NULL 分配给handle
。 Dlopen 失败是因为在您的 GNU/Linux 发行版(和大多数其他现代发行版)上lib.so
不是共享库 - 它是 GNU ld 脚本。
dlopen ("libc.so.6", RTLD_LAZY)
会成功。go = dlsym(handle, "ptrace")
成功(!)。使用 glibc,可以将 NULL 指针作为句柄参数传递给 dlsym,因为 glibc 恰好将((void *) 0)
用作RTLD_DEFAULT
。
这通常不适用于其他系统。 FreeBSD 的 dlsym 使用((void *) -2)
作为RTLD_DEFAULT
,如果您使用 NULL 句柄调用 dlsym,它将在调用 dlsym 的可执行文件或共享库中查找符号。go(PTRACE_TRACEME, 0)
成功。dlclose(handle)
不能容忍 NULL 句柄,它会导致段错误,因此引发SIGSEGV
信号。由于正在跟踪进程,因此接收到信号会导致进程停止(挂起)。在 shell 中键入
jobs
将显示使进程停止的信号。
代码
signal(SIGSTOP, SIG_IGN);
不会真的做任何事情。 SIGSTOP
是无法捕捉、忽略或保留的信号之一。