我在SSLX10.8.5上使用dtruss,试图查看正在运行的应用程序与与其对话的MacOS服务器之间的对话。与Linux上的strace不同,我在输出中没有看到完整的数据字符串,就像程序在文件描述符上执行send和recv一样。
如何让dtruss显示应用程序在SSL服务器上发送和接收的数据?
在有人告诉我要代理到我控制的SSL服务器的连接之前,是的,我知道这个技巧,而且这个特定的应用程序太聪明了,不会让它上当的。
发布于 2013-11-10 22:54:07
dtruss既是为DTrace编写的脚本的优雅示例,也是DTrace可以完成的任务的演示。然而,尽管它与truss或strace的相似之处在相对贫乏的OS上是非常受欢迎的,但我怀疑dtruss从来没有完全替代任何一种。
无论如何,您的问题有点模棱两可:我不确定您是否担心您看到的字符串被截断,还是您根本没有看到sendto()或recvfrom() (DTrace显示的底层接口)的任何字符串。我两个人都来。
首先,DTrace在内核中收集数据;在记录和传输回消费者--通常是dtrace(1)命令之前,使用D语言的copyin()或copyinstr()获取用户土地缓冲区。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 f 0123456789abcdef
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本身不会这样做,如果被要求跟踪非常驻地址,会在运行时产生错误。
https://stackoverflow.com/questions/19883966
复制相似问题