win7 xp vista 下获取进程对应的ip地址和端口信息

// NetStat_Src.cpp : 定义控制台应用程序的入口点。
#include <stdio.h>
#include <tchar.h>

#include <windows.h>
#include <Tlhelp32.h>
#include <winsock.h>

//#include <winsock2.h>
#include <iphlpapi.h>
//#include <ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "iphlpapi.lib")
//---------------------------------------------------------------------------
#define  TCP_TYPE  1
#define  UDP_TYPE 0
// 以下为与TCP相关的结构.
typedef struct tagMIB_TCPEXROW{
    DWORD dwState;              // 连接状态.
    DWORD dwLocalAddr;             // 本地地址.
    DWORD dwLocalPort;           // 本地端口.
    DWORD dwRemoteAddr;            // 远程地址.
    DWORD dwRemotePort;         // 远程端口.
    int dwProcessId;            //进程pid
} MIB_TCPEXROW, *PMIB_TCPEXROW;

typedef struct tagMIB_TCPEXTABLE{
    DWORD dwNumEntries;
    MIB_TCPEXROW table[100];    // 任意大小数组变量.
} MIB_TCPEXTABLE, *PMIB_TCPEXTABLE;


//---------------------------------------------------------------------------
// 以下为与UDP相关的结构.
typedef struct tagMIB_UDPEXROW{
    DWORD dwLocalAddr;             // 本地计算机地址.
    DWORD dwLocalPort;             // 本地计算机端口.
    int dwProcessId;            //进程id
} MIB_UDPEXROW, *PMIB_UDPEXROW;

typedef struct tagMIB_UDPEXTABLE{
    DWORD dwNumEntries;
    MIB_UDPEXROW table[100];    // 任意大小数组变量.
} MIB_UDPEXTABLE, *PMIB_UDPEXTABLE;

//---------------------------------------------------------------------------
// 所用的iphlpapi.dll中的函数原型定义.
//    XP 系统下UDP和TCP表
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
    );

//VISTA 系统下UDP和TCP表
//typedef DWORD (WINAPI *_InternalGetTcpTable2)(
//  PMIB_TCPTABLE2*pTcpTable_Vista,
//  HANDLE heap,
//  DWORD flags
//  );

//修改版本
typedef DWORD (WINAPI *_InternalGetTcpTable2)(
      PMIB_TCPTABLE2 pTcpTable_Vista,
      PULONG SizePointer,
      BOOL Order
      );

typedef DWORD (WINAPI *_InternalGetUdpTableWithOwnerPid)(
  PMIB_UDPEXTABLE *pUdpTable,
  HANDLE heap,
  DWORD flags
  );

//XP系统下 TCP UDP函数指针初始化
static PALLOCATE_AND_GET_TCPEXTABLE_FROM_STACK pAllocateAndGetTcpExTableFromStack = NULL;
static PALLOCATE_AND_GET_UDPEXTABLE_FROM_STACK pAllocateAndGetUdpExTableFromStack = NULL;
static _InternalGetTcpTable2 pGetTcpTable = NULL;
static _InternalGetUdpTableWithOwnerPid pGetUdpTable = NULL;

//全局变量定义区
MIB_TCPTABLE2  g_TcpTable;
//---------------------------------------------------------------------------
//
// 可能的 TCP 端点状态.
//
static char TcpState[][32] = {
    TEXT("???"),
    TEXT("CLOSED"),
    TEXT("LISTENING"),
    TEXT("SYN_SENT"),
    TEXT("SYN_RCVD"),
    TEXT("ESTABLISHED"),
    TEXT("FIN_WAIT1"),
    TEXT("FIN_WAIT2"),
    TEXT("CLOSE_WAIT"),
    TEXT("CLOSING"),
    TEXT("LAST_ACK"),
    TEXT("TIME_WAIT"),
    TEXT("DELETE_TCB")
};

