首页 电脑 电脑学堂 查看内容

XP平台实现端口进程关联

2009-1-19 09:59 564 0

摘要:     在命令行下用命令“netstat”可以查看TCP和UDP的状态,但它不能显示出某个端口是哪个进程打开的,而fport就有这个功能,不仅能够查看端口状态,而且能够查...
关键词: nbsp lstPort szRemoteAddress SetItemText szLocalAddress TCPEXTABLE szLocalName szLocalPort sizeof memset

    在命令行下用命令“netstat”可以查看TCP和UDP的状态,但它不能显示出某个端口是哪个进程打开的,而fport就有这个功能,不仅能够查看端口状态,而且能够查看与端口关联的进程状态。     在Windows XP以上的操作系统,我们很容易实现这个功能,因为操作系统提供了一个名为iphlpapi.dll的动态链接库,它导出了两个函数:AllocateAndGetTcpExTableFromStack和AllocateAndGetUdpExTableFromStack,它们可以输出详尽的信息,包括端口号、地址信息、状态、以及关联进程标识符。(下面的代码来自冉林仓的《Windows API编程》,但它的程序最后有个地方打印错了,UDP信息那里它输出的却是TCP表的内容): void CDlgPort::OnButtonPort() { // 清空列表框 m_lstPort.DeleteAllItems();  // 变量定义 PMIB_TCPEXTABLE TCPExTable; PMIB_UDPEXTABLE UDPExTable; char szProcessname[MAX_PATH]; char szState[32]; char szPid[6]; char szLocalName[MAX_PATH],szRemoteName[MAX_PATH]; char szLocalPort[MAX_PATH],szRemotePort[MAX_PATH]; char szLocalAddress[MAX_PATH * 2],szRemoteAddress[MAX_PATH * 2];  int nRetCode = LoadAPI(); if(!nRetCode) {  MessageBox("LoadLibrary Error!");  return; }  WSADATA ws; if(WSAStartup(MAKEWORD(1,1),&ws)) {  MessageBox("WSAStartup Error!");  return; }  // 读取TCP信息列表 nRetCode = pAllocateAndGetTcpExTableFromStack(&TCPExTable, TRUE, GetProcessHeap(), 2, 2); if(nRetCode) {  MessageBox("AllocateAndGetTcpExTableFromStack Error!");  return; }  // 读取UDP信息列表 nRetCode = pAllocateAndGetUdpExTableFromStack(&UDPExTable, TRUE, GetProcessHeap(), 2, 2); if(nRetCode) {  MessageBox("AllocateAndGetUdpExTableFromStack Error!");  return; }  // 获取TCP信息列表 for(unsigned int i = 0; i < TCPExTable->dwNumEntries; i++) {  memset(szLocalName,0,sizeof(szLocalName));  memset(szLocalPort,0,sizeof(szLocalPort));  memset(szRemoteName,0,sizeof(szRemoteName));  memset(szRemotePort,0,sizeof(szRemotePort));  memset(szPid,0,sizeof(szPid));  memset(szLocalAddress,0,sizeof(szLocalAddress));  memset(szRemoteAddress,0,sizeof(szRemoteAddress));   // 获取本地地址  GetIp(TCPExTable->table[i].dwLocalAddr, szLocalName);  GetPort(TCPExTable->table[i].dwLocalPort, szLocalPort);  sprintf(szLocalAddress,"%s:%s", szLocalName, szLocalPort);   // 获取外部地址  GetIp(TCPExTable->table[i].dwRemoteAddr,szRemoteName);  GetPort(TCPExTable->table[i].dwRemotePort,szRemotePort);  sprintf(szRemoteAddress,"%s:%s", szRemoteName, szRemotePort);   // 获取进程信息  GetProcessNameFromPID(TCPExTable->table[i].dwProcessId, szProcessname);  sprintf(szPid, "%d", TCPExTable->table[i].dwProcessId);   // 获取状态信息  strcpy(szState, TcpState[TCPExTable->table[i].dwState]);   // 输出到列表框  m_lstPort.InsertItem(i, "TCP", NULL);  m_lstPort.SetItemText(i, 1, szProcessname);  m_lstPort.SetItemText(i, 2, szPid);  m_lstPort.SetItemText(i, 3, szLocalAddress);  m_lstPort.SetItemText(i, 4, szRemoteAddress);  m_lstPort.SetItemText(i, 5, szState); }  // 获取UDP信息列表 for(unsigned int j = 0; j < UDPExTable->dwNumEntries; j++) {  memset(szLocalName,0,sizeof(szLocalName));  memset(szLocalPort,0,sizeof(szLocalPort));  memset(szPid,0,sizeof(szPid));  memset(szLocalAddress,0,sizeof(szLocalAddress));  memset(szRemoteAddress,0,sizeof(szRemoteAddress));   // 获取本地地址  GetIp(UDPExTable->table[j].dwLocalAddr, szLocalName);  GetPort(UDPExTable->table[j].dwLocalPort, szLocalPort);  sprintf(szLocalAddress,"%s:%s", szLocalName, szLocalPort);   // UDP与TCP不同,它没有状态信息,外部地址也不确定,因为它不需要 建立一条完整连接  // UDP外部地址  sprintf(szRemoteAddress,"%s","*:*");   // 获取进程信息  GetProcessNameFromPID(UDPExTable->table[j].dwProcessId, szProcessname);  sprintf(szPid, "%d", UDPExTable->table[j].dwProcessId);   // 输出到列表  m_lstPort.InsertItem(j+i, "UDP", NULL);  m_lstPort.SetItemText(j+i, 1, szProcessname);  m_lstPort.SetItemText(j+i, 2, szPid);  m_lstPort.SetItemText(j+i, 3, szLocalAddress);  m_lstPort.SetItemText(j+i, 4, szRemoteAddress);  m_lstPort.SetItemText(j+i, 5, " "); } WSACleanup();}     注意,我们只能得到进程的PID,但只要有了PID,要想得到进程名和完整路径就不在话下了,具体可参考《【科普1】进程(模块)枚举方法谈》一文,程序运行结果如下图所示:
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部