動機
接著說說strace與ltrace
strace & ltrace
用法:
strace -e {syscall_want_to_trace,...} {cmd & its args}
ltrace -e {syscall_want_to_trace,...} {cmd & its args}
strace會列出syscall,ltrace是列出lib 的 function call 兩個都是透過ptrace來完成 strace與ltrace是透過ptrace讓發生事件時讓process停下來
ptrace
ptrace是linux的process debug框架,在thread發生下面的case發生時回報給追蹤者(process)
- 收到signal (除了SIGKILL)
- 可以攔截singal,進而轉發、送新signal
- 跑syscall
- 跑到被ptrace參數指定的事件
- 被停下來時
ptrace的流程是
- 登記 (PTRACE_ATTACH, PTRACE_SEIZE, PTRACE_TRACEME(對象是child))
- 設參數
- waitpid
- 取得在意的資料
- PTRACE_CONT
strace需要PTRACE_ATTACH、PTRACE_SYSCALL,所以下面就看這兩項
PTRACE_ATTACH
一開始先登記
- 先到泛用的ptrace syscall
- 之後開始檢查被trace的程式能不能用ptrace,之後替該process上被attach的flag
- 之後根據流程,ptrace會跑到arch-specific的ptrace code
- 但沒有PTRACE_ATTACH事就直接退出
- 這個時候被trace的程式會停下來
PTRACE_SEIZE
與PTRACE_ATTACH
很像,但是PTRACE_SEIZE
不會讓process停下來,PTRACE_ATTACH
會先讓process停下來
所以做PTRACE_SEIZE
的同時可以加上ptrace的參數,PTRACE_ATTACH
因為會先stop,所以要等到對方停了才可以另外加ptrace的參數
PTRACE_SYSCALL
登記好了就讓他跑吧
- 先到泛用的ptrace syscall
- 之後開始檢查被trace的程式能不能用ptrace,之後替該process上被attach的flag
- 之後根據流程,ptrace會跑到arch-specific的ptrace code
- 會call ptrace_resume,之後再thread上打
TIF_SYSCALL_TRACE
的flag
- 會call ptrace_resume,之後再thread上打
- 被trace的程式就開始跑
call system call了
- 在執行system call的程式中會看有沒有
TIF_SYSCALL_TRACE
或是其他在此無關的flag,有就會calltracesys
tracesys
中會看有沒有TIF_SYSCALL_TRACE
,有就callptrace_report_syscall
ptrace_report_syscall
會- 用
SIGTRAP
kill 被trace的程式,讓他停下來 - 執行trace的程式會被通知,就可以看需要的東西了
- 用
ltrace & interrupt 3
如果不想看syscall只想看function call怎麼辦?
interrupt 3 (software breakpoint)
執行後,kernel會用SIGTRAP
kill執行interrupt 3的process
所以這樣ptrace看的到,但要怎麼插入interrupt 3?
PTRACE_POKETEXT & the Procedure Linkage Table (PLT) and the Global Offset Table (GOT)
PTRACE_POKETEXT
可以讓ptrace插入code,可以用他插入interrupt 3
process(ELF)有
- Global Offset Table (GOT): shared lib的位置
- Procedure Linkage Table (PLT): 紀錄怎麼call function的code
- 如果是shared lib就是變成調用linker
- linker找到後會把位置填到GOT,跑function
- 之後的同一個function call就是找GOT上寫的位置直接call function
ltrace = irq 3 + PTRACE_POKETEXT
- 先登記 (attach)
- 查PLT,用
PTRACE_POKETEXT
插入interrupt 3 - 讓被trace的程式開始跑
- 之後就是
SIGTRAP
- 等結束後,再用
PTRACE_POKETEXT
把原本的code插回去
Ref
How does strace work? How does ltrace work? Understanding ptrace ptrace man