我使用ptrace(PTRACE_POKETEXT, pid, addr, (orig ^ flip_mask));来更改实时进程的数据,但是一旦调用终止,所做的更改就会消失,即使在终止ptrace调用之后,是否可以永久保留PTRACE_POKETEXT更改?
void run_pro1 (pid_t child_pid) {
srand(time(0));
int wait_status;
unsigned icounter = 0;
procmsg("debugger started\n");
wait(&wait_status);
while (WIFSTOPPED(wait_status)) {
icounter++;
struct user_regs_struct regs;
ptrace(PTRACE_GETREGS, child_pid, 0, ®s);
unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.rax , 0);
unsigned *instr3 ;
instr3 = &instr;
unsigned instr2 = instr ^ (1UL << (1 << (rand()%32)));
ptrace(PTRACE_POKETEXT, child_pid, instr, instr2);
unsigned *instr4 ;
instr4 = &instr2;
cout<<"addrctn="<< *instr3 <<endl;
cout<<"addrctn="<< *instr4 <<endl;
if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) {
perror("ptrace");
return;
} /* Wait for child to stop on its next instruction */
ptrace(PTRACE_CONT, child_pid, 0, 0);
wait(&wait_status); //break;
}
procmsg("the child executed %u instructions\n", icounter);
}发布于 2016-11-25 16:41:49
我认为,您的主要问题是调用ptrace两次。第一次传递PTRACE_SINGLESTEP时,它告诉它只继续执行一条指令。然而,紧接着调用PTRACE_CONT,它告诉它继续到下一个信号。最终的结果是你的程序根本不是单步执行的。它只是运行而已。
你的代码有几个次要的问题。第一个问题是您总是以零作为信号参数来调用这两个函数。实际上,你是在屏蔽来自程序的信号。
此外,您将调用PEEK和POKE TEXT,并将其存储在一个名为"instr“的变量中。所有这些都没有任何区别,但它们建议您认为您正在处理指令。您从中读取此内容的内存来自rax,它很少指向指令,并且通常根本不指向任何映射的内容。这也意味着你可能正在做一些与你认为你正在做的事情不同的事情,这可能是导致你的问题的原因。
发布于 2016-11-26 00:26:52
POKETEXT的参数是错误的。第三个参数应该是一个地址,但是您给了instr,这是旧值,而不是从中读取它的地址。要替换您读取的值,它应该是:
ptrace(PTRACE_POKETEXT, child_pid, regs.rax, instr2);Schachar Shemesh在他的回答中也有很好的观点,但我认为这解决了您所询问的具体问题。
https://stackoverflow.com/questions/40791120
复制相似问题