看起来有时候PTRACE_KILL
不能很好地工作,您可以使用kill
代替:
if (orig_eax == 10)
{
kill(pid, SIGKILL);
}
编辑:我在我的电脑上进行了测试(Ubuntu内核3.4),使用这个程序一切正常:
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/reg.h>
#include <stdio.h>
int main(int argc, char **argv)
{
pid_t child;
long orig_eax;
int status;
child = fork();
if(child == 0)
{
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("/bin/ls", "ls", NULL);
}
else
{
waitpid(child, &status, 0);
orig_eax = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
if (orig_eax == 11)
{
fprintf(stdout, "GOT IT\n");
kill(child, SIGKILL);
}
}
return 0;
}
更新:问题在于您使用了10
来跟踪系统调用,而不是11
(因为您执行了execve
命令),这段代码将适用于您的rm
命令:
if (orig_eax == 11)
{
/* Both PTRACE_KILL and kill() works on my 3.4.4 Kernel */
fprintf(stdout, "INSIDE THE TRAP, FILE WILL NOT BE REMOVED\n");
ptrace(PTRACE_KILL, child, NULL, NULL);
//kill(child, SIGKILL);
}
编辑: 我尝试了这段代码,一切都正常(在执行CALL_REMOVE
后,文件abc.out
仍然存在)。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
unlink("/root/abc.out");
return 0;
}
#include <signal.h>
#include <syscall.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <sys/user.h>
#include <sys/reg.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
int i;
pid_t child;
int status;
long orig_eax;
int kill_ret = 0;
child = fork();
if(child == 0)
{
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("/root/REMOVE", "REMOVE", NULL);
}
else
{
i = 0;
while(1)
{
wait(&status);
if (WIFEXITED(status) || WIFSIGNALED(status) )
break;
orig_eax = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
if (orig_eax == 10)
{
fprintf(stderr, "Got it\n");
kill_ret = kill(child, SIGKILL);
if (kill_ret == -1)
{
fprintf(stderr, "Failed to kill ---> %s\n", strerror(errno));
}
}
printf("%d time, system call %ld\n", i++, orig_eax);
ptrace(PTRACE_SYSCALL, child, NULL, NULL);
}
}
return 0;
}
我们得到了这个输出:
root@UnixServer:/root# ll
total 28K
-rw-r--r-- 1 root root 6 2012-08-18 19:37 abc.out
-rw-r--r-- 1 root root 1023 2012-08-18 19:39 CALL_REMOVE.c
-rw-r--r-- 1 root root 213 2012-08-18 19:39 REMOVE.c
-rwxr-xr-x 1 root root 7,3K 2012-08-18 19:39 CALL_REMOVE
-rwxr-xr-x 1 root root 7,0K 2012-08-18 19:39 REMOVE
root@UnixServer:/root# ./CALL_REMOVE
0 time, system call 11
1 time, system call 45
2 time, system call 45
3 time, system call 33
4 time, system call 33
5 time, system call 192
6 time, system call 192
7 time, system call 33
8 time, system call 33
9 time, system call 5
10 time, system call 5
11 time, system call 197
12 time, system call 197
13 time, system call 192
14 time, system call 192
15 time, system call 6
16 time, system call 6
17 time, system call 33
18 time, system call 33
19 time, system call 5
20 time, system call 5
21 time, system call 3
22 time, system call 3
23 time, system call 197
24 time, system call 197
25 time, system call 192
26 time, system call 192
27 time, system call 192
28 time, system call 192
29 time, system call 192
30 time, system call 192
31 time, system call 6
32 time, system call 6
33 time, system call 192
34 time, system call 192
35 time, system call 243
36 time, system call 243
37 time, system call 125
38 time, system call 125
39 time, system call 125
40 time, system call 125
41 time, system call 125
42 time, system call 125
43 time, system call 91
44 time, system call 91
Got it
45 time, system call 10
root@UnixServer:/root# ll
total 28K
-rw-r--r-- 1 root root 6 2012-08-18 19:37 abc.out
-rw-r--r-- 1 root root 1023 2012-08-18 19:39 CALL_REMOVE.c
-rw-r--r-- 1 root root 213 2012-08-18 19:39 REMOVE.c
-rwxr-xr-x 1 root root 7,3K 2012-08-18 19:39 CALL_REMOVE
-rwxr-xr-x 1 root root 7,0K 2012-08-18 19:39 REMOVE
root@UnixServer:/root#
waitpid()
将使当前进程等待直到分叉进程终止。因此,您将无法停止系统调用。当您能够获取系统调用代码时,分叉进程已经执行了它。 - arothwaitpid()
能够工作,我的问题是如何取消这个系统调用? - laifjei