为什么我的ptrace失败了?

时间:2017-08-02 16:41:32

标签: c ptrace

我正在玩ptrace。我有一个简单的程序,它加载我构建的共享库,然后调用其中的两个函数。共享库和主程序都有一些sleep()调用,给我时间来附加。

当程序运行时,我cat / proc / [pid] / maps来确定共享对象的内存在哪里。我想转储加载的文本部分(或我选择的任何其他部分)的内容。

在ptrace程序中,我附加,等待停止,然后尝试PTRACE_PEEKDATA读取内存。 [通过以下更新修复]问题是,我总是收到EIO错误。为什么会这样?这个过程显然存在,如果我这样做,我可以看到它处于't'状态 - 被跟踪阻止。

更新:ESRCH错误已修复(ptrace调用中缺少参数)。我现在正在尝试读取EIO错误。为什么会这样?对ptrace的调用(PTRACE_PEEKDATA ...)似乎是正确的,内存地址在页面对齐的边界上。

主程序(待跟踪)。用-ldl

编译
#include <stdio.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <unistd.h>

typedef int (*Add_t)(int, int);
typedef int (*Mul_t)(int, int);

#define LIB_PATH "./libmylib.so"

int main()
{
    void *pHandle = NULL;
    Mul_t pfnMultiply = NULL;
    Add_t pfnAdd = NULL;
    int a = 5, b = 10;
    int i=0;

    printf("My pid: %u\n", getpid());

    pHandle = dlopen(LIB_PATH, RTLD_NOW);

    if (pHandle == NULL)
    {
        printf("Did not find library!\n");
        return -1;
    }

    pfnMultiply = dlsym(pHandle, "Mul");
    if (pfnMultiply == NULL)
    {
        printf("Could not find multiply symbol");
        return -1;
    }

    pfnAdd = dlsym(pHandle, "Add");
    if (pfnAdd == NULL)
    {
        printf("Could not find add symbol");
        return -1;
    }

    printf("add function address: %p, function pointer address: %x\n", pfnAdd, &pfnAdd);
    printf("mul function address: %p, function pointer address: %x\n", pfnMultiply, &pfnMultiply);

    printf("a + b = %d\n", pfnAdd(a, b));
    printf("a * b = %d\n", pfnMultiply(a, b));

    fflush(stdout);

    for (i=0; i < 120; i++)
    {
        if (i % 10 == 0) { printf("sleeping: %d of %d\n", i, 120); }
        fflush(stdout);
        sleep(1);
    }

    printf("done!\n");
    return 0;
}

库。使用-shared -fPIC编译

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

volatile void *pFunc = 0xAAAAAAAA;
volatile void *pFunc2 = 0xBBBBBBBB;

int Add(int a, int b)
{
    printf("sleeping 200...\n");
    sleep(200);
    return a + b;
}

int Mul(int a, int b)
{
    return a*b;
}

示踪

#include <stdio.h>
#include <stdlib.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char **argv)
{
    unsigned int pid = (unsigned int)atoi(argv[1]);
    unsigned long long searchStart = strtoull(argv[2], NULL, 16);
    long long searchEnd = strtoull(argv[3], NULL, 16);
    long long pos = searchStart;
    int status = 0;



    printf("Attaching to pid: %d\n", pid);

    if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1)
    {
        printf("Ptrace attach failed. Error: %s\n", strerror(errno));
        return -1;
    }
    printf("Attached\n");

    printf("Waiting for pid to stop\n");
    while (1)
    {
        if (waitpid(pid, &status, 0) == -1)
        {
            printf("Waitpid failed. Error: %s\n", strerror(errno));
            return -1;
        }

        if (WIFSTOPPED(status))
        {
            printf("stopped...\n");
            if (WSTOPSIG(status) == SIGSTOP)
            {
                printf("Got SIGSTOP\n");
                break;
            }
            else
            {
                printf("Did not get SIGSTOP");
                ptrace(PTRACE_CONT, pid, 0, WSTOPSIG(status));
            }
        }
    }

    printf("Process stopped\n");

    unsigned long long value = 0;

    printf("Looking at pos: %llx\n", pos);
    value = ptrace(PTRACE_PEEKDATA, pid, (void *)&pos, NULL);
    if (value = -1)
    { 
        printf("Error reading data\n"); 
    }
    else
    {
        printf("Value: %llu\n", value);
    }

    for (pos; pos < searchEnd; pos++) 
    {
        long value = 0;
        errno = 0;
        value = ptrace(PTRACE_PEEKDATA, pid, (void *)&pos, NULL);

        if (errno != 0 && value == -1)
        {
            switch(errno)
            {
                case EBUSY:
                    printf("EBUSY\n");
                    break;
                case EFAULT:
                    printf("EFAULT\n");
                    break;
                case EINVAL:
                    printf("EINVAL\n");
                    break;
                case EIO:
                    printf("EIO\n");
                    break;
                case EPERM:
                    printf("EPERM\n");
                    break;
                case ESRCH:
                    printf("ESRCH\n");
                    break;
            }
            printf("Error: %s\n", strerror(errno));
            break;
        }

        if (value != 0 && value != 0xffffffffffffffff)
        {
            printf("%llx: %llx\n", pos, value);
        }
    }

    printf("done\n");

    sleep(800);
    return 0;
}