///////////////////////////////函数声明区///////////////////////////////////////////
DWORD GetAllPortByProcessId(BOOL type, DWORD dwProcessId, DWORD * dwAllPort, DWORD dwMaxLen);
//---------------------------------------------------------------------------
//
// 生成IP地址字符串.
//
PCHAR GetIP(unsigned int ipaddr)
{
    static char pIP[20];
    unsigned int nipaddr = htonl(ipaddr);
    sprintf(pIP, "%d.%d.%d.%d",
        (nipaddr >>24) &0xFF,
        (nipaddr>>16) &0xFF,
        (nipaddr>>8) &0xFF,
        (nipaddr)&0xFF);
    return pIP;
}
//---------------------------------------------------------------------------
//
// 由进程号获得全程文件名.
//
char* ProcessPidToName(DWORD ProcessId)
{
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 processEntry = { 0 };
    processEntry.dwSize = sizeof(PROCESSENTRY32);
    static char ProcessName[256];

    lstrcpy(ProcessName, "Idle");
    if (hProcessSnap == INVALID_HANDLE_VALUE)
        return ProcessName;

    BOOL bRet=Process32First(hProcessSnap, &processEntry);

    while(bRet)
    {
        if (processEntry.th32ProcessID == ProcessId)
        {
            MODULEENTRY32 me32 = {0};
            me32.dwSize = sizeof(MODULEENTRY32);
            HANDLE hModuleSnap = CreateToolhelp32Snapshot
                (TH32CS_SNAPMODULE, processEntry.th32ProcessID);

            Module32First(hModuleSnap, &me32); // 获得全程路径.
            lstrcpy(ProcessName, me32.szExePath);
            CloseHandle(hProcessSnap);
            return ProcessName;
        }

        bRet=Process32Next(hProcessSnap, &processEntry);
    }     

    CloseHandle(hProcessSnap);
    return ProcessName;
}


