Отслеживайте вызовы функций дочернего процесса, используя /proc/pid/maps и ptrace.Linux

Ответить Пред. темаСлед. тема
Anonymous
 Отслеживайте вызовы функций дочернего процесса, используя /proc/pid/maps и ptrace.

Сообщение Anonymous »

Я пытаюсь написать трассировщик для любой программы на языке C, который отображает все вызываемые функции. Вот пример:

Код: Выделить всё

$./tracer toto.out
+ Entering main at 0x123456789
'I am in Toto's main'
+ Entering toto at 0x123456AAA
'I am in toto'
+ Entering tutu at 0x123456BBB
'I am in tutu'

With toto.out being the simple program:
void tutu(void) {
char msg[] = "I am in tutu\n";
size_t len = strlen(msg);
write(1, msg, len);
}
void toto(void) {
char msg[] = "I am in toto\n";
size_t len = strlen(msg);
write(1, msg, len);
}
int main(void) {
char msg[] = "I am in toto's main\n";
size_t len = strlen(msg);
write(1, msg, len);
toto();
tutu();
return 0;
}
Вот все, что у меня есть на данный момент:
Я уже проанализировал /proc/[child_pid] /maps и перечислил список символов из заголовка ELF64 каждого исполняемого файла:

Код: Выделить всё

59bcd6a5f000-59bcd6a60000 r-xp 00001000 103:04 5244516                   /home/julian/epitech/ftrace/toto.out
76ac3ba28000-76ac3bbbd000 r-xp 00028000 103:04 5899229                   /usr/lib/x86_64-linux-gnu/libc.so.6
76ac3be00000-76ac3be06000 r-xp 00000000 103:04 5948263                   /usr/lib/x86_64-linux-gnu/libgtk3-nocsd.so.0
76ac3c049000-76ac3c04a000 r-xp 00001000 103:04 5907768                   /usr/lib/x86_64-linux-gnu/libpthread.so.0
76ac3c06f000-76ac3c099000 r-xp 00002000 103:04 5898261                   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
Это дает мне следующий список символов (исключая символы, находящиеся в неисполняемых сегментах) благодаря простой математике для получения глобального/сопоставленного адреса символ.

Адрес исполняемого сегмента — смещение сегмента + локальный адрес символа (Elf64_Sym->st_value)


т.е. для toto.out main: 0x59bcd6a5f000 - 0x1000 + 0x128d = 0x59bcd6a628d

Код: Выделить всё

/home/me/epitech/ftrace/toto.out at address 0x000059bcd6a5f000->0x000059bcd6a60000 (offset 0x1000) :
_init
0x000059bcd6a5f000->    0x000059bcd6a5f000 (local addr 0x1000) (size 0x0).
main
0x000059bcd6a5f28d->    0x000059bcd6a5f32d (local addr 0x128d) (size 0xa0).
_start
0x000059bcd6a5f0c0->    0x000059bcd6a5f0e6 (local addr 0x10c0) (size 0x26).
_IO_stdin_used
0x000059bcd6a60000->    0x000059bcd6a60004 (local addr 0x2000) (size 0x4).
tutu
0x000059bcd6a5f1a9->    0x000059bcd6a5f21b (local addr 0x11a9) (size 0x72).
toto
0x000059bcd6a5f21b->    0x000059bcd6a5f28d (local addr 0x121b) (size 0x72).
_fini
0x000059bcd6a5f330->    0x000059bcd6a5f330 (local addr 0x1330) (size 0x0).
frame_dummy
0x000059bcd6a5f1a0->    0x000059bcd6a5f1a0 (local addr 0x11a0) (size 0x0).
__do_global_dtors_aux
0x000059bcd6a5f160->    0x000059bcd6a5f160 (local addr 0x1160) (size 0x0).
register_tm_clones
0x000059bcd6a5f120->    0x000059bcd6a5f120 (local addr 0x1120) (size 0x0).
deregister_tm_clones
0x000059bcd6a5f0f0->    0x000059bcd6a5f0f0 (local addr 0x10f0) (size 0x0).
-/usr/lib/x86_64-linux-gnu/libc.so.6 at address 0x000076ac3ba28000->0x000076ac3bbbd000 (offset 0x28000) :
I cannot find the .strtab to name the symbol...
-/usr/lib/x86_64-linux-gnu/libgtk3-nocsd.so.0 at address 0x000076ac3be00000->0x000076ac3be06000 (offset 0x0) :
Same .strtab issue...
-/usr/lib/x86_64-linux-gnu/libdl.so.2 at address 0x000076ac3c04e000->0x000076ac3c04f000 (offset 0x1000) :
Same...
-/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 at address 0x000076ac3c06f000->0x000076ac3c099000 (offset 0x2000) :
Same...
-/usr/lib/x86_64-linux-gnu/libpthread.so.0 at address 0x000076ac3c049000->0x000076ac3c04a000 (offset 0x1000) :
__libpthread_version_placeholder@GLIBC_2.3.2
0x000076ac3c049100->    0x000076ac3c049105 (local 0x1100) (size 0x5).
..a lot of other irrelevant symbols for toto...
Всякий раз, когда я обнаруживаю вызов рядом с кодом операции с помощью PTRACE_PEEKTEXT, я жду, пока не будет сделан переход, чтобы сравнить регистр RIP с моим списком адресов символов:

