я использую ptrace(PTRACE_POKETEXT, pid, addr, (orig ^ flip_mask));
для того, чтобы изменить данные реального процесса, но как только вызов завершится, сделанные изменения исчезнут, можно ли сохранить PTRACE_POKETEXT
постоянно меняется даже после прекращения ptrace
вызов ?
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);
}
Думаю, ваша главная проблема в том, что вы дважды вызываете ptrace. Первый раз, когда вы пройдете это PTRACE_SINGLESTEP
, который говорит ему, чтобы продолжить только одну инструкцию. Однако сразу после того, как вы позвоните PTRACE_CONT
, что говорит о том, чтобы продолжить до следующего сигнала. Конечным результатом является то, что ваша программа не делает ни одного шага. Это просто работает.
Есть несколько второстепенных проблем с вашим кодом. Во-первых, вы всегда вызываете эти две функции с нулем в качестве аргумента сигнала. По сути, вы маскируете сигналы из программы.
Кроме того, вы вызываете PEEK и POKE TEXT и сохраняете это в переменной с именем «instr». Все это не имеет значения, но они предлагают вам думать, что вы имеете дело с инструкциями. Память, из которой вы читаете это, из rax
, который редко будет указывать на инструкции, а часто может вообще не указывать на что-либо сопоставленное. Это также означает, что вы, вероятно, делаете что-то отличное от того, что, по вашему мнению, вы делаете, что является вероятной причиной вашей проблемы.
Аргументы POKETEXT
не правы. Третий аргумент должен быть адресом, но вы дали instr
, которое является старым значением, а не адресом, с которого оно было прочитано. Чтобы заменить значение, которое вы прочитали, оно должно быть:
ptrace(PTRACE_POKETEXT, child_pid, regs.rax, instr2);
У Шахара Шемеша также есть хорошие моменты в его ответе, но я думаю, что это решает конкретную проблему, о которой вы спрашивали.