枚举bound状态的网络连接信息

在 Windows 的“netstat”实用程序的较新版本中,有一个命令行选项“-q”,可显示已绑定但未连接的套接字(即**“bound state”**)。

“bound state” 表示套接字已经绑定到了本地地址和端口但未连接,“bound state” 是套接字的一种暂时状态,目前只在Win 10系统中发现
有关此类套接字的输出如下所示

TCP    0.0.0.0:4294           0.0.0.0:0              BOUND
TCP    0.0.0.0:8054           0.0.0.0:0              BOUND
TCP    0.0.0.0:8840           0.0.0.0:0              BOUND

Windows 目前没有任何记录或支持的用于查询绑定连接的 API。唯一的选择是使用这两个未记录的函数:

ULONG WINAPI InternalGetBoundTcpEndpointTable(
    _Out_ PMIB_TCPTABLE2* BoundTcpTable,
    _In_ PVOID HeapHandle,
    _In_opt_ ULONG HeapFlags
    );

ULONG WINAPI InternalGetBoundTcp6EndpointTable(
    _Out_ PMIB_TCP6TABLE2* BoundTcp6Table,
    _In_ PVOID HeapHandle,
    _In_opt_ ULONG HeapFlags
    );

下面代码能够查询到处于bound状态的网络连接信息,包括本地ip、本地端口、远程ip、远程端口、进程id和套接字的状态。
静态加载:

#pragma comment(lib, "iphlpapi.lib")

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

#include <windows.h>
#include <stdio.h>

ULONG WINAPI InternalGetBoundTcpEndpointTable(
    _Out_ PMIB_TCPTABLE2* BoundTcpTable,
    _In_ PVOID HeapHandle,
    _In_opt_ ULONG HeapFlags
    );

ULONG WINAPI InternalGetBoundTcp6EndpointTable(
    _Out_ PMIB_TCP6TABLE2* BoundTcp6Table,
    _In_ PVOID HeapHandle,
    _In_opt_ ULONG HeapFlags
    );

void main()
{
    PMIB_TCPTABLE2 boundTcpTable;
    PMIB_TCP6TABLE2 boundTcp6Table;

    if (InternalGetBoundTcpEndpointTable(&boundTcpTable, GetProcessHeap(), 0) == ERROR_SUCCESS)
    {
        for (ULONG i = 0; i < boundTcpTable->dwNumEntries; i++)
        {
            printf("%lu: %lu\n",
                boundTcpTable->table[i].dwOwningPid,
                ntohs((u_short)boundTcpTable->table[i].dwLocalPort));
        }

        HeapFree(GetProcessHeap(), 0, boundTcpTable);
    }

    if (InternalGetBoundTcp6EndpointTable(&boundTcp6Table, GetProcessHeap(), 0) == ERROR_SUCCESS)
    {
        for (ULONG i = 0; i < boundTcp6Table->dwNumEntries; i++)
        {
            printf("%lu: %lu\n",
                boundTcp6Table->table[i].dwOwningPid,
                ntohs((u_short)boundTcp6Table->table[i].dwLocalPort));
        }

        HeapFree(GetProcessHeap(), 0, boundTcp6Table);
    }
}

动态加载:

#include <windows.h>
#include <stdio.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>

// 定义函数指针类型,用于存储加载的函数地址
typedef ULONG (WINAPI *LPFN_InternalGetBoundTcpEndpointTable)(
    _Out_ PMIB_TCPTABLE2* BoundTcpTable,
    _In_ PVOID HeapHandle,
    _In_opt_ ULONG HeapFlags
);

typedef ULONG (WINAPI *LPFN_InternalGetBoundTcp6EndpointTable)(
    _Out_ PMIB_TCP6TABLE2* BoundTcp6Table,
    _In_ PVOID HeapHandle,
    _In_opt_ ULONG HeapFlags
);

int main() {
    // 加载 IPHLPAPI.DLL 库
    HMODULE hIPHLPAPIDLL = LoadLibrary(TEXT("IPHLPAPI.DLL"));
    if (hIPHLPAPIDLL == NULL) {
        printf("Failed to load IPHLPAPI.DLL\n");
        return 1;
    }

    // 获取函数地址
    LPFN_InternalGetBoundTcpEndpointTable pfnInternalGetBoundTcpEndpointTable = 
        (LPFN_InternalGetBoundTcpEndpointTable)GetProcAddress(hIPHLPAPIDLL, "InternalGetBoundTcpEndpointTable");

    LPFN_InternalGetBoundTcp6EndpointTable pfnInternalGetBoundTcp6EndpointTable =
        (LPFN_InternalGetBoundTcp6EndpointTable)GetProcAddress(hIPHLPAPIDLL, "InternalGetBoundTcp6EndpointTable");

    if (pfnInternalGetBoundTcpEndpointTable == NULL || pfnInternalGetBoundTcp6EndpointTable == NULL) {
        printf("Failed to get function addresses\n");
        FreeLibrary(hIPHLPAPIDLL); // 释放库
        return 1;
    }

    PMIB_TCPTABLE2 boundTcpTable;
    PMIB_TCP6TABLE2 boundTcp6Table;

    // 使用加载的函数
    if (pfnInternalGetBoundTcpEndpointTable(&boundTcpTable, GetProcessHeap(), 0) == ERROR_SUCCESS) {
        for (ULONG i = 0; i < boundTcpTable->dwNumEntries; i++) {
            printf("%lu: %lu\n",
                boundTcpTable->table[i].dwOwningPid,
                boundTcpTable->table[i].dwLocalPort);
        }

        HeapFree(GetProcessHeap(), 0, boundTcpTable);
    }

    if (pfnInternalGetBoundTcp6EndpointTable(&boundTcp6Table, GetProcessHeap(), 0) == ERROR_SUCCESS) {
        for (ULONG i = 0; i < boundTcp6Table->dwNumEntries; i++) {
            printf("%lu: %lu\n",
                boundTcp6Table->table[i].dwOwningPid,
                boundTcp6Table->table[i].dwLocalPort);
        }

        HeapFree(GetProcessHeap(), 0, boundTcp6Table);
    }

    FreeLibrary(hIPHLPAPIDLL); // 释放库

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值