Linux -- 利用 ptrace 进行代码注入

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

void getdata(pid_t child,long addr,char *str,int len);
void setdata(pid_t child,long addr,char *str,int len);

int main(int argc,char *argv[])
{
    pid_t traced_process = 0;
    long ret = 0;
    struct user_regs_struct regs = {};
    struct user_regs_struct oldregs = {};
    long ins = 0;
    //char code[] = {0xcd,0x80,0xcc,0};//int 0x80,int 3
    char code[] = {0xeb,0x0e,0x68,0x65,0x6c,0x6c,0x6f,0x2c,0x77,0x6f,0x72,0x6c,0x64,0x21,0x0a,0x00,0xe8,0x00,0x00,0x00,0x00,0x41,0x5f,0x49,0x83,0xef,0x13,0xb8,0x01,0x00,0x00,0x00,0xbf,0x02,0x00,0x00,0x00,0x4c,0x89,0xfe,0xba,0x0e,0x00,0x00,0x00,0x0f,0x05,0xcd,0x80,0xcc};// print "hello world"
    int code_len = sizeof(code);
    char backup[sizeof(code)];
    
    if(argc != 2){
        printf("Usage:%s <pid to be traced>\n",argv[0]);
        exit(1);
    }
    
    traced_process = atoi(argv[1]);

    ret = ptrace(PTRACE_ATTACH,traced_process,NULL,NULL);
    if(ret == -1){
        perror("attach error\n");
        exit(1);
    }

    wait(NULL);
    
    ptrace(PTRACE_GETREGS,traced_process,NULL,&regs);
    oldregs = regs;

    getdata(traced_process,regs.rip,backup,code_len);
    setdata(traced_process,regs.rip,code,code_len);

    ptrace(PTRACE_CONT,traced_process,NULL,NULL);

    wait(NULL);

    printf("The process stopped,putting back the original instructions\n");
    printf("Press <enter> to continue\n");
    getchar();
    setdata(traced_process,oldregs.rip,backup,code_len);
    
    ptrace(PTRACE_SETREGS,traced_process,NULL,&oldregs);
    ptrace(PTRACE_DETACH,traced_process,NULL,NULL);
    return 0;
}

void getdata(pid_t child,long addr,char *str,int len)
{
    long data;
    int j = len / sizeof(data);
    int i;
    char *pos = str;
    
    for(i = 0;i<j;i++){
        data = ptrace(PTRACE_PEEKDATA,child,addr + i*sizeof(data),NULL);    
        memcpy(pos,&data,sizeof(data));
        pos += sizeof(data);
    }
    
    j = len %sizeof(data);
    if( j != 0){
        data = ptrace(PTRACE_PEEKDATA,child,addr + i*sizeof(data),NULL);    
        memcpy(pos,&data,j);
    }
}

void setdata(pid_t child,long addr,char *str,int len)
{
    long data;
    int i,j;
    j = len /sizeof(data);
    
    for(i = 0;i<j;i++){
        ptrace(PTRACE_POKEDATA,child,addr + i* sizeof(data),*(long*)(str+i*sizeof(data)));
    }

    j = len % sizeof(data);
    if(j!=0){
        data = ptrace(PTRACE_PEEKDATA,child,addr + i* sizeof(data),NULL);//align
        memcpy(&data,str+i*sizeof(data),j);
        ptrace(PTRACE_POKEDATA,child,addr + i* sizeof(data),data);
    }
}

参考质料:

https://www.linuxjournal.com/article/6100

https://www.linuxjournal.com/article/6210

转载于:https://www.cnblogs.com/r1ng0/p/9585356.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值