首页
社区
课程
招聘
[分享][分享]玩转ptrace之x64举例
发表于: 2014-8-24 17:44 6805

[分享][分享]玩转ptrace之x64举例

2014-8-24 17:44
6805
关于ptrace的用法,首推Pradeep Padala 的作品Playing with ptrace:
Playing with ptrace, Part I
Playing with ptrace, Part II

现在用64系统的比较多了,文中的例子都是基于x86的,要想在64位系统上运行,就需适当修改。下面举个例子,大牛不要拍砖啊
 #include <sys/ptrace.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
 #include <sys/reg.h> //#include <linux/user.h>
 #include <sys/syscall.h>
 

 const int long_size = sizeof(long);
 
 void reverse(char *str)
  { 
     int i, j;
     char temp;
     for(i = 0, j = strlen(str) - 2; 
          i <= j; ++i, --j) {
         temp = str[i];
         str[i] = str[j];
         str[j] = temp;
     }
 }
 
 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 * 8, //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 * 8, //i * 4
                           NULL);
         memcpy(laddr, data.chars, j);
     }
     str[len] = '\0';
 }
 
 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;
 
     i = 0;
     j = len / long_size;
     laddr = str;
      while(i < j) {
         memcpy(data.chars, laddr, long_size);
         ptrace(PTRACE_POKEDATA, child, 
                addr + i * 8, data.val); //i * 4
         ++i;
         laddr += long_size;
     }
     j = len % long_size;
      if(j != 0) {
         memcpy(data.chars, laddr, j);
         ptrace(PTRACE_POKEDATA, child, 
                addr + i * 8, data.val); //i * 4
     }
 }

 int main()
  { 
    pid_t child;
    child = fork();
     if(child == 0) {
       ptrace(PTRACE_TRACEME, 0, NULL, NULL);
       execl("/bin/ls", "ls", NULL);
    }
     else {
       long orig_eax;
       long params[3];
       int status;
       char *str, *laddr;
       int toggle = 0;
        while(1) {
          wait(&status);
          if(WIFEXITED(status))
              break;
          orig_eax = ptrace(PTRACE_PEEKUSER, 
                            child, 8 * ORIG_RAX, //4 * ORIG_EAX
                            NULL);
           if(orig_eax == SYS_write) {
              if(toggle == 0) {
                toggle = 1;
                params[0] = ptrace(PTRACE_PEEKUSER, 
                                   child, 8 * RDI, //4 * EBX
                                   NULL);
                params[1] = ptrace(PTRACE_PEEKUSER, 
                                   child, 8 * RSI, //4 * ECX
                                   NULL);
                params[2] = ptrace(PTRACE_PEEKUSER,
                                   child, 8 * RDX, //4 * EDX
                                   NULL);
                str = (char *)calloc((params[2]+1) //
                                  , sizeof(char));
                getdata(child, params[1], str, 
                        params[2]);
                reverse(str);
                putdata(child, params[1], str, 
                        params[2]);
             }
              else {
                toggle = 0;
             }
          }
       ptrace(PTRACE_SYSCALL, child, NULL, NULL);
       }
    }
    return 0;
 }


