[Ptrace]Linux内存替换(三)运行控制

来源:互联网 发布:灵界基友网络剧第一集 编辑:程序博客网 时间:2024/05/18 01:56

在上一节中利用Ptrace实现了B程序对A程序进程信息的读取,下面一个实例将实现B进程对A进程的运行控制,即利用B进程暂停A进程固定时间后再恢复运行(以操作者手动输入任意字符后恢复执行的方式,A始终恢复失败,报段错误,具体原因请好心人指点)。

【环境】
CentOS 6.6 (Final)
Linux version 2.6.32-504.el6.i686
Gcc version 4.4.7 20120313

【A程序:counter.c】

#include <sys/time.h>#include <stdio.h>long long timeum(){    struct timeval tim;     gettimeofday (&tim , NULL);    return (long long)tim.tv_sec*1000000+tim.tv_usec;}int main(){    int i;    long long start,tmp;    start = timeum();    for(i = 0; i < 60; ++i){        printf("My Counter: %d\n", i);        sleep(1);        tmp = timeum();        printf("Time Interval: %lld\n",tmp-start);        start = tmp;    }    return 0;}

gcc -o counter counter.c

【B程序:pause.c】

#include <sys/ptrace.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/user.h>#include <stdio.h>#include <string.h>const int long_size = sizeof(long);void getdata(pid_t child, long addr, char *str, int len){    char *laddr;    int i,j;    union u{        long val;        char chars[long_size];    }data;    i = 0;    j = len / long_size;    laddr = str;    while(i < j){        data.val = ptrace(PTRACE_PEEKDATA, child, addr + i*4, NULL);        memcpy(laddr, data.chars, long_size);        ++i;        laddr += long_size;    }    j = len % long_size;    if(j != 0){        data.val = ptrace(PTRACE_PEEKDATA, child, addr + i*4, NULL);        memcpy(laddr, data.chars, j);    }    str[len] = ' ';}void putdata(pid_t child, long addr, char *str, int len){    char *laddr;    int i,j;    union u{        long val;        char chars[long_size];    }data;    long rst;     i = 0;    j = len / long_size;    laddr = str;    while(i < j){        memcpy(data.chars, laddr, long_size);        rst = ptrace(PTRACE_POKEDATA, child, addr + i*4, data.val);        if (rst < 0) printf("Putdata Failed! \n");        ++i;        laddr += long_size;    }    j = len % long_size;    if(j != 0){        memcpy(data.chars, laddr, j);        rst = ptrace(PTRACE_POKEDATA, child, addr + i*4, data.val);        if (rst < 0) printf("Putdata Failed! \n");    }}int main(int argc, char *argv[]){    pid_t traced_process;    struct user_regs_struct regs, newregs;    /* int 0x80, int3 */    char code[] = {0xcd,0x80,0xcc,0};    //char code[] = {0,0,0,0}; //TEST    char backup[4];    if(argc != 2) {        printf("PID?\n");        return 1;    }    traced_process = atoi(argv[1]);    ptrace(PTRACE_ATTACH, traced_process, NULL, NULL);    int pid = wait(NULL);    printf("Attach Pid: %d\n",pid);    ptrace(PTRACE_GETREGS, traced_process, NULL, &regs);    /* Copy instructions into a backup variable */    getdata(traced_process, regs.eip, backup, 3);    /* Put the breakpoint */    putdata(traced_process, regs.eip, code, 3);    /* Let the process continue and execute         the int 3 instruction */    ptrace(PTRACE_CONT, traced_process, NULL, NULL);    wait(NULL);    sleep(5);    /*Segmentation fault (core dumped)    printf("The process stopped, putting back "            "the original instructions ");    printf("Press <enter> to continue ");    getchar();*/    putdata(traced_process, regs.eip, backup, 3);    //putdata(traced_process, regs.eip, backup, 3);  //TEST    /* Setting the eip back to the original         instruction to let the process continue */    ptrace(PTRACE_SETREGS, traced_process, NULL, &regs);    ptrace(PTRACE_DETACH, traced_process, NULL, NULL);    return 0;}

gcc -o pause pause.c

【执行】
1. run counter
./counter
2. find pid of counter
ps aux | grep counter
3. run pause(root)
./pause %pid%

【结果】
A进程部分输出如下,从时间间隔上可以明显区分出B程序控制A程序运行的时机。
My Counter: 0
1000217
My Counter: 1
6001265
My Counter: 2
1000604
My Counter: 3
1000585
My Counter: 4
6001558
My Counter: 5
1000564

【补充说明】
通过进一步思考,作者认为以上测试只能说明A程序被成功暂停和恢复(只利用ptrace的附加和脱离操作也可实现以上测试结果)。
基于以上测试,作者又做了两项尝试:一是只去除恢复原代码函数(putdata(traced_process, regs.eip, backup, 3)),测试结果发现A程序崩溃,提示Trace/breakpoint trap;二是将替换代码int80/int3 (char code[] = {0,0,0,0})全部修改成零,再去除恢复原代码函数,测试结果发现A程序崩溃,提示Segmentation Fault;
结合以上两项附加测试,作者认为可以充分证明代码注入成功。

【参考】
http://www.cnblogs.com/wangkangluo1/archive/2012/06/05/2535484.html

0 0
原创粉丝点击