1

I'm using ptrace(PTRACE_POKETEXT, pid, addr, (orig ^ flip_mask)); in order to change a live process's data, but as soon as the call is terminated the changes that have been made disappear, would it be possible to keep the PTRACE_POKETEXT changes permanently even after terminating the ptrace call ?

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, &regs);       
        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);
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • The changes shouldn't disappear. – Barmar Nov 24 '16 at 16:41
  • The only reason it would disappear is because the process you poked reassigned the variable. You would have to change the code of the process to prevent that. – Barmar Nov 24 '16 at 16:42
  • Can you show the code of the process you're tracing and how you're using `ptrace`? – Barmar Nov 24 '16 at 16:45
  • Dear Barmar, thank you very much for your reply, I just posted the code for the tracer process tracing a child pid – Yasser Nezzari Nov 24 '16 at 18:51
  • What do you mean by "permanently"? –  Nov 24 '16 at 20:03
  • I meant the bit-flips that I'm injecting will be saved, so when I run again the child process it will still have flipped addresses giving wrong outputs as expected (trying to simulate space radiation effects) – Yasser Nezzari Nov 25 '16 at 12:30

2 Answers2

1

Your main problem, I think, is that you are calling ptrace twice. The first time you pass it PTRACE_SINGLESTEP, which tells it to continue just one instruction. Immediately after, however, you call PTRACE_CONT, which tells it to continue until the next signal. The end result is that your program doesn't single step at all. It just runs.

There are a couple of secondary problems with your code. The first is that you are always calling these two functions with zero as the signal argument. Effectively, you are masking signals from the program.

Also, you are calling PEEK and POKE TEXT, and storing this in a variable called "instr". All of those don't make any difference, but they suggest you think you are dealing with instructions. The memory you read this from is from rax, which will rarely point at instructions, and might often not point at anything mapped at all. This, too, means you are probably doing something different than what you think you are doing, which is a probable cause of your problem.

Shachar Shemesh
  • 8,193
  • 6
  • 25
  • 57
  • Dear Shacshar, could you please write your suggestions in code, would really appreciate it, because I tried what you said but still the child process doesn't show any changes – Yasser Nezzari Dec 07 '16 at 12:33
1

The arguments to POKETEXT are wrong. The 3rd argument should be an address, but you gave instr, which is the old value, not the address from which it was read. To replace the value that you read, it should be:

ptrace(PTRACE_POKETEXT, child_pid, regs.rax, instr2);

Schachar Shemesh also has good points in his answer, but I think this addresses the specific problem you asked about.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Dear Barmar, I have tried your suggestion, but still the changes haven't been saved, the child process runs without problems – Yasser Nezzari Dec 07 '16 at 12:32
  • I don't know what the `RAX` register is used for, are you sure that's the right address to be poking? – Barmar Dec 07 '16 at 16:10
  • I tried to modify the following registers:AL/AH/AX/EAX/RAX: Accumulator BL/BH/BX/EBX/RBX: Base index (for use with arrays) CL/CH/CX/ECX/RCX: Counter (for use with loops and strings) DL/DH/DX/EDX/RDX: Extend the precision of the accumulator (e.g. combine 32-bit EAX and EDX for 64-bit integer operations in 32-bit code) .CS: Code DS: Data SS: Stack ES: Extra data FS: Extra data #2 GS: Extra data #3 – Yasser Nezzari Dec 07 '16 at 17:13
  • If you want to modify the program, you should use the Program Counter register as the address. – Barmar Dec 07 '16 at 17:18