//DWORD GetAllPortByProcessId(BOOL type, DWORD dwProcessId, DWORD * dwAllPort, DWORD dwMaxLen)
//{
//    PMIB_TCPEXTABLE TCPExTable;
//    PMIB_UDPEXTABLE UDPExTable;
//    DWORD dwPortCount = 0;
//
//    if(TCP_TYPE == type)//tcp类型
//    {
//        if(pAllocateAndGetTcpExTableFromStack != NULL)
//        {
//            if(pAllocateAndGetTcpExTableFromStack(&TCPExTable, TRUE, GetProcessHeap(), 0, AF_INET))//倒数第二个参数
//            {
//                if (TCPExTable)
//                {
//                    HeapFree(GetProcessHeap(), 0, TCPExTable);
//                }
//                printf("AllocateAndGetTcpExTableFromStack Error!\n");
//                return dwPortCount;
//            }
//
//            for (UINT i = 0;i<TCPExTable->dwNumEntries;i++)
//            {
//                if (dwProcessId == TCPExTable->table[i].dwProcessId)//找到对应的pid
//                {
//                    if (dwPortCount < dwMaxLen)
//                    {
//                        dwAllPort[dwPortCount] = htons((WORD) TCPExTable->table[i].dwLocalPort);
//                        dwPortCount++;
//                    }
//                }
//            }
//            //销毁
//            if (TCPExTable)
//            {
//                HeapFree(GetProcessHeap(), 0, TCPExTable);
//            }
//            return dwPortCount;
//        }
//        //xp下的隐藏函数获取失败,则采用Vista下的隐藏函数
//        else if (pGetTcpTable != NULL )
//        {
//            if (pGetTcpTable(&TCPExTable,GetProcessHeap(),1))
//            {
//                if (TCPExTable)
//                {
//                    HeapFree(GetProcessHeap(), 0, TCPExTable);
//                }
//                printf("pGetTcpTable Error!.\n");
//                return dwPortCount;
//            }
//
//            //遍历
//            for (UINT i = 0;i<TCPExTable->dwNumEntries;i++)
//            {
//                if (dwProcessId == TCPExTable->table[i].dwProcessId)//找到对应的pid
//                {
//                    if (dwPortCount < dwMaxLen)
//                    {
//                        dwAllPort[dwPortCount] = htons((WORD) TCPExTable->table[i].dwLocalPort);
//                        dwPortCount++;
//                    }
//                }
//            }
//            //销毁
//            if (TCPExTable)
//            {
//                HeapFree(GetProcessHeap(), 0, TCPExTable);
//            }
//            return dwPortCount;
//        }
//
//    }
//    else if (UDP_TYPE == type)
//    {
//        if (pAllocateAndGetUdpExTableFromStack != NULL)
//        {
//            if(pAllocateAndGetUdpExTableFromStack
//                (&UDPExTable, TRUE, GetProcessHeap(), 2, 2 ))
//            {
//                printf("AllocateAndGetUdpExTableFromStack Error!.\n");
//                return dwPortCount;
//            }
//        }
//        else if (pGetUdpTable != NULL)
//        {
//            if (pGetUdpTable(&UDPExTable,GetProcessHeap(),1))
//            {
//                printf("pGetUdpTable Error!.\n");
//                return dwPortCount;
//            }
//        }
//
//        //遍历
//        for (UINT i = 0;i<UDPExTable->dwNumEntries;i++)
//        {
//            if(dwProcessId == UDPExTable->table->dwProcessId)
//            {
//                if (dwPortCount < dwMaxLen)
//                {
//                    dwAllPort[dwPortCount] = htons(UDPExTable->table[i].dwLocalPort);
//                    dwPortCount++;
//                }
//            }
//        }
//
//        //销毁
//        if (UDPExTable)
//        {
//            HeapFree(GetProcessHeap(),0,UDPExTable);
//        }
//        return dwPortCount;
//    }
//    return dwPortCount;
//}
//---------------------------------------------------------------------------
//
// 显示进程、端口和文件名之间的关联.
//
void DisplayPort()
{
    DWORD i;
    PMIB_TCPEXTABLE TCPExTable;
    PMIB_TCPTABLE2 TCPTable2ForWin7;
    PMIB_UDPEXTABLE UDPExTable;
    ULONG ulSize = 0;
    DWORD dwRetVal = 0;

    char szLocalAddress[256];
    char szRemoteAddress[256];

    //xp下的隐藏函数获取
    if(pAllocateAndGetTcpExTableFromStack != NULL && pAllocateAndGetUdpExTableFromStack != NULL)
    {
        //FALSE or TRUE 表明数据是否排序
        if(pAllocateAndGetTcpExTableFromStack(&TCPExTable, FALSE, GetProcessHeap(), 2, AF_INET))//倒数第二个参数
        {
            printf("AllocateAndGetTcpExTableFromStack Error!\n");
            return;
        }

        //FALSE or TRUE 表明数据是否排序
        if(pAllocateAndGetUdpExTableFromStack(&UDPExTable, FALSE, GetProcessHeap(), 2, AF_INET ))
        {
            printf("AllocateAndGetUdpExTableFromStack Error!.\n");
            return;
        }
    }
    //xp下的隐藏函数获取失败,则采用Vista下的隐藏函数
    else if (pGetUdpTable != NULL && pGetTcpTable != NULL)
    {

        //为TCPTable2ForWin7申请内存空间
        /*TCPTable2ForWin7 = (MIB_TCPTABLE2 *)HeapAlloc(GetProcessHeap(), 0, sizeof (MIB_TCPTABLE2));
        ulSize = sizeof (MIB_TCPTABLE);
        if (NULL == TCPTable2ForWin7)
        {
            printf("allocating memory Error\n");
            return ;
        }*/

        //获取UDP的数据信息
        if (pGetUdpTable(&UDPExTable,GetProcessHeap(),1))
        {
            printf("pGetUdpTable Error!.\n");
            return ;
        }
        
        /*if ((dwRetVal = pGetTcpTable(TCPTable2ForWin7, &ulSize, TRUE)) ==ERROR_INSUFFICIENT_BUFFER)
        {
                HeapFree(GetProcessHeap(), 0, TCPTable2ForWin7);
                TCPTable2ForWin7 = (MIB_TCPTABLE2 *)HeapAlloc(GetProcessHeap(), 0, ulSize);
                if (TCPTable2ForWin7 == NULL)
                {
                    printf("Error allocating memory\n");
                    return ;
                }
        }*/
        //调用GetTcpTable函数来获取tcp连接信息
        ulSize = 50;
        pGetTcpTable(&g_TcpTable,&ulSize,TRUE);

         /*if ((dwRetVal = pGetTcpTable(TCPTable2ForWin7, &ulSize, TRUE)) == NO_ERROR)
         {

         }*/
        //if (pGetTcpTable(&TCPTable2ForWin7,GetProcessHeap(),1))//更改存储tcp连接信息的类型
        //{
        //    printf("pGetTcpTable Error!.\n");
        //    return ;
        //}
    }

    printf("%-6s%-22s%-22s%-11s%\n",
        TEXT("Proto"),
        TEXT("Local Address"),
        TEXT("Foreign Address"),
        //TEXT("State"),
        TEXT("Process"));

    ////xp下输出TCPExTable中的网络信息
    //// 获得TCP列表.
    //for( i = 0; i <TCPExTable->dwNumEntries; i++ )
    //{
    //    //构造本地地址
    //    sprintf( szLocalAddress, "%s:%d",
    //        GetIP(TCPExTable->table[i].dwLocalAddr),
    //        htons((WORD) TCPExTable->table[i].dwLocalPort));

    //    //构造远程地址
    //    sprintf( szRemoteAddress, "%s:%d",
    //        GetIP(TCPExTable->table[i].dwRemoteAddr),
    //        htons((WORD)TCPExTable->table[i].dwRemotePort));

    //    //输出信息
    //    printf("%-6s%-22s%-22s%-4d%\n",
    //        TEXT("TCP"),
    //        szLocalAddress,
    //        szRemoteAddress,
    //        //TEXT("ESTABLISHED"),
    //        TCPExTable->table[i].dwProcessId);
    //}

    //Vista 以及Win7下输出网络信息
    // 获得TCP列表.
    for( i = 0; i <g_TcpTable.dwNumEntries; i++ )
    {
        //构造本地地址
        sprintf( szLocalAddress, "%s:%d",
            GetIP(g_TcpTable.table[i].dwLocalAddr),
            htons((WORD) g_TcpTable.table[i].dwLocalPort));

        //构造远程地址
        sprintf( szRemoteAddress, "%s:%d",
            GetIP(g_TcpTable.table[i].dwRemoteAddr),
            htons((WORD)g_TcpTable.table[i].dwRemotePort));

        //输出信息
        printf("%-6s%-22s%-22s%-4d%\n",
            TEXT("TCP"),
            szLocalAddress,
            szRemoteAddress,
            //TEXT("ESTABLISHED"),
            g_TcpTable.table[i].dwOwningPid);
    }
    

    //// 获得UDP列表.
    //for( i = 0; i < UDPExTable->dwNumEntries; i++ )
    //{
    //    sprintf( szLocalAddress, "%s:%d",
    //        GetIP(UDPExTable->table[i].dwLocalAddr),
    //        htons( (WORD)UDPExTable->table[i].dwLocalPort));//本地地址和本地端口

    //    sprintf( szRemoteAddress, "%s","*:*");

    //    printf("%-6s%-22s%-22s%-11d%\n",
    //        TEXT("UDP"),
    //        szLocalAddress,
    //        szRemoteAddress,
    //        //ProcessPidToName(UDPExTable->table[i].dwProcessId),
    //        UDPExTable->table[i].dwProcessId);
    //}
}

