取消与ptrace的系统调用() [英] Cancel a system call with ptrace()

查看:171
本文介绍了取消与ptrace的系统调用()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于某些安全目的,我使用ptrace函数来获取系统调用数,如果这是一个危险的调用(如10取消链接),我要取消这个系统调用。

For some security purpose, I use ptrace to get the syscall number, and if it's a dangerous call (like 10 for unlink), I want to cancel this syscall.

下面是源$ C ​​$ C的测试程序 del.c 。与编译的gcc -o德尔del.c

Here's the source code for the test program del.c. Compile with gcc -o del del.c.

#include <stdio.h>
#include <stdlib.h>
int main()
{
    remove("/root/abc.out");
    return 0;
}

这里的安全管理器源$ C ​​$ C test.c以。与的gcc -o测试test.c的

#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>

int main()
{
    int i;
    pid_t child;
    int status;
    long orig_eax;
    child = fork();
    if(child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/root/del", "del",  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(child, SIGKILL);
            }
            printf("%d time,"
               "system call %ld\n", i++, orig_eax);
            ptrace(PTRACE_SYSCALL, child, NULL, NULL);
        }
    }
    return 0;
}

abc.out 文件,然后运行测试程序:

Create the abc.out file, then run the test program:

cd /root
touch abc.out
./test

文件 /root/abc.out 应该还是存在的。

我如何落实这一要求?

推荐答案

那么它似乎有时 PTRACE_KILL 并不能很好地工作,你可以使用而不是:

Well it seems that sometimes PTRACE_KILL does not work very well, you can use kill instead:

if (orig_eax == 10)
{
    kill(pid, SIGKILL);
}

修改:我测试我的机器(Ubuntu的内核3.4)与这个程序,一切正常:

EDIT : I test on my machine (Ubuntu kernel 3.4) with this program and all is ok:

#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 
    {
        /* Both wait and waitpid works */
        //wait(NULL);
        waitpid(child, &status, 0);
        orig_eax = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
        /* Tracking execve syscall */
        if (orig_eax == 11)
        {
            /* Both PTRACE_KILL and kill() works on my 3.4.4 Kernel */
            fprintf(stdout, "GOT IT\n");
            //ptrace(PTRACE_KILL, child, NULL, NULL);
            kill(child, SIGKILL);
        }
    }

    return 0;
}

更新:问题是,你正在使用 10 跟踪系统调用,而不是 11 (因为你正在执行的execve 命令),这个code将与您 RM 命令工作:

UPDATE : The problem is that you are using 10 for tracking system call instead of 11(because you are executing execve command), this code will work with your rm command:

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);
}

修改:我尝试这个code和所有wroks精(文件 abc.out 执行后仍存在 CALL_REMOVE

EDIT : I try this code and all wroks fine (the file abc.out still exist after the execution of CALL_REMOVE)

/*
 * REMOVE.c
 * gcc -Wall REMOVE.c -o REMOVE
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv)
{
        /* Both calls work */
        //remove("/root/abc.out");
        unlink("/root/abc.out");

        return 0;
}

/*
 * CALL_REMOVE.c
 * gcc -Wall CALL_REMOVE.c -o CALL_REMOVE
 */

#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;
}

我们得到了这样的输出:

We got this output:

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# 

这篇关于取消与ptrace的系统调用()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