Enumerating TCP ports and mapping them to PID (for XP)
0 answers - 6022 bytes -

Hello,
I've written an example for Windows XP that enumerates all open TCP and UDP ports and map them to the owning application. It uses a couple of undocumented functions like NETSTAT.EXE does.
Unfortunately, I don't have a time to write an article about this technique for Godeguru so if anybody want to write it, please feel free to use my example.
// portsenumxp.cpp (Windows XP)
//
// This example will show how you can enumerate
// all open TCP and UDP ports and map them to
// the owning application. It uses undocumented
// functions from iphlpapi.dll which were found
// by reversing netstat.exe.
//
//
// (c) 2002 Ashot Oganesyan K (ashot@protect-me.com)
// (c) 2002 SmartLine, Inc. (http://www.protect-me.com)
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <Iphlpapi.h>
typedef struct _MIB_TCPROW_EX
{
DWORD dwState; // MIB_TCP_STATE_*
DWORD dwLocalAddr;
DWORD dwLocalPort;
DWORD dwRemoteAddr;
DWORD dwRemotePort;
DWORD dwProcessId;
} MIB_TCPROW_EX, *PMIB_TCPROW_EX;
typedef struct _MIB_TCPTABLE_EX
{
DWORD dwNumEntries;
MIB_TCPROW_EX table[ANY_SIZE];
} MIB_TCPTABLE_EX, *PMIB_TCPTABLE_EX;
typedef struct _MIB_UDPROW_EX
{
DWORD dwLocalAddr;
DWORD dwLocalPort;
DWORD dwProcessId;
} MIB_UDPROW_EX, *PMIB_UDPROW_EX;
typedef struct _MIB_UDPTABLE_EX
{
DWORD dwNumEntries;
MIB_UDPROW_EX table[ANY_SIZE];
} MIB_UDPTABLE_EX, *PMIB_UDPTABLE_EX;
/*
DWORD
WINAPI
AllocateAndGetTcpExTableFromStack(
OUT PMIB_TCPTABLE_EX *pTcpTableEx,
IN BOOL bOrder,
IN HANDLE hAllocHeap,
IN DWORD dwAllocFlags,
IN DWORD dwProtocolVersion; // 2 - TCP, 23 - TCPv6 (size of *pTcpTableEx must be 56!)
);
*/
typedef DWORD (WINAPI *PROCALLOCATEANDGETTCPEXTABLEFROMSTACK)(PMIB_TCPTABLE_EX*,BOOL,HANDLE,DWORD,DWORD);
PROCALLOCATEANDGETTCPEXTABLEFROMSTACK lpfnAllocateAndGetTcpExTableFromStack = NULL;
/*
DWORD
WINAPI
AllocateAndGetUdpExTableFromStack(
OUT PMIB_UDPTABLE_EX *pUdpTable,
IN BOOL bOrder,
IN HANDLE hAllocHeap,
IN DWORD dwAllocFlags,
IN DWORD dwProtocolVersion; // 2 - UDP, 23 - UDPv6 (size of *pUdpTable must be 28!)
);
*/
typedef DWORD (WINAPI *PROCALLOCATEANDGETUDPEXTABLEFROMSTACK)(PMIB_UDPTABLE_EX*,BOOL,HANDLE,DWORD,DWORD);
PROCALLOCATEANDGETUDPEXTABLEFROMSTACK lpfnAllocateAndGetUdpExTableFromStack = NULL;
BOOL LoadExIpHelperProcedures(void)
{
HMODULE hModule;
hModule = LoadLibrary(_T("iphlpapi.dll"));
if (hModule == NULL)
return FALSE;
// XP and later
lpfnAllocateAndGetTcpExTableFromStack = (PROCALLOCATEANDGETTCPEXTABLEFROMSTACK)GetProcAddress(hModule,"AllocateAndGetTcpExTableFromStack");
if (lpfnAllocateAndGetTcpExTableFromStack == NULL)
return FALSE;
// XP and later
lpfnAllocateAndGetUdpExTableFromStack = (PROCALLOCATEANDGETUDPEXTABLEFROMSTACK)GetProcAddress(hModule,"AllocateAndGetUdpExTableFromStack");
if (lpfnAllocateAndGetUdpExTableFromStack == NULL)
return FALSE;
return TRUE;
}
void main(void)
{
DWORD dwLastError,
dwSize;
PMIB_TCPTABLE_EX lpBuffer = NULL;
PMIB_UDPTABLE_EX lpBuffer1 = NULL;
if (!LoadExIpHelperProcedures())
return;
dwLastError = lpfnAllocateAndGetTcpExTableFromStack(&lpBuffer,TRUE,GetProcessHeap(),0,2);
if (dwLastError == NO_ERROR)
{
printf(_T("Local IP\tLocal Port\tRemote Ip\tRemote Port\tPID\n\n"));
for (dwSize = 0; dwSize < lpBuffer->dwNumEntries; dwSize++)
{
// Local IP Address
printf(_T("%d.%d.%d.%d\t"),LOBYTE(LOWORD(lpBuffer->table[dwSize].dwLocalAddr)),HIBYTE(LOWORD(lpBuffer->table[dwSize].dwLocalAddr)),LOBYTE(HIWORD(lpBuffer->table[dwSize].dwLocalAddr)),HIBYTE(HIWORD(lpBuffer->table[dwSize].dwLocalAddr)));
// Local Port
printf(_T("%d\t"),((lpBuffer->table[dwSize].dwLocalPort & 0xFF00) >> 8) + ((lpBuffer->table[dwSize].dwLocalPort & 0x00FF) << 8));
// Remote IP Address
printf(_T("%d.%d.%d.%d\t"),LOBYTE(LOWORD(lpBuffer->table[dwSize].dwRemoteAddr)),HIBYTE(LOWORD(lpBuffer->table[dwSize].dwRemoteAddr)),LOBYTE(HIWORD(lpBuffer->table[dwSize].dwRemoteAddr)),HIBYTE(HIWORD(lpBuffer->table[dwSize].dwRemoteAddr)));
// Remote Port
if (lpBuffer->table[dwSize].dwRemoteAddr)
printf(_T("%d\t"),((lpBuffer->table[dwSize].dwRemotePort & 0xFF00) >> 8) + ((lpBuffer->table[dwSize].dwRemotePort & 0x00FF) << 8));
else
printf(_T("0\t"));
// PID
printf(_T("%lu\n"),lpBuffer->table[dwSize].dwProcessId);
}
}
dwLastError = lpfnAllocateAndGetUdpExTableFromStack(&lpBuffer1,TRUE,GetProcessHeap(),0,2);
if (dwLastError == NO_ERROR)
{
printf(_T("Local IP\tLocal Port\tPID\n\n"));
for (dwSize = 0; dwSize < lpBuffer1->dwNumEntries; dwSize++)
{
// Local IP Address
printf(_T("%d.%d.%d.%d\t"),LOBYTE(LOWORD(lpBuffer1->table[dwSize].dwLocalAddr)),HIBYTE(LOWORD(lpBuffer1->table[dwSize].dwLocalAddr)),LOBYTE(HIWORD(lpBuffer1->table[dwSize].dwLocalAddr)),HIBYTE(HIWORD(lpBuffer1->table[dwSize].dwLocalAddr)));
// Local Port
printf(_T("%d\t"),((lpBuffer1->table[dwSize].dwLocalPort & 0xFF00) >> 8) + ((lpBuffer1->table[dwSize].dwLocalPort & 0x00FF) << 8));
// PID
printf(_T("%lu\n"),lpBuffer1->table[dwSize].dwProcessId);
}
}
if (lpBuffer)
HeapFree(GetProcessHeap(),0,lpBuffer);
if (lpBuffer1)
HeapFree(GetProcessHeap(),0,lpBuffer1);
}