int _tmain(int argc, _TCHAR* argv[])
{
    WSADATA WSAData;
    if( WSAStartup(MAKEWORD(1,1), &WSAData ))//sock version 2.2
    {
        printf("WSAStartup error!\n");
        //return -1;
    }

    //加载库
    HMODULE hIpDLL = LoadLibrary( "iphlpapi.dll");
    if ( !hIpDLL)
        printf("LoadLibrary error!\n");
    //return -1;

    //从指定模块获取函数地址 xp
    pAllocateAndGetTcpExTableFromStack =
        (PALLOCATE_AND_GET_TCPEXTABLE_FROM_STACK)
        GetProcAddress( hIpDLL,"AllocateAndGetTcpExTableFromStack");

    pAllocateAndGetUdpExTableFromStack =
        (PALLOCATE_AND_GET_UDPEXTABLE_FROM_STACK)
        GetProcAddress(hIpDLL, "AllocateAndGetUdpExTableFromStack" );

    if (pAllocateAndGetTcpExTableFromStack == NULL
        || pAllocateAndGetUdpExTableFromStack == NULL)
    {
        //vista以后的系统来使用
        pGetTcpTable = (_InternalGetTcpTable2)GetProcAddress(hIpDLL,"GetTcpTable2");//InternalGetTcpTable2

        pGetUdpTable = (_InternalGetUdpTableWithOwnerPid)GetProcAddress(hIpDLL,"InternalGetUdpTableWithOwnerPid");
    }
    
    //使用pAllocateAndGetTcpExTableFromStack和pAllocateAndGetUdpExTableFromStack调用相应函数进行输出
    DisplayPort();

    //释放库
    FreeLibrary(hIpDLL);
    WSACleanup();

    system("pause");
    return 0;
}


你可能感兴趣的:(win7 xp vista 下获取进程对应的ip地址和端口信息)