避開 PTRACE_TRACME 反追蹤技巧
在前文 [
ptrace / SIGTRAP / int3 的關聯] 提到藉由檢查 ptrace(PTRACE_TRACEME, ...) 的技巧,確認該 process 是否被 GDB 所追蹤,而做出必要的回應。不過,這不表示就沒轍,事實上,還是能透過 gdb 來追蹤。
先來看看之前的範例程式碼:
嘗試編譯並使用 gdb:
$ gcc -o ptraceme{,.c} && gdb ptraceme
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
...
(gdb) r
Starting program: /tmp/ptraceme
No, I don't want to serve you.
由於執行到無窮迴圈,我們只好按下 Ctrl-C 結束:
^C
Program received signal SIGINT, Interrupt.
0x08048451 in main ()
讓我們來觀察反組譯的程式碼:(筆者的環境是 x86 32-bit)
0x0804843c <+40>: call 0x8048350 <ptrace@plt>
0x08048441 <+45>: test %eax,%eax
0x08048443 <+47>: jns 0x8048453 <main+63>
0x08048445 <+49>: movl $0x8048540,(%esp)
0x0804844c <+56>: call 0x8048320 <puts@plt>
=> 0x08048451 <+61>: jmp 0x8048451 <main+61>
顯然 "jmp 0x8048451" 就是目前的無窮迴圈,但我們往上可見 call ptrace 這個調用 ptrace 系統呼叫的動作,接下來一行就是關鍵:
0x0804843c <+40>: call 0x8048350 <ptrace@plt>
0x08048441 <+45>: test %eax,%eax
使用 test 指令來查對 ptrace() 系統呼叫的傳回值 (置於 %eax 暫存器),那也意味著,如果我們能在此設定中斷點,並且強制更改 %eax 內含值,就可跳過此反追蹤技巧。咱們來試試看:
(gdb) b *0x08048441
Breakpoint 1 at 0x8048441
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /tmp/ptraceme
Breakpoint 1, 0x08048441 in main ()
如我們預期,停在 test 指令那邊,這時設定 %eax 暫存器並繼續執行:
(gdb) set $eax=0
(gdb) c
Continuing.
Yes, real routines go here
[Inferior 1 (process 13899) exited normally]
終於見到 "Yes, real routines go here" 字樣,而且該 process 也正常執行完畢。我們可編撰以下的 GDB script,來自動化上述操作,原理就是檢查 ptrace 系統呼叫的參數與修改回傳值。建立檔案 "gdb-ptrace" 如下:
set $ptrace_bpnum = 0
define ptrace-hook
catch syscall ptrace
commands
if ($ebx == 0)
set $eax = 0
continue
end
end
set $ptrace_bpnum = $bpnum
end
define ptrace-unhook
if ($ptrace_bpnum != 0)
delete $ptrace_bpnum
set $ptrace_bpnum = 0
end
end
我們定義兩個自訂指令: ptrace-hook 與 ptrace-unhook,前者的技巧在於 "catch syscall ptrace",這時要求 GDB 檢查參數。離開 GDB 後,載入該 GDB script 並重新執行 ptraceme 執行檔:
$ gdb -x gdb-ptrace ptraceme
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
...
鍵入自訂指令並執行:
(gdb) ptrace-hook
Catchpoint 1 (syscall 'ptrace' [26])
(gdb) r
Starting program: /tmp/ptraceme
Catchpoint 1 (call to syscall 'ptrace'), 0x001110c2 in ?? ()
from /lib/ld-linux.so.2
Catchpoint 1 (returned from syscall 'ptrace'), 0x001110c2 in ?? ()
from /lib/ld-linux.so.2
Yes, real routines go here
[Inferior 1 (process 13973) exited normally]
由上可見,Catchpoint 1 就是 syscall 'ptrace',我們順利的攔截並改變程式執行流程。
由 jserv 發表於
11:25 PM
|
迴響 (0)
「開放原始碼作為新事業: 台灣本土經驗談」簡報上線

本月適逢台灣區開放源碼界的盛會 [
COSCUP],除了過去分享 [
0xlab] 這一年來的 [
開發進度] 外,今年嘗試調整演講的型態,以「開放原始碼作為新事業: 台灣本土經驗談」為題作 keynote 分享,簡報已上線,請參考: [
0xlab-experience-2011.pdf]
一開始先分享 [
0xlab] 成立時的背景,為了搭 Google Android 的順風車,著實付出頗多代價,特別對我們這些對 open source 有著天真憧憬的人來說。中間則是以一位系統開發者的角度,看 Android 特有的生態系統 (ecosystem) 有了哪些本質上的轉變,而我們則以與其他團隊或知名開放原始碼專案合作的方式,試著去找到一個切入點:專注於 Android 系統層面的軟體品質。過程中,也以開放原始碼的形式,釋出了若干專案,可參考 [
0xlab::Technologies]。另外也分享了一個小插曲,當出國在 ARM 的長官前面忐忑不安地作簡報,腦袋真是一片空白,只好在終端機前面敲 "git log | grep 0xlab",說明 Android 已正式收錄多項來自我們的貢獻,沒想到竟然意外成功地拿到合約。
最近發生很多事,因而習得一些法務與會計的觀念。只要真心去克服問題,終究還是能解決的,也要感謝客戶長久以來給我們的支持。不過長久以來的壓力與挫折,竟然使得自己在面對台下一千人的 keynote speech 時,不小心沒控制情緒,就哽咽起來、語無倫次,實在很抱歉。感謝您的蒞臨指教,也歡迎交流。
由 jserv 發表於
1:39 PM
|
迴響 (0)