2013-11-09 32 views
0

我在MacOS X 10.8.5上使用dtruss試圖查看正在運行的應用程序與它正在與之交談的SSL服務器之間的對話。與Linux上的strace不同,我沒有在輸出中看到完整的數據串,就像我期望的那樣,因爲程序在文件描述符上執行了sendrecv如何在dtruss輸出中看到完整的字符串?

如何讓dtruss向我顯示應用程序使用SSL服務器發送和接收的數據?

在任何人告訴我代理到SSL服務器的連接之前,我控制,是的,我知道這個訣竅,並且沒有這個特定的應用程序太聰明而不適合它。

回答

2

dtruss既是爲DTrace編寫的腳本的典型示例,也是DTrace可以完成的演示。然而,雖然它與trussstrace的相似性在相對貧瘠的OS X上是深受歡迎的,但我懷疑dtruss從來不打算完全替代它們。

在任何情況下,您的問題都有點含糊不清:我不確定您是否擔心您看到的字符串被截斷或者根本沒有看到任何字符串,因爲sendto()recvfrom()(基礎由DTrace顯示的接口)。我會解決這兩個問題。

首先,DTrace在內核中收集數據;在記錄並傳輸回消費者之前,通常使用D語言的copyin()copyinstr()獲得用戶地緩衝區,通常是dtrace(1)命令。 DTrace要求在編譯時知道其內核緩衝區大小,並因此對字符串的其他不可預知的長度施加限制。該限制默認爲256字節;如果你看到截斷,那麼你可以通過添加,例如更改限制,

#pragma D option strsize=512 

下面dtruss現有pragma。其次,dtruss是硬編碼,以瞭解各種系統調用的格式要求。您在其輸出中看不到任何緩衝區解釋爲sendto()recvfrom(),因爲它們沒有在源中明確處理。沒有什麼能阻止你找到合適的添加他們的地方,但你可以代替編寫自己的腳本:

bash-3.2# cat sr.d 
#pragma D option rawbytes 

syscall::sendto:entry, 
syscall::recvfrom:entry 
/pid == $target/ 
{ 
    self->bufp = arg1; 
    self->size = arg2; 
} 

syscall::sendto:return, 
syscall::recvfrom:return 
/pid == $target && self->bufp && self->size/ 
{ 
    printf("%s():\n", probefunc); 
    tracemem(copyin(self->bufp, self->size), 64); 
    printf("\n"); 
    self->bufp = self->size = NULL; 
} 
bash-3.2# dtrace -qs ./sr.d -p 16988 
sendto(): 

      0 1 2 3 4 5 6 7 8 9 a b c d e fabcdef 
     0: 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 hello........... 
     10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 
     20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 
     30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 

^C 

bash-3.2# 

注意的是,對於字符串,我們有義務提供tracemem()的使用DTrace的硬性限制數據記錄緩衝區。如果極限很少被接近,那麼這會產生令人不愉快的結果,即輸出可能是壓倒性的並且大部分是多餘的。如果你知道你正在尋找字符串,那麼你可以簡單地使用copyinstr();如果你有一個更現代的DTrace執行比我的OS X 10.6.8,那麼你可能會發現,你可以寫

tracemem(copyin(self->bufp, self->size), 64, self->size); 

,其中第二個參數是仍然字節記錄但數數的硬性限制字節顯示受限於可選的第三個參數。

最後,請注意,用戶地址地址記錄在系統調用的入口處,但僅用於出口。這是一個常見的習慣用法,如果有必要,系統調用可以使數據發生故障--DTrace本身不會這樣做,如果要求跟蹤非常駐地址,它將在運行時產生錯誤。

相關問題