我正在尝试读取正在运行的进程的寄存器值。这是我要跟踪的过程的代码:
#include <stdio.h>
int x=0;
int main(){
while(1){
x++;
printf("%d\n",x);
}
return 0;
}
这是我正在使用的ptrace程序:
#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>
void dumpRegs(int pid){
printf("------------------------\n");
struct user_regs_struct regs;
ptrace(PTRACE_GETREGS,pid,NULL, ®s);
printf("rbx: %lx.\n", regs.rbx);
printf("r15: %lx.\n",regs.r15);
printf("r14: %lx.\n",regs.r14);
printf("r13: %lx.\n",regs.r13);
printf("r12: %lx.\n",regs.r12);
printf("rbp: %lx.\n",regs.rbp);
printf("rbx: %lx.\n",regs.rbx);
printf("r11: %lx.\n",regs.r11);
printf("r10: %lx.\n",regs.r10);
printf("r9: %lx.\n",regs.r9);
printf("r8: %lx.\n",regs.r8);
printf("rax: %lx.\n",regs.rax);
printf("rcx: %lx.\n",regs.rcx);
printf("rdx: %lx.\n",regs.rdx);
printf("rsi: %lx.\n",regs.rsi);
printf("rdi: %lx.\n",regs.rdi);
printf("orig_rax: %lx.\n",regs.orig_rax);
printf("rip: %lx.\n",regs.rip);
printf("cs: %lx.\n",regs.cs);
printf("eflags: %lx.\n",regs.eflags);
printf("rsp: %lx.\n",regs.rsp);
printf("ss: %lx.\n",regs.ss);
printf("fs_base: %lx.\n",regs.fs_base);
printf("gs_base: %lx.\n",regs.gs_base);
printf("ds: %lx.\n",regs.ds);
printf("es: %lx.\n",regs.es);
printf("fs: %lx.\n",regs.fs);
printf("gs: %lx.\n",regs.gs);
}
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{
ptrace(PTRACE_SINGLESTEP,pid);
dumpRegs(pid);
}while(getchar()!='q');
ptrace(PTRACE_DETACH,pid);//attach to process
printf("end\n");
return 0;
}
代码可以很好地附加到进程中,我可以知道,因为它停止打印x的值了,我也可以在top和htop中看到它,但是无论do ... while循环有多少次迭代经过,dumpRegs的输出保持不变。我认为即使在这样一个简单的过程中,至少有一些寄存器会改变它们的值,所以我认为我一定做错了。我已经发布了下面的输出示例。
输出:
rbx: 9.
r15: 9.
r14: 7ff23e124600.
r13: 1.
r12: 9.
rbp: 559d2ee03010.
rbx: 9.
r11: 246.
r10: 64.
r9: 8.
r8: 1.
rax: fffffffffffffe00.
rcx: 7ff23de65730.
rdx: 9.
rsi: 559d2ee03010.
rdi: 1.
orig_rax: 1.
rip: 7ff23de65730.
cs: 33.
eflags: 246.
rsp: 7ffcee0ce6f8.
ss: 2b.
fs_base: 7ff23e318700.
gs_base: 0.
ds: 0.
es: 0.
fs: 0.
gs: 0.
我正在64位Debian上运行它,并使用gcc进行编译。
答案 0 :(得分:1)
我这样叫ptrace:
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, ®s);
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;
}