注释部分是对原代码的修改,测试环境ubuntu 14。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 230
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
另外一个例子,谢谢。
/*****************************
*ptrace testing by lasvegas
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/user.h>
#include <string.h>

void getdata(pid_t child, char* const addr, unsigned long getlen, char* const rbuf);
void setdata(pid_t child, void* const addr, unsigned long setlen, char* const sbuf);

int main(int argc, char** argv)
{
	unsigned long lrmt =0x31;
	char rmt[] ="\xEB\x1D\x5B\x48\xC7\xC0\x01\x00\x00\x00\x48\xC7\xC7\x01\x00\x00\x00\x48\x89\xDE\x48\xC7\xC2\x0D\x00\x00\x00\x0F\x05\xEB\x13\xE8\xDE\xFF\xFF\xFF\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x21\x0A";
	char back[lrmt];
	pid_t child =0;
	struct user_regs_struct reg;
	
	if(argc !=2)
	{
		printf("Usage: %s <target executable file>\n", argv[0]);
		exit(1);
	}
	child =fork();
	if(child ==0)
	{
		ptrace(PTRACE_TRACEME, 0, NULL, 0);
		if(execlp(argv[1], argv[1], NULL) <0)
		{
			printf("Damn for executable execlp(%s,...)\n", argv[1]);
			exit(2);
		}
	}
	else
	{
		printf("Trace on %d...\n", child);
		int status;
		ptrace(PTRACE_ATTACH, child, NULL, NULL);
		wait(&status);
		if(WIFEXITED(status))
		{
			exit(0);
		}
		ptrace(PTRACE_GETREGS, child, NULL, ®);
		getdata(child, (void*)reg.rip, lrmt, back);	
		setdata(child, (void*)reg.rip, lrmt, rmt);
		ptrace(PTRACE_SETREGS, child, NULL, ®);
		ptrace(PTRACE_CONT, child, NULL, NULL);
		wait(NULL);
		//restore
		setdata(child, (void*)reg.rip, lrmt, back);
		ptrace(PTRACE_SETREGS, child, NULL, ®);
		//
		ptrace(PTRACE_DETACH, child, NULL, NULL);
	}
	return 0;													
}
/*
typedef union _mem_byte
{
	long inst;
	char insts[sizeof(long)];
}mem_byte;
*/

void getdata(pid_t child, char* const addr, unsigned long getlen, char* const rbuf)
{
	int i =0, j =0;
	char *laddr =NULL;
	char *lbuf =NULL;
	long mb;
	
	laddr =addr;
	lbuf =rbuf;
	j =getlen/sizeof(long);
	for(i =0; i <j; i++)
	{
		memset(&mb, 0, sizeof(long));
		mb =ptrace(PTRACE_PEEKDATA, child, laddr, NULL);
		memcpy(lbuf, &mb, sizeof(long));
		lbuf +=sizeof(long);
		laddr +=sizeof(long);
	}
	if(getlen %sizeof(long) !=0)
	{
		memset(&mb, 0, sizeof(long));
		mb =ptrace(PTRACE_PEEKDATA, child, laddr, NULL);
		memcpy(lbuf, &mb, getlen %sizeof(long));
	}
	return;
}

void setdata(pid_t child, void* const addr,unsigned long setlen, char* const sbuf)
{
	int i =0, j=0;
	char *laddr =NULL;
	char *lbuf =NULL;
	long mb;
	
	laddr =addr;
	lbuf =sbuf;
	j =setlen/sizeof(long);
	for(i =0; i <j; i++)
	{
		memset(&mb, 0, sizeof(long));
		memcpy(&mb, lbuf, sizeof(long));
		ptrace(PTRACE_POKETEXT, child, laddr, mb);
		laddr +=sizeof(long);
		lbuf +=sizeof(long);
	}
	if(setlen %sizeof(long) !=0)
	{
		memset(&mb, 0, sizeof(long));
		memcpy(&mb, lbuf, setlen%sizeof(long));
		ptrace(PTRACE_POKETEXT, child, laddr, mb);
	}

	return;
}
2014-8-26 11:27
0
雪    币: 101
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
linux上的。。mark
2014-8-26 12:32
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我这两天也在做这个小移植的工作,其实这里主要的问题就是从4B-->8B的问题,还有就是寄存器的对应关系,想知道楼主是怎么对应的?
例如:
ECX<==>RSI
EDX<==>RDX

很久以前学过intel的汇编,现在忘了,请楼主指教
2015-1-20 13:35
0
雪    币: 188
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不错不错,多谢分享。
2015-1-20 13:38
0
游客
登录 | 注册 方可回帖
返回
//