Код: Выделить всё

// old rip before call
Re-Extended Instruction Pointer 0x000059bcd6a5f2f9.  (+0x5)

// Debug printing the opcode and the operand when I find a near call (opcode 0xe8) to main
Opcode 0xe8b2 0xfd, 0xff, 0xff, 0xe8, 0x18, 0xff...

// Debug printing the new RIP
Re-Extended Instruction Pointer 0x000059bcd6a5f0b0. (-0x249)

// Current rip in indeed inside toto.out's executable segment but doesn't match toto function address 0x000059bcd6a5f28d
+ Entering unknow at 0x59bcd6a5f080

// Child process prints
'I am in toto'

// Same for tutu, somehow jumps to the same address as toto
Re-Extended Instruction Pointer 0x000059bcd6a5f1ff. (+0x5)
Opcode 0xe87c 0xfe, 0xff, 0xff, 0x90, 0x48, 0x8b...
Re-Extended Instruction Pointer 0x000059bcd6a5f080.  (-0x17f)
+ Entering unknow at 0x59bcd6a5f080
'I am in tutu'
...
Вот для справки objdump toto.out:

Код: Выделить всё

...a lot of symbols omitted for shortening this post...
00000000000011a9 :
11a9:   f3 0f 1e fa             endbr64
11ad:   55                      push   %rbp
11ae:   48 89 e5                mov    %rsp,%rbp
11b1:   48 83 ec 20             sub    $0x20,%rsp
11b5:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
11bc:   00 00
11be:   48 89 45 f8             mov    %rax,-0x8(%rbp)
11c2:   31 c0                   xor    %eax,%eax
11c4:   48 b8 49 20 61 6d 20    movabs $0x206e69206d612049,%rax
11cb:   69 6e 20
11ce:   48 89 45 ea             mov    %rax,-0x16(%rbp)
11d2:   c7 45 f2 74 75 74 75    movl   $0x75747574,-0xe(%rbp)
11d9:   66 c7 45 f6 0a 00       movw   $0xa,-0xa(%rbp)
11df:   48 8d 45 ea             lea    -0x16(%rbp),%rax
11e3:   48 89 c7                mov    %rax,%rdi
11e6:   e8 a5 fe ff ff          call   1090 
11eb:   48 89 45 e0             mov    %rax,-0x20(%rbp)
11ef:   48 8b 55 e0             mov    -0x20(%rbp),%rdx
11f3:   48 8d 45 ea             lea    -0x16(%rbp),%rax
11f7:   48 89 c6                mov    %rax,%rsi
11fa:   bf 01 00 00 00          mov    $0x1,%edi
11ff:   e8 7c fe ff ff          call   1080 
1204:   90                      nop
1205:   48 8b 45 f8             mov    -0x8(%rbp),%rax
1209:   64 48 2b 04 25 28 00    sub    %fs:0x28,%rax
1210:   00 00
1212:   74 05                   je     1219 
1214:   e8 87 fe ff ff          call   10a0 
1219:   c9                      leave
121a:   c3                      ret
000000000000121b :
121b:   f3 0f 1e fa             endbr64
121f:   55                      push   %rbp
1220:   48 89 e5                mov    %rsp,%rbp
1223:   48 83 ec 20             sub    $0x20,%rsp
1227:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
122e:   00 00
1230:   48 89 45 f8             mov    %rax,-0x8(%rbp)
1234:   31 c0                   xor    %eax,%eax
1236:   48 b8 49 20 61 6d 20    movabs $0x206e69206d612049,%rax
123d:   69 6e 20
1240:   48 89 45 ea             mov    %rax,-0x16(%rbp)
1244:   c7 45 f2 74 6f 74 6f    movl   $0x6f746f74,-0xe(%rbp)
124b:   66 c7 45 f6 0a 00       movw   $0xa,-0xa(%rbp)
1251:   48 8d 45 ea             lea    -0x16(%rbp),%rax
1255:   48 89 c7                mov    %rax,%rdi
1258:   e8 33 fe ff ff          call   1090 
125d:   48 89 45 e0             mov    %rax,-0x20(%rbp)
1261:   48 8b 55 e0             mov    -0x20(%rbp),%rdx
1265:   48 8d 45 ea             lea    -0x16(%rbp),%rax
1269:   48 89 c6                mov    %rax,%rsi
126c:   bf 01 00 00 00          mov    $0x1,%edi
1271:   e8 0a fe ff ff          call   1080 
1276:   90                      nop
1277:   48 8b 45 f8             mov    -0x8(%rbp),%rax
127b:   64 48 2b 04 25 28 00    sub    %fs:0x28,%rax
1282:   00 00
1284:   74 05                   je     128b 
1286:   e8 15 fe ff ff          call   10a0 
128b:   c9                      leave
128c:   c3                      ret
000000000000128d :
128d:   f3 0f 1e fa             endbr64
1291:   55                      push   %rbp
1292:   48 89 e5                mov    %rsp,%rbp
1295:   48 83 ec 30             sub    $0x30,%rsp
1299:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
12a0:   00 00
12a2:   48 89 45 f8             mov    %rax,-0x8(%rbp)
12a6:   31 c0                   xor    %eax,%eax
12a8:   48 b8 49 20 61 6d 20    movabs $0x206e69206d612049,%rax
12af:   69 6e 20
12b2:   48 ba 74 6f 74 6f 27    movabs $0x6d2073276f746f74,%rdx
12b9:   73 20 6d
12bc:   48 89 45 e0             mov    %rax,-0x20(%rbp)
12c0:   48 89 55 e8             mov    %rdx,-0x18(%rbp)
12c4:   c7 45 f0 61 69 6e 0a    movl   $0xa6e6961,-0x10(%rbp)
12cb:   c6 45 f4 00             movb   $0x0,-0xc(%rbp)
12cf:   48 8d 45 e0             lea    -0x20(%rbp),%rax
12d3:   48 89 c7                mov    %rax,%rdi
12d6:   e8 b5 fd ff ff          call   1090 
12db:   48 89 45 d8             mov    %rax,-0x28(%rbp)
12df:    48 8b 55 d8             mov    -0x28(%rbp),%rdx
12e3:   48 8d 45 e0             lea    -0x20(%rbp),%rax
12e7:   48 89 c6                mov    %rax,%rsi
12ea:   bf 01 00 00 00          mov    $0x1,%edi
12ef:   e8 8c fd ff ff          call   1080 
12f4:   bf 01 00 00 00          mov    $0x1,%edi
12f9:   e8 b2 fd ff ff          call   10b0 
12fe:   e8 18 ff ff ff          call   121b 
1303:   bf 01 00 00 00          mov    $0x1,%edi
1308:   e8 a3 fd ff ff          call   10b0 
130d:   e8 97 fe ff ff          call   11a9 
1312:   b8 00 00 00 00          mov    $0x0,%eax
1317:   48 8b 55 f8             mov    -0x8(%rbp),%rdx
131b:   64 48 2b 14 25 28 00    sub    %fs:0x28,%rdx
1322:   00 00
1324:   74 05                   je     132b 
1326:   e8 75 fd ff ff          call   10a0 
132b:   c9                      leave
132c:   c3                      ret
Наконец, вот все вопросы, с которыми мне нужна помощь:
  • Я получение правильного глобального адреса?
  • Если адреса верны, почему сообщение печатается, хотя я не в основной функции?
  • Почему RIP перенаправляется на один и тот же адрес ПЕРЕД main, toto и tutu для обеих функций?
Спасибо всем, кто нашел время, чтобы прочитать этот огромный пост и спасибо +1 тем, кто достаточно осведомлен, чтобы ответить

Подробнее здесь: https://stackoverflow.com/questions/783 ... and-ptrace
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Linux»