输出

user@machine:~/projects/scratch/x86$ ./call
My pid: 30776
add function address: 0x7f371292a805, function pointer address: e87569e8
mul function address: 0x7f371292a862, function pointer address: e87569e0
Me: 0x7f371292a805
sleeping 200...
a + b = 15
a * b = 50
sleeping: 0 of 120
sleeping: 10 of 120
sleeping: 20 of 120
sleeping: 30 of 120
sleeping: 40 of 120
sleeping: 50 of 120
sleeping: 60 of 120
sleeping: 70 of 120
sleeping: 80 of 120
sleeping: 90 of 120
sleeping: 100 of 120
sleeping: 110 of 120
done!

While that program is running...

user@machine:~/projects/scratch$ cat /proc/30776/maps | grep lib
7f371292a000-7f371292b000 r-xp 00000000 00:5c 14136507                   /home/user/projects/scratch/x86/libmylib.so
7f371292b000-7f3712b2a000 ---p 00001000 00:5c 14136507                   /home/user/projects/scratch/x86/libmylib.so
7f3712b2a000-7f3712b2b000 r--p 00000000 00:5c 14136507                   /home/user/projects/scratch/x86/libmylib.so
7f3712b2b000-7f3712b2c000 rw-p 00001000 00:5c 14136507                   /home/user/projects/scratch/x86/libmylib.so
7f3712b2c000-7f3712ce7000 r-xp 00000000 08:01 4200143                    /lib/x86_64-linux-gnu/libc-2.19.so
7f3712ce7000-7f3712ee7000 ---p 001bb000 08:01 4200143                    /lib/x86_64-linux-gnu/libc-2.19.so
7f3712ee7000-7f3712eeb000 r--p 001bb000 08:01 4200143                    /lib/x86_64-linux-gnu/libc-2.19.so
7f3712eeb000-7f3712eed000 rw-p 001bf000 08:01 4200143                    /lib/x86_64-linux-gnu/libc-2.19.so
7f3712ef2000-7f3712ef5000 r-xp 00000000 08:01 4200131                    /lib/x86_64-linux-gnu/libdl-2.19.so
7f3712ef5000-7f37130f4000 ---p 00003000 08:01 4200131                    /lib/x86_64-linux-gnu/libdl-2.19.so
7f37130f4000-7f37130f5000 r--p 00002000 08:01 4200131                    /lib/x86_64-linux-gnu/libdl-2.19.so
7f37130f5000-7f37130f6000 rw-p 00003000 08:01 4200131                    /lib/x86_64-linux-gnu/libdl-2.19.so
7f37130f6000-7f3713119000 r-xp 00000000 08:01 4200137                    /lib/x86_64-linux-gnu/ld-2.19.so
7f3713318000-7f3713319000 r--p 00022000 08:01 4200137                    /lib/x86_64-linux-gnu/ld-2.19.so
7f3713319000-7f371331a000 rw-p 00023000 08:01 4200137                    /lib/x86_64-linux-gnu/ld-2.19.so


user@machine:~/projects/scratch$ ./trace 30776 0x7f371292a000 0x7f371292b000
Attaching to pid: 30776
Ptrace attach failed. Error: Operation not permitted
user@machine:~/projects/scratch$ sudo bash
root@machine:~/projects/scratch# ./trace 30776 0x7f371292a000 0x7f371292b000
Attaching to pid: 30776
Attached
Waiting for pid to stop
stopped...
Got SIGSTOP
Process stopped
Looking at pos: 7f371292a000
Value: 0
ESRCH
Error: No such process
done

0 个答案:

没有答案