【发布时间】:2019-02-22 01:32:11
【问题描述】:
程序步骤:
- 通过fork创建子进程并在其中调用execv
- Ptrace 附加到子进程
- 用 ptrace 做点什么
- 与孩子分离
- 执行 gdb -p child_pid
但是当 gdb 启动时,它会写入子进程已经被跟踪。 如何从被跟踪的进程中分离出来,以便被另一个进程跟踪?
执行上述操作的代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/signal.h>
#include <sys/user.h>
#include <sys/ptrace.h>
#define Error(msg) do { perror(msg); exit(0); } while(0)
#define PTRACE_E(req, pid, addr, data) \
do { \
if(ptrace(req, pid, addr, data) < 0) { \
perror(#req); \
exit(0); \
} \
} while(0)
#define BUF_SIZE 16
int main(int argc, char **argv) {
pid_t pid;
struct user_regs_struct regs;
int status;
char buf[BUF_SIZE];
if (argc < 2) {
fprintf(stderr, "Usage: %s <executable> [ARGS]\n", argv[0]);
exit(0);
}
pid = fork();
if(pid < 0) {
Error("fork");
} else if(pid == 0) {
if(execv(argv[1], &argv[1]) < 0)
Error("execv");
}
PTRACE_E(PTRACE_ATTACH, pid, NULL, NULL);
while(wait(&status) && !WIFEXITED(status)) {
PTRACE_E(PTRACE_GETREGS, pid, NULL, ®s);
if(regs.orig_eax == 26 && regs.ebx == PTRACE_TRACEME) {
regs.eax = 0;
PTRACE_E(PTRACE_SETREGS, pid, NULL, ®s);
break;
}
PTRACE_E(PTRACE_SYSCALL, pid, NULL, NULL);
}
ptrace(PTRACE_DETACH, pid, NULL, NULL);
snprintf(buf, BUF_SIZE, "%d", pid);
execl("/usr/bin/gdb", "/usr/bin/gdb", "-p", buf, NULL);
}
【问题讨论】:
-
ptrace(PTRACE_DETACH, pid, 0, sig)? -
@oakad 我用了ptrace_detach,但是不行,所以问了这个问题
-
@Cyberfined 你能把#includes 添加到示例的顶部吗?
-
@jamieguinan 是的,已经完成了。
-
试图在这里重复你的测试用例。你的子命令是什么,它是如何设置 eax 和 ebx 的?