PID和端口关系映射学习

来源:互联网 发布:android php 编辑:程序博客网 时间:2024/06/06 07:40

        程序功能是获取系统进程ID和TCP/UDP端口的映射关系,利用的是AllocateAndGetTcpExTableFromStack和AllocateAndGetUdpExTableFromStack函数,这两个函数在WIN7之后已经不适用了,虽然有些过时,但对我这种菜鸟学习基础来说还是很有帮助的。

        PS:如果想获取进程名与端口的映射关系要麻烦些,需要自己写个函数,通过进程枚举,通过PID获取进程名,由于前面的学习记录已经有相关的了,就不重复实现了。还有个函数PsLookupProcessByProcessId拒说可以直接实现这个功能,不过我的水平太烂,没有调试成功。

代码如下,基本都是拷过来的:

#include "stdafx.h"
#include <windows.h>
#include<iprtrmib.h>
#include<iphlpapi.h>
#pragma comment(lib,"ws2_32.lib")

typedef struct tagMIB_TCPEXROW{
        DWORD dwState;//TCP连接状态
        DWORD dwLocalAddr;//本地IP地址
        DWORD dwLocalPort;//打开的本地端口
        DWORD dwRemoteAddr;//远程IP地址
        DWORD dwRemotePort;//远程端口号
        DWORD dwProcessId;//进程标识
}MIB_TCPEXROW,*PMIB_TCPEXROW;


typedef struct tagMIB_TCPEXTABLE{
       DWORD dwNumEntries;
       MIB_TCPEXROW table[ANY_SIZE];
}MIB_TCPEXTABLE,*PMIB_TCPEXTABLE;

typedef struct tagMIB_UDPEXROW{
      DWORD dwLocalAddr;//本地IP地址
      DWORD dwLocalPort;//打开的本地端口
      DWORD dwProcessId;//进程标识
}MIB_UDPEXROW,*PMIB_UDPEXROW;


typedef struct tagMIB_UDPEXTABLE{
      DWORD dwNumEntries;
      MIB_UDPEXROW table[ANY_SIZE];
}MIB_UDPEXTABLE,*PMIB_UDPEXTABLE;


//函数声明:
typedef DWORD(WINAPI *PALLOCATE_AND_GET_TCPEXTABLE_FROM_STACK)( PMIB_TCPEXTABLE *pTcpTable,  BOOL bOrder,  HANDLE heap,  DWORD zero, DWORD flags);

typedef DWORD(WINAPI *PALLOCATE_AND_GET_UDPEXTABLE_FROM_STACK)( PMIB_UDPEXTABLE *pUdpTable,  BOOL bOrder,  HANDLE heap,  DWORD zero, DWORD flags);

//定义函数事例入口指针,初始化为NULL
static PALLOCATE_AND_GET_TCPEXTABLE_FROM_STACK pAllocateAndGetTcpExTableFromStack=NULL;
static PALLOCATE_AND_GET_UDPEXTABLE_FROM_STACK pAllocateAndGetUdpExTableFromStack=NULL;
static char TcpState[][32]={"???", "CLOSED", "LISTENING", "SYN_SENT", "SYN_RCVD", "ESTABLISHED", "FIN_WAIT1" ,"FIN_WAIT2" ,"CLOSE_WAIT", "CLOSING", "LAST_ACK" ,"TIME_WAIT" ,"DELETE_TCB"};

char pPort[255];                  //这里不能声明为函数内部的局部变量,否则返回主函数后指针会不稳定。
PCHAR GetPort(unsigned int port)
{
       sprintf(pPort,"%d",htons((WORD)port));
       return pPort;
}

char pIP[255];               //此处同上,开始写程序时定义在里面了,结果返回的内容老是不对,找了半天才发现问题所在,我真是太菜了 。
PCHAR GetIp(unsigned int ipaddr)
{
      unsigned int nipaddr;
      nipaddr=htonl(ipaddr);
      sprintf(pIP,"%d.%d.%d.%d",(nipaddr>>24)&0xFF,(nipaddr>>16)&0xFF,(nipaddr>>8)&0xFF,(nipaddr)&0xFF);
      return pIP;
}


//加载DLL的API函数
BOOL LoadAPI()
{
      pAllocateAndGetTcpExTableFromStack=(PALLOCATE_AND_GET_TCPEXTABLE_FROM_STACK)GetProcAddress(LoadLibrary(L"iphlpapi.dll"),"AllocateAndGetTcpExTableFromStack");
     if(!pAllocateAndGetTcpExTableFromStack)
              return FALSE;
     pAllocateAndGetUdpExTableFromStack=(PALLOCATE_AND_GET_UDPEXTABLE_FROM_STACK)GetProcAddress(LoadLibrary(L"iphlpapi.dll"),"AllocateAndGetUdpExTableFromStack");
     if(!pAllocateAndGetUdpExTableFromStack)
             return FALSE;
     return TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
     int nRetCode;
     DWORD i;
     WSADATA WSAData;
     PMIB_TCPEXTABLE TCPExTable;
     PMIB_UDPEXTABLE UDPExTable;
     char szLocalAddress[512],szRemoteAddress[512];
     nRetCode=LoadAPI();
     if(nRetCode==FALSE)
     {
           printf("Loadlibrary error!\n");
           return 0;
     }  
     if(WSAStartup(MAKEWORD(1,1),&WSAData))   //MAKEWORD,宏,高32位(左)+低32位(右)
    {
          printf("WSAStartup error!\n");      //WSAStartup,即WSA(异步套接字)的启动命令。
          return 0;
    }
    nRetCode=pAllocateAndGetTcpExTableFromStack(&TCPExTable,TRUE,GetProcessHeap(),2,2);
    if(nRetCode)
    {
          printf("AllocateAndGetTcpExTableFromStackError!\n");
          return 0;
    }
    nRetCode=pAllocateAndGetUdpExTableFromStack(&UDPExTable,TRUE,GetProcessHeap(),2,2);
    if(nRetCode)
    {
         printf("AllocateAndGetUdpExTableFromStackError!.\n");
         return 0;
    }  
//GetTCPList
        printf("%-6s%-22s%-22s%-11s%s\n","Proto","LocalAddress","ForeignAddress","State","PID");
        for(i=0;i<TCPExTable->dwNumEntries;i++)
        {
            sprintf(szLocalAddress,"%s:%s",GetIp(TCPExTable->table[i].dwLocalAddr),GetPort(TCPExTable->table[i].dwLocalPort));
            sprintf(szRemoteAddress,"%s:%s",GetIp(TCPExTable->table[i].dwRemoteAddr),GetPort(TCPExTable->table[i].dwRemotePort));
            printf("%-6s%-22s%-22s%-11s:%d\n","TCP",szLocalAddress,szRemoteAddress,TcpState[TCPExTable->table[i].dwState],TCPExTable->table[i].dwProcessId);
        }
//GetUDPList
       for(i=0;i<UDPExTable->dwNumEntries;i++)
       {
            sprintf(szLocalAddress,"%s:%s",GetIp(UDPExTable->table[i].dwLocalAddr),GetPort(UDPExTable->table[i].dwLocalPort));
            sprintf(szRemoteAddress,"%s","*:*");
            printf("%-6s%-22s%-33s:%d\n","UDP",szLocalAddress,szRemoteAddress,TCPExTable->table[i].dwProcessId);
       }
       WSACleanup();  //终止Winsock 2 DLL (Ws2_32.dll) 的使用.
       getchar();
       return 0;
}

原创粉丝点击