良好的Linux TCP/IP监控工具,不使用';不需要根访问权限?
我想为我正在增强的程序调试TCP/IP交互。我没有root访问权限(因此没有tcpdump等),但该应用程序在我自己的id下运行。我可以使用strace等工具拦截系统调用,但是否有值得推荐的替代方案?如果是,为什么-他们提供什么?首选命令行(我的电脑上现在没有安装X服务器:-(),但对GUI也很好奇 理想情况下,它会这样说: app listening on port <portA> app listening on port <portB> client connection #1 accepted on listening port <portA> to local port <portC> from remote <hostX:portXA> app sent #1 <number> bytes "<data dump...>" app received from client #1 <number> bytes "<data dump...>" client #1 closed connection 应用程序侦听端口 应用程序侦听端口 侦听端口到本地端口的客户端连接#1已接受 远在 已发送应用程序#1字节“” 从客户端接收的应用程序#1字节“” 客户端#1关闭连接 我自己会把一个拼凑在一起,但太多的轮子无法重新创造 提前谢谢 更新:paulrubel和ypnos都提出了非常有用的建议…(希望我能接受这两个答案,因为它们是不同的,同样好)。实现Paul建议的LD_预加载拦截的代码如下:良好的Linux TCP/IP监控工具,不使用';不需要根访问权限?,linux,debugging,sockets,networking,tcp,Linux,Debugging,Sockets,Networking,Tcp,我想为我正在增强的程序调试TCP/IP交互。我没有root访问权限(因此没有tcpdump等),但该应用程序在我自己的id下运行。我可以使用strace等工具拦截系统调用,但是否有值得推荐的替代方案?如果是,为什么-他们提供什么?首选命令行(我的电脑上现在没有安装X服务器:-(),但对GUI也很好奇 理想情况下,它会这样说: app listening on port <portA> app listening on port <portB> client conne
// TCP comms trace library
// as per http://www.jayconrod.com/cgi/view_post.py?23
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <dlfcn.h>
typedef ssize_t (*Recv)(int s, void* buf, size_t len, int flags);
ssize_t recv(int s, void* buf, size_t len, int flags)
{
static Recv real = NULL;
if (!real)
real = (Recv)dlsym(RTLD_NEXT, "recv");
fprintf(stderr, "> recv(s '%d', buf %p, len %lld, flags %d)...\n",
s, buf, len, flags);
ssize_t result = real(s, buf, len, flags);
fprintf(stderr, "< recv(s '%d', buf %p, len %lld, flags %d) return %lld\n",
s, buf, len, flags, result);
return result;
}
typedef ssize_t (*Send)(int s, const void* buf, size_t len, int flags);
ssize_t send(int s, const void* buf, size_t len, int flags)
{
static Send real = NULL;
if (!real)
real = (Send)dlsym(RTLD_NEXT, "send");
fprintf(stderr, "> send(s '%d', buf %p, len %lld, flags %d)...\n",
s, buf, len, flags);
ssize_t result = real(s, buf, len, flags);
fprintf(stderr, "< recv(s '%d', buf %p, len %lld, flags %d) return %lld\n",
s, buf, len, flags, result);
return result;
}
typedef int (*Connect)(int s, const struct sockaddr* serv_addr, socklen_t addrlen);
int connect(int s, const struct sockaddr* serv_addr, socklen_t addrlen)
{
static Connect real = NULL;
if (!real)
real = (Connect)dlsym(RTLD_NEXT, "connect");
fprintf(stderr, "> connect(s %d, sockaddr %p, addrlen %d)\n",
s, (void*)serv_addr, addrlen);
int result = real(s, serv_addr, addrlen);
fprintf(stderr, "< connect(s %d, sockaddr %p, addrlen %d) return %d\n",
s, (void*)serv_addr, addrlen, result);
return result;
}
typedef int (*Accept)(int s, const struct sockaddr* serv_addr, socklen_t* addrlen);
int accept(int s, struct sockaddr* serv_addr, socklen_t* addrlen)
{
static Accept real = NULL;
if (!real)
real = (Accept)dlsym(RTLD_NEXT, "accept");
fprintf(stderr, "> accept(s %d, sockaddr %p, addrlen %p)\n",
s, (void*)serv_addr, addrlen);
int result = real(s, serv_addr, addrlen);
fprintf(stderr, "< accept(s %d, sockaddr %p, addrlen %p -> %d) return %d\n",
s, (void*)serv_addr, addrlen, *addrlen, result);
return result;
}
//TCP通信跟踪库
//依照http://www.jayconrod.com/cgi/view_post.py?23
#定义GNU源
#包括
#包括
#包括
#包括
typedef ssize_t(*Recv)(int s,void*buf,size_t len,int标志);
ssize\u t recv(整数s、空*小单位、大小长度、整数标志)
{
静态Recv real=NULL;
如果(!real)
real=(Recv)dlsym(RTLD_NEXT,“Recv”);
fprintf(stderr,“>recv(s'%d',buf%p,len%lld,flags%d)…\n”,
s、 buf、len、旗帜);
ssize_t结果=实(s、buf、len、标志);
fprintf(stderr,“send(s'%d',buf%p,len%lld,flags%d)…\n”,
s、 buf、len、旗帜);
ssize_t结果=实(s、buf、len、标志);
fprintf(stderr,“connect(s%d,sockaddr%p,addrlen%d)\n”,
s、 (无效*)服务地址,地址);
int result=real(s,serv_addr,addrlen);
fprintf(stderr,“接受(s%d,sockaddr%p,addrlen%p)\n”,
s、 (无效*)服务地址,地址);
int result=real(s,serv_addr,addrlen);
fprintf(stderr,“%d)返回%d\n”,
s、 (无效*)服务地址,地址,*地址,结果);
返回结果;
}
即使您使用与受害者程序相同的用户id运行,也无法拦截套接字连接
你需要做的是
有一个想法,可能有点像打苍蝇的大锤,就是使用。基本上,你包装了一个系统调用,连接并发送,这对你来说似乎是一个很好的起点,并记录在将数据传递给真正的调用之前看到的参数。2是个好主意,谢谢。1在我的特殊情况下,它太复杂了-整个想法是为了得到一些数据与程序无关的东西,因为我不太信任它。更一般地说,像strace和gdb这样的程序作为控制进程启动(或附加到正在运行的程序),并且似乎做类似的事情,所以我怀疑你关于“无法拦截”的说法是否正确。感谢您的帮助和想法。在程序调用write()之前,您可以告诉调试器查看输出缓冲区变量,如果这也算是拦截。但是,除此之外,您在内核空间中,如果不是root,则无法调试内核空间。strace只在内核空间的边界上运行,并且在内核中对此有特定的支持。如果您找到任何用于“套接字调试”的内核接口,告诉我。我所知道的都没有。我非常喜欢tcpdump,所以我有以下建议:从另一台机器上进行交互,在那里你可以运行tcpdump(甚至wireshark),或者要求通过sudo运行tcpdump。@stefaanv:很好的建议,但是在一家(大银行)公司环境我有Buckley的机会在任何共享框上都能找到它…如果有人愚蠢到可以ftp到该框上,那么就很容易嗅探密码。如果我有自己的UNIX工作站,那么可能会有机会。这是一个非常好的建议。我实现了它(虽然很长,但会增加上面的问题).仅供参考/我已决定接受ypnos的回答,因为他获得的选票较少,所以我会公平对待你们的帮助。我已经向你们两位表示感谢,并相信你们就是上面的代码。再次感谢。