C 跟踪进程的寄存器值为';t改变

C 跟踪进程的寄存器值为';t改变,c,linux,ptrace,C,Linux,Ptrace,我试图读取正在运行的进程的寄存器值。这是我试图跟踪的流程的代码: #include <stdio.h> int x=0; int main(){ while(1){ x++; printf("%d\n",x); } return 0; } 我在64位Debian上运行它,并使用gcc进行编译。我是这样调用ptrace的: ptrace(PTRACE_SINGLESTEP,pid); ptrace(PTRACE_SINGL

我试图读取正在运行的进程的寄存器值。这是我试图跟踪的流程的代码:

#include <stdio.h>

int x=0;

int main(){
    while(1){
        x++;
        printf("%d\n",x);
    }
    return 0;
}

我在64位Debian上运行它,并使用gcc进行编译。

我是这样调用ptrace的:

ptrace(PTRACE_SINGLESTEP,pid);
ptrace(PTRACE_SINGLESTEP,pid,NULL,NULL);
但它需要这样称呼:

ptrace(PTRACE_SINGLESTEP,pid);
ptrace(PTRACE_SINGLESTEP,pid,NULL,NULL);
如果不包含NULL参数,PTRACE_SINGLESTEP将返回-1。 在分离之前,我还添加了一个PTRACE_CONT

以下是更新的代码:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ptrace.h>
#include <sys/reg.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/wait.h>

int x=0;

void dumpRegs(int pid){
    printf("------------------------\n");
    printf("%d\n",x);
    struct user_regs_struct regs;
    ptrace(PTRACE_GETREGS,pid,NULL, &regs);
    printf("cs: %lx.\n",regs.cs);
    printf("ds: %lx.\n",regs.ds);
    printf("eflags: %lx.\n",regs.eflags);
    printf("es: %lx.\n",regs.es);
    printf("fs: %lx.\n",regs.fs);
    printf("fs_base: %lx.\n",regs.fs_base);
    printf("gs: %lx.\n",regs.gs);
    printf("gs_base: %lx.\n",regs.gs_base);
    printf("orig_rax: %lx.\n",regs.orig_rax);
    printf("r10: %lx.\n",regs.r10);
    printf("r11: %lx.\n",regs.r11);
    printf("r12: %lx.\n",regs.r12);
    printf("r13: %lx.\n",regs.r13);
    printf("r14: %lx.\n",regs.r14);
    printf("r15: %lx.\n",regs.r15);
    printf("r8: %lx.\n",regs.r8);
    printf("r9: %lx.\n",regs.r9);
    printf("rax: %lx.\n",regs.rax);
    printf("rbp: %lx.\n",regs.rbp);
    printf("rbx: %lx.\n", regs.rbx);
    printf("rbx: %lx.\n",regs.rbx);
    printf("rcx: %lx.\n",regs.rcx);
    printf("rdi: %lx.\n",regs.rdi);
    printf("rdx: %lx.\n",regs.rdx);
    printf("rip: %lx.\n",regs.rip);
    printf("rsi: %lx.\n",regs.rsi);
    printf("rsp: %lx.\n",regs.rsp);
    printf("ss: %lx.\n",regs.ss);
}

int main(int argc, char **argv){
    printf("begin\n");
    int pid=atoi(argv[1]);//the pid of the process
    int status;
    ptrace(PTRACE_ATTACH,pid);//attach to process
    waitpid(pid,&status,0);

    do{
        x++;
        printf("%d",ptrace(PTRACE_SINGLESTEP,pid,NULL,NULL));
        dumpRegs(pid);
    }while(getchar()!='q');

    printf("%d",ptrace(PTRACE_CONT,pid,NULL,NULL));
    ptrace(PTRACE_DETACH,pid);//attach to process
    printf("end\n");

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int x=0;
无效转储寄存器(整数pid){
printf(“---------------------------\n”);
printf(“%d\n”,x);
结构用户\u注册表\u结构注册表;
ptrace(ptrace_GETREGS、pid、NULL和regs);
printf(“cs:%lx.\n”,regs.cs);
printf(“ds:%lx.\n”,regs.ds);
printf(“eflags:%lx.\n”,regs.eflags);
printf(“es:%lx.\n”,regs.es);
printf(“fs:%lx.\n”,regs.fs);
printf(“fs_base:%lx.\n”,regs.fs_base);
printf(“gs:%lx.\n”,regs.gs);
printf(“gs\u base:%lx.\n”,regs.gs\u base);
printf(“orig_-rax:%lx.\n”,regs.orig_-rax);
printf(“r10:%lx.\n”,regs.r10);
printf(“r11:%lx.\n”,regs.r11);
printf(“r12:%lx.\n”,regs.r12);
printf(“r13:%lx.\n”,regs.r13);
printf(“r14:%lx.\n”,regs.r14);
printf(“r15:%lx.\n”,regs.r15);
printf(“r8:%lx.\n”,regs.r8);
printf(“r9:%lx.\n”,regs.r9);
printf(“rax:%lx.\n”,regs.rax);
printf(“rbp:%lx.\n”,regs.rbp);
printf(“rbx:%lx.\n”,regs.rbx);
printf(“rbx:%lx.\n”,regs.rbx);
printf(“rcx:%lx.\n”,regs.rcx);
printf(“rdi:%lx.\n”,regs.rdi);
printf(“rdx:%lx.\n”,regs.rdx);
printf(“rip:%lx.\n”,regs.rip);
printf(“rsi:%lx.\n”,regs.rsi);
printf(“rsp:%lx.\n”,regs.rsp);
printf(“ss:%lx.\n”,regs.ss);
}
int main(int argc,字符**argv){
printf(“begin\n”);
int pid=atoi(argv[1]);//进程的pid
智力状态;
ptrace(ptrace_ATTACH,pid);//附加到进程
waitpid(pid和status,0);
做{
x++;
printf(“%d”,ptrace(ptrace_SINGLESTEP,pid,NULL,NULL));
转储文件(pid);
}while(getchar()!='q');
printf(“%d”,ptrace(ptrace_CONT,pid,NULL,NULL));
ptrace(ptrace_DETACH,pid);//附加到进程
printf(“end\n”);
返回0;
}

您似乎没有跟踪系统调用是否成功。你应该广泛地这样做,以确保打电话成功。除此之外,我想我帮不了你。谢谢!显然,PTRACE_SINGLESTEP请求返回了一个错误值(-1),因此我必须研究是什么导致它失败。是否需要向子级发送SIGCONT信号,以便它在停止后继续?我不确定这是PTU单步赛的哪一边。无论如何,至少你有事情要调查。祝你好运谢谢你的帮助!我已经解决了我的问题,并在下面发布了答案。你可能会觉得有趣。它是关于一个多线程进程的,包括一个示例程序。