// RemoteThread.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <excpt.h>
#include <psapi.h>
#pragma comment(lib, "Wsock32.lib")
#pragma comment(lib, "Psapi.lib")
using namespace std;
#define ANY_SIZE 1
enum TcpOrUdp
{
TcpType = 0,
UdpType
};
// TCP
typedef struct
{
DWORD dwState; //连接状态
DWORD dwLocalAddr; //本地地址
DWORD dwLocalPort; //本地端口
DWORD dwRemoteAddr; //远程地址
DWORD dwRemotePort; //远程端口
DWORD dwProcessId; //进程ID
} MIB_TCPEXROW, * PMIB_TCPEXROW;
typedef struct
{
DWORD dwNumEntries;
MIB_TCPEXROW table[255];
} MIB_TCPEXTABLE, * PMIB_TCPEXTABLE;
typedef struct
{
DWORD dwState; //连接状态
DWORD dwLocalAddr; //本地地址
DWORD dwLocalPort; //本地端口
DWORD dwRemoteAddr; //远程地址
DWORD dwRemotePort; //远程端口
DWORD dwProcessId; //进程标识
DWORD Unknown; //待定标识
}MIB_TCPEXROW_VISTA, * PMIB_TCPEXROW_VISTA;
typedef struct
{
DWORD dwNumEntries;
MIB_TCPEXROW_VISTA table[ANY_SIZE];
}MIB_TCPEXTABLE_VISTA, * PMIB_TCPEXTABLE_VISTA;
typedef DWORD(WINAPI* PFNInternalGetTcpTable2)(
PMIB_TCPEXTABLE_VISTA * pTcpTable_Vista,
HANDLE heap,
DWORD flags
);
typedef DWORD(WINAPI* PFNAllocateAndGetTcpExTableFromStack)(
PMIB_TCPEXTABLE* pTcpTable,
BOOL bOrder,
HANDLE heap,
DWORD zero,
DWORD flags
);
// UDP
typedef struct tagMIB_UDPEXROW {
DWORD dwLocalAddr; // 本地计算机地址.
DWORD dwLocalPort; // 本地计算机端口.
DWORD dwProcessId;
} MIB_UDPEXROW, * PMIB_UDPEXROW;
typedef struct tagMIB_UDPEXTABLE {
DWORD dwNumEntries;
MIB_UDPEXROW table[100]; // 任意大小数组变量.
} MIB_UDPEXTABLE, * PMIB_UDPEXTABLE;
typedef DWORD(WINAPI* PFNAllocateAndGetUdpExTableFromStack)(
PVOID* ppUdpTable,
BOOL bOrder,
HANDLE hHeap,
DWORD dwFlags,
DWORD dwFamily
);
typedef DWORD(WINAPI* PFNInternalGetUdpTableWithOwnerPid)(
PMIB_UDPEXTABLE* pUdpTable,
HANDLE heap,
DWORD flags
);
DWORD GetAllPortByProcessId(TcpOrUdp type, DWORD dwProcessId, DWORD * dwAllPort, DWORD dwMaxLen)
{
DWORD dwPortCount = 0;
HMODULE hModule = LoadLibraryW(L"iphlpapi.dll");
if (hModule == NULL)
{
return dwPortCount;
}
if(type == TcpType)
{
// 表明查询的是 UDP 信息
PFNAllocateAndGetTcpExTableFromStack pAllocateAndGetTcpExTableFromStack;
pAllocateAndGetTcpExTableFromStack =
(PFNAllocateAndGetTcpExTableFromStack)GetProcAddress(hModule, "AllocateAndGetTcpExTableFromStack");
if (pAllocateAndGetTcpExTableFromStack != NULL)
{
// 表明为 XP 或者 Server 2003 操作系统
PMIB_TCPEXTABLE pTcpExTable = NULL;
if (pAllocateAndGetTcpExTableFromStack(&pTcpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0)
{
if (pTcpExTable)
{
HeapFree(GetProcessHeap(), 0, pTcpExTable);
}
FreeLibrary(hModule);
hModule = NULL;
return dwPortCount;
}
for (UINT i = 0; i < pTcpExTable->dwNumEntries; i++)
{
// 过滤掉数据,只获取我们要查询的进程的 Port 信息
if(dwProcessId == pTcpExTable->table[i].dwProcessId)
{
if(dwPortCount < dwMaxLen)
{
dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort);
dwPortCount++;
}
}
}
if (pTcpExTable)
{
HeapFree(GetProcessHeap(), 0, pTcpExTable);
}
FreeLibrary(hModule);
hModule = NULL;
return dwPortCount;
}
else
{
// 表明为 Vista 或者 7 操作系统
PMIB_TCPEXTABLE_VISTA pTcpExTable = NULL;
PFNInternalGetTcpTable2 pInternalGetTcpTable2 =
(PFNInternalGetTcpTable2)GetProcAddress(hModule, "InternalGetTcpTable2");
if (pInternalGetTcpTable2 == NULL)
{
if (pTcpExTable)
{
HeapFree(GetProcessHeap(), 0, pTcpExTable);
}
FreeLibrary(hModule);
hModule = NULL;
return dwPortCount;
}
if (pInternalGetTcpTable2(&pTcpExTable, GetProcessHeap(), 1))
{
if (pTcpExTable)
{
HeapFree(GetProcessHeap(), 0, pTcpExTable);
}
FreeLibrary(hModule);
hModule = NULL;
return dwPortCount;
}
for (UINT i = 0;i < pTcpExTable->dwNumEntries; i++)
{
// 过滤掉数据,只获取我们要查询的进程的 TCP Port 信息
if(dwProcessId == pTcpExTable->table[i].dwProcessId)
{
if(dwPortCount < dwMaxLen)
{
dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort);
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_addr.s_addr = pTcpExTable->table[i].dwRemoteAddr;
char* ip = inet_ntoa(local.sin_addr);
dwPortCount++;
}
}
}
if (pTcpExTable)
{
HeapFree(GetProcessHeap(), 0, pTcpExTable);
}
FreeLibrary(hModule);
hModule = NULL;
return dwPortCount;
}
}
else if(type == UdpType)
{
// 表明查询的是 UDP 信息
PMIB_UDPEXTABLE pUdpExTable = NULL;
PFNAllocateAndGetUdpExTableFromStack pAllocateAndGetUdpExTableFromStack;
pAllocateAndGetUdpExTableFromStack =
(PFNAllocateAndGetUdpExTableFromStack)GetProcAddress(hModule,"AllocateAndGetUdpExTableFromStack");
if (pAllocateAndGetUdpExTableFromStack != NULL)
{
// 表明为 XP 或者 Server 2003 操作系统
if (pAllocateAndGetUdpExTableFromStack((PVOID*)&pUdpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0)
{
if (pUdpExTable)
{
HeapFree(GetProcessHeap(), 0, pUdpExTable);
}
FreeLibrary(hModule);
hModule = NULL;
return dwPortCount;
}
for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++)
{
// 过滤掉数据,只获取我们要查询的进程的 UDP Port信息
if(dwProcessId == pUdpExTable->table[i].dwProcessId)
{
if(dwPortCount < dwMaxLen)
{
dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort);
dwPortCount++;
}
}
}
if (pUdpExTable)
{
HeapFree(GetProcessHeap(), 0, pUdpExTable);
}
FreeLibrary(hModule);
hModule = NULL;
return dwPortCount;
}
else
{
// 表明为 Vista 或者 7 操作系统
PFNInternalGetUdpTableWithOwnerPid pInternalGetUdpTableWithOwnerPid;
pInternalGetUdpTableWithOwnerPid =
(PFNInternalGetUdpTableWithOwnerPid)GetProcAddress(hModule, "InternalGetUdpTableWithOwnerPid");
if (pInternalGetUdpTableWithOwnerPid != NULL)
{
if (pInternalGetUdpTableWithOwnerPid(&pUdpExTable, GetProcessHeap(), 1))
{
if (pUdpExTable)
{
HeapFree(GetProcessHeap(), 0, pUdpExTable);
}
FreeLibrary(hModule);
hModule = NULL;
return dwPortCount;
}
for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++)
{
// 过滤掉数据,只获取我们要查询的进程的 UDP Port信息
if(dwProcessId == pUdpExTable->table[i].dwProcessId)
{
if(dwPortCount < dwMaxLen)
{
dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort);
dwPortCount++;
}
}
}
}
if (pUdpExTable)
{
HeapFree(GetProcessHeap(), 0, pUdpExTable);
}
FreeLibrary(hModule);
hModule = NULL;
return dwPortCount;
}
}
else
{
FreeLibrary(hModule);
hModule = NULL;
return dwPortCount;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwRet = 0;
DWORD allPort[10240] = { 0 };
DWORD dwMaxLen = 10240;
dwRet = GetAllPortByProcessId(TcpType, 16368, allPort, dwMaxLen);
return 0;
}