首页
社区
课程
招聘
[分享]仿IDA ,OD 单步调试,使用ptrace 函数实现,单步调试!,并且拿到返回值
发表于: 2021-7-28 17:27 6705

[分享]仿IDA ,OD 单步调试,使用ptrace 函数实现,单步调试!,并且拿到返回值

2021-7-28 17:27
6705
// 自己编写工具,实现ptrace 拿到函数返回值 , 虽然才几行代码,但是鼓捣了,好久 这个代码 ,在linux 中,直接 复制编译就能使用 
 直接编写ptrace 的好处,可以实现,高度的定制化.....内存尽在掌握中..  ,当然自己可以编写 ,类似于inLinHook 相关的代码,是不是很牛逼

 
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/reg.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
int msgText(int x,int y){
	int x2 = 500;
	x2 = 1000+1000;
	return  x+y;
}


int main()
{   pid_t child;
    long orig_eax,eax;
    int status,insyscall;
    struct user_regs_struct regs;

    child = fork();
    if(child == 0) {
        // 告知,父进程,我可以被跟踪...
    	ptrace(PTRACE_TRACEME, 0, NULL, NULL);
    	///.执行相关指令
    	printf("child \n");
    	sleep(2);
    	if (kill(getpid(),SIGSTOP) != 0) {
    		perror("kill sigstop err");
    	}
    	// 子线程,调用
    	int retlust = msgText(100,200);
    	 printf("child end\n");
    }
    sleep(1);
    wait(&status);
    printf("\nstatus=  %d \n", status);
    if(WIFEXITED(status)){
    	printf(" error\n");
    	return 0;
    }
    long orig_code;
    // 需要,记录,是调用前后 ...




    // 执行这一条,指令,程序会发出一个信号,暂停下来!
    orig_code=ptrace(PTRACE_PEEKDATA,child,&msgText,NULL);
    printf("old Code orig_rax= %lx msgText addr= %lx \n",orig_code,&msgText);
    // 修改指令
    // | 有个1 就等于 1
    long new_code = (orig_code & 0xFFFFFFFFFFFFFF00) | 0xcc;
    //printf("new Code orig_rax= %lx \n",new_code);
    // 指令修改完毕..然后把内存写进去
    // 把指令 ,写入到 内存里面
    //     指令 		       调试进程pid 修改的地址     需要修改的指令
    ptrace(PTRACE_POKEDATA,child,&msgText,new_code);
    long change_code=ptrace(PTRACE_PEEKDATA,child,&msgText,NULL);
    printf("change orig_rax= %lx \n",change_code);
    // 恢复程序运行  ,在程序第一行下断点..






    // 华丽的分割线
    // 华丽的分割线
    // 华丽的分割线
    // 华丽的分割线
    // 华丽的分割线
    // 华丽的分割线
    // 华丽的分割线
    // 华丽的分割线





    long temp_trap;
    temp_trap = orig_code;// 把第一次,修改的存贮到 temp
    // flog...
    int codeNumber = 1; // 默认第一次,指令间隔为 1
    int rip_temp=0;  // 计算,上一次指令的间隔...
    // 记录,当前指令间隔


ptrace:
    // 恢复程序运行 ...

    ptrace(PTRACE_CONT ,child,NULL,NULL);
    wait(&status);
    if(WIFEXITED(status)){
    	printf("wait error \n");
    	return 0;
    }
    // 读取寄存器的值...
    ptrace(PTRACE_GETREGS,child,NULL,&regs);
    long result  = regs.rax;
    long arg1 = regs.rdi;
    long arg2 = regs.rsi;
    long rip  = regs.rip;
    printf("Enter arg1 = %lx ,arg2 %lx , rip %lx \n",arg1 ,arg2,rip);
    if(rip == 0){
    	// rip 等于 0   表示,直接可以返回了
    	printf("return %d\n",result);
    	return 0;
    }
    printf("getchar pause...\n");
    getchar();
    // 单步调试
    ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
    goto ptrace;


    printf("Main end!\n");
    return 0;
}




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

收藏
免费 0
支持
分享
最新回复 (2)
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
这个程序虽然得到了正确的结果,但是逻辑上有问题,msgText 的第一条指令push   %rbp 被替换成了0xcc,在执行以后没有恢复为原来的指令
2022-5-15 20:00
0
雪    币: 117
活跃值: (1557)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
对 ,这个确实没有 恢复成功 ,请赐教
2022-5-19 09:48
0
游客
登录 | 注册 方可回帖
返回
//