觀察被 uprobe 修改過的程序
在 SHLUG 月聚上分享了 ftrace, 在介紹 ftrace + uprobe 時, shell 問到有關 instruction 被替換時, debug 用的指令 (int 3) 通常為 2 bytes, 但 nop 則只有一 byte, ftrace 是怎麼處理這個問題的? 這裡實際來看個例子.
準備 C 代碼 (內容不是那麼重要)
/* test.c */
#include <stdio.h>
#include <stdlib.h>
int global_var = 0x12345678;
int main(int argc, char *args[])
{
printf("waiting...\n");
sleep(2);
printf("hello %s, global_var = 0x%x, main()=%p\n", "world", global_var, &main);
return 0;
}
Build 出 executable
$ gcc -o test test.c
匯編如下
$ objdump -d test
[...]
0000000000400596 <main>:
400596: 55 push %rbp
400597: 48 89 e5 mov %rsp,%rbp
40059a: 48 83 ec 10 sub $0x10,%rsp
40059e: 89 7d fc mov %edi,-0x4(%rbp)
4005a1: 48 89 75 f0 mov %rsi,-0x10(%rbp)
4005a5: bf 74 06 40 00 mov $0x400674,%edi
4005aa: e8 a1 fe ff ff callq 400450 <[email protected]>
4005af: bf 02 00 00 00 mov $0x2,%edi
4005b4: b8 00 00 00 00 mov $0x0,%eax
4005b9: e8 d2 fe ff ff callq 400490 <[email protected]>
4005be: 8b 05 4c 04 20 00 mov 0x20044c(%rip),%eax # 600a10 <global_var>
4005c4: 89 c2 mov %eax,%edx
4005c6: be 7f 06 40 00 mov $0x40067f,%esi
4005cb: bf 85 06 40 00 mov $0x400685,%edi
4005d0: b8 00 00 00 00 mov $0x0,%eax
4005d5: e8 86 fe ff ff callq 400460 <[email protected]>
4005da: b8 00 00 00 00 mov $0x0,%eax
4005df: c9 leaveq
4005e0: c3 retq
4005e1: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
4005e8: 00 00 00
4005eb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
[...]
Load address 為 0x400000, 在調用 sleep() 的位置插入 uprobe, 所以 address 為 0x4005b9-0x400000=0x5b9
# cd /sys/kernel/debug/tracing
# echo 'p /home/derekdai/test:0x5b9 sec=%di:s32' >uprobe_events
# echo 1 >events/uprobes/enable
# echo 1 >tracing_on
啟動 test 後立即 stop 以利操作
$ ./test & kill -STOP $!
[1] 17276
用 gdb 將內存中的 main() dump 下來
$ gdb --pid 17276
(gdb) dump memory ./main.dump 0x400596 0x4005eb
比較內容
$ xxd -g1 <main.dump
0000000: 55 48 89 e5 48 83 ec 10 89 7d fc 48 89 75 f0 bf UH..H....}.H.u..
0000010: 78 06 40 00 e8 a1 fe ff ff bf 02 00 00 00 b8 00 [email protected]
0000020: 00 00 00 cc d2 fe ff ff 8b 05 64 04 20 00 b9 96 ..........d. ...
0000030: 05 40 00 89 c2 be 83 06 40 00 bf 90 06 40 00 b8 [email protected]@[email protected]
0000040: 00 00 00 00 e8 81 fe ff ff b8 00 00 00 00 c9 c3 ................
0000050: 66 2e 0f 1f 84
在第三行 (0000020) 處, 第 4 個 byte 起, 原本的 e8 d2 fe ff ff
現在成為了 cc d2 fe ff ff
, 看起來只用到了一個 byte.
可參考 Eli 的 blog