ptrace with PTRACE_PEEKDATA in ubuntu

谁都会走 提交于 2020-01-17 05:44:06

问题


I use ubuntu 16.04 64bit to practice ptrace. When I used PTRACE_PEEKDATA,I'm confused.

the child process execute "ls",I want get the string pass to SYS_write. I get the string address and length in RCX,RDX with PTARECE_PEEKUSER. However when I use PTRACE_PEEKDATA to get string,the result is wrong.

here is result :

mmmmar@acer:$ ls
ptrace  ptrace_1.c  ptrace2  ptrace_2.c  ptrace3  ptrace_3.C  ptrace4  ptrace_4.C
mmmmar@acer:$ ./ptrace4
make write call params 81, 140258879076880, 81
get str: H=���s1�H����
ptrace  ptrace_1.c  ptrace2  ptrace_2.c  ptrace3  ptrace_3.C  ptrace4  ptrace_4.C

here is my code(it run on 64bit ubuntu):

#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/reg.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define LONG_SIZE 8

void getdata(pid_t child,long addr,char *str,long len)
{
    char *laddr = str;
    int i = 0, j = len/LONG_SIZE;
    union u{
        long int val;
        char chars[LONG_SIZE];
    }data;
    while(i<j)
    {
        data.val = ptrace(PTRACE_PEEKDATA,child,addr + i*LONG_SIZE,NULL);
        memcpy(laddr,data.chars,LONG_SIZE);
        laddr += LONG_SIZE;
        ++i;
    }
    j = len % LONG_SIZE;
    if(j != 0)
    {
        data.val = ptrace(PTRACE_PEEKDATA,child,addr + i*LONG_SIZE,NULL);
        memcpy(laddr,data.chars,j);
    }
}

int main()
{
    pid_t child;
    child = fork();
    if(child == 0)
    {
        ptrace(PTRACE_TRACEME,0,NULL,NULL);
        execl("/bin/ls","ls",NULL);
    }
    else
    {
        long orig_rax = 0;
        long params[3] = {0};
        int status = 0;
        char *str;
        int toggle = 0;
        while(1)
        {
            wait(&status);
            if(WIFEXITED(status))
                break;
            orig_rax = ptrace(PTRACE_PEEKUSER,child,8*ORIG_RAX,NULL);
            if(orig_rax == SYS_write)
            {
                if(toggle == 0)
                {
                    toggle = 1;
                    params[0] = ptrace(PTRACE_PEEKUSER,child,8*RBX,NULL);
                    params[1] = ptrace(PTRACE_PEEKUSER,child,8*RCX,NULL);
                    params[2] = ptrace(PTRACE_PEEKUSER,child,8*RDX,NULL);
                    printf("make write call params %ld, %ld, %ld\n",params[0],params[1],params[2]);
                    str = (char*)malloc(params[2]+1);
                    memset(str,0,params[2]+1);
                    getdata(child,params[1],str,params[2]);
                    printf("get str: %s\n",str);
                    free(str);
                }
                else
                {
                    toggle = 0;
                }
            }
            ptrace(PTRACE_SYSCALL,child,NULL,NULL);
        }
    }
    return 0;
}

来源:https://stackoverflow.com/questions/40355632/ptrace-with-ptrace-peekdata-in-ubuntu

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!