1

Using the code below I inject an INT3 at an specific address.

unsigned long data = ptrace(PTRACE_PEEKTEXT, child_pid, 0x4173c0, NULL);
ptrace(PTRACE_POKETEXT, child_pid, 0x4173c0, (data & 0xFFFFFFFFFFFFFF00) | 0xCC);
printf("%lx\n", ptrace(PTRACE_PEEKTEXT, child_pid, 0x4173c0, NULL));

As expected this prints data ending in CC. But latter in my program when I run that last line again

printf("%lx\n", ptrace(PTRACE_PEEKTEXT, child_pid, 0x4173c0, NULL));

It shows the original data without the CC. What is causing my modification to be overwritten? Is the memory being remapped or something? What can I do to prevent this or catch when it happens to reset the INT3?

EDIT:

The relevant section from objdump -d

00000000004173c0 <final_term_get_text_menus_by_code>:
  4173c0:   55                      push   %rbp
  4173c1:   48 89 e5                mov    %rsp,%rbp
  4173c4:   48 c7 45 f0 00 00 00    movq   $0x0,-0x10(%rbp)
  4173cb:   00 
  4173cc:   48 8b 05 dd bd 26 00    mov    0x26bddd(%rip),%rax        # 6831b0 <final_term__text_menus_by_code>
  4173d3:   48 89 45 f0             mov    %rax,-0x10(%rbp)
  4173d7:   48 8b 45 f0             mov    -0x10(%rbp),%rax
  4173db:   48 89 45 f8             mov    %rax,-0x8(%rbp)
  4173df:   48 8b 45 f8             mov    -0x8(%rbp),%rax
  4173e3:   5d                      pop    %rbp
  4173e4:   c3                      retq   
Ava
  • 2,038
  • 3
  • 23
  • 45
  • What kind of data is that in the original program? – Barmar Aug 20 '16 at 20:44
  • The lowpc of a function. The `push` instruction (0x55) in particular. – Ava Aug 20 '16 at 20:47
  • 1
    Very surprising, the text segment shouldn't update by itself. The only thing I can think of is that it's a library being loaded at runtime with `dlopen()`, then being removed and later loaded again. – Barmar Aug 20 '16 at 21:05
  • I don't believe it is. Its simply an executable compiled from Vala. As far as I can tell the change happens inside a call to `g_object_new` if that is any help. – Ava Aug 20 '16 at 21:09
  • Use a GDB watchpoint to monitor the change: `(gdb) awatch 0x4173c0` – Iwillnotexist Idonotexist Aug 21 '16 at 09:59
  • 1
    @IwillnotexistIdonotexist, he cannot use gdb on the area, is he is ptracing it himself. Only one program can ptrace a specific thread at once. – Shachar Shemesh Oct 04 '16 at 06:48
  • @ShacharShemesh True, but then OP could use `(gdb) set detach-on-fork off` to follow multiple children, breakpoint the _tracer_ parent process on `ptrace`, simulate the parent's actions by typing commands in GDB aimed at the _tracee_ child process, and use `watch/awatch` as I recommended. – Iwillnotexist Idonotexist Oct 04 '16 at 07:26

0 Answers0