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

在上一节中利用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 
#include 

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

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, ®s);
    /* 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  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, ®s);
    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

你可能感兴趣的:(信息安全,编程研发,Linux内存替换)