2013-02-12 137 views
0

好吧,我正在构建一个实用程序来监视文件系统,注册表和网络活动(流程明智;只有选定流程的活动)。我通过开发微型过滤器驱动程序来完成文件系统和注册表活动部分。但是,我不确定我应该如何为网络做这件事。我想要做的很像sysinternal的TCPView所做的事情,但我只想通过选定的进程来监视ESTABLISHED连接。以下是我想实时获得每个连接:什么技术/ API /技术用于网络监控?

-protocol(TCP或UDP)

- 源端口

-remote IP和端口

- [可选]量在监控开始时在特定连接上传输的字节数

我应该使用什么?我听说过LSPs,但进一步阅读它后,我意识到编写正确运行的LSP非常困难,更不用说他们几乎没有任何材料可以从头开始学习。而且他们正在变得过时。问题是我只有大约2-3周的时间来学习+编写这个模块。由于时间限制,我当然不想去像WFP这样的东西,除非有非常好的教程,我不是在谈论MSDN文档。我不知道这是否可以使用NDIS“轻松”完成。

无论如何,我应该怎么做,我应该在哪里集中精力。我是否应该冒险学习LSP,或者NDIS是否完成任务或其他事情。我现在有点无知。帮帮我吧!

+0

我也希望得到的ProcessID /每个连接过程。另外,我不想监视“网络流量”,只想实时获取TCP和UDP端点,就像TCPView一样,除了ESTABLISHED连接之外。 – user1831704 2013-02-12 17:36:20

回答

2

GetExtendedTcpTableGetExtendedUdpTable。这些API将为您提供所需的大部分功能。但为了保持有趣,我写的代码使用GetTcp6Table2代替。

#define WIN32_LEAN_AND_MEAN 
#define UNICODE 
#define _UNICODE 

#include <windows.h> 
#include <winsock2.h> 
#include <Ws2tcpip.h> 
#include <iphlpapi.h> 
#include <Tcpestats.h> 
#include <Tcpmib.h> 
#include <Mstcpip.h> 
#include <stdlib.h> 
#include <stdio.h> 

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

PCWSTR 
StringFromState(MIB_TCP_STATE State) 
{ 
    switch (State) 
    { 
     case MIB_TCP_STATE_CLOSED: 
      return L"CLOSED"; 
     case MIB_TCP_STATE_LISTEN: 
      return L"LISTEN"; 
     case MIB_TCP_STATE_SYN_SENT: 
      return L"SYN_SENT"; 
     case MIB_TCP_STATE_SYN_RCVD: 
      return L"SYN_RCVD"; 
     case MIB_TCP_STATE_ESTAB: 
      return L"ESTAB"; 
     case MIB_TCP_STATE_FIN_WAIT1: 
      return L"FIN_WAIT1"; 
     case MIB_TCP_STATE_FIN_WAIT2: 
      return L"FIN_WAIT2"; 
     case MIB_TCP_STATE_CLOSE_WAIT: 
      return L"CLOSE_WAIT"; 
     case MIB_TCP_STATE_CLOSING: 
      return L"CLOSING"; 
     case MIB_TCP_STATE_LAST_ACK: 
      return L"LAST_ACK"; 
     case MIB_TCP_STATE_TIME_WAIT: 
      return L"TIME_WAIT"; 
     case MIB_TCP_STATE_DELETE_TCB: 
      return L"DELETE_TCB"; 
     default: 
      return L"[Unknown]"; 
    } 
} 

LPWSTR (NTAPI *pRtlIpv6AddressToStringW)(const IN6_ADDR *, LPWSTR); 

int __cdecl main() 
{ 
    ULONG r; 

    // We need to load this dynamically, because ntdll.lib doesn't export it 
    HMODULE ntdll = LoadLibrary(L"ntdll"); 
    pRtlIpv6AddressToStringW = (decltype(pRtlIpv6AddressToStringW))GetProcAddress(ntdll, "RtlIpv6AddressToStringW"); 

    // Initial guess for the table size 
    ULONG cbTable = 100; 
    MIB_TCP6TABLE2 *table = nullptr; 
    while (true) 
    { 
     table = (MIB_TCP6TABLE2*)malloc(cbTable); 
     if (!table) 
      return 1; 
     r = GetTcp6Table2(table, &cbTable, FALSE); 
     if (ERROR_INSUFFICIENT_BUFFER == r) 
     { 
      // Try again with bigger buffer 
      free(table); 
      continue; 
     } 
     else if (ERROR_SUCCESS == r) 
     { 
      break; 
     } 
     else 
     { 
      free(table); 
      wprintf(L"GetTcp6Table2 = %u\n", r); 
      return 1; 
     } 
    } 

    // Print table heading 
    wprintf(L"%56s %56s %10s %6s\n", L"Local endpoint", L"Remote endpoint", L"State", L"PID"); 
    for (ULONG i = 0; i < table->dwNumEntries; i++) 
    { 
     MIB_TCP6ROW2 const &entry = table->table[i]; 

     WCHAR localAddr[46]; 
     WCHAR remoteAddr[46]; 
     pRtlIpv6AddressToStringW(&entry.LocalAddr, localAddr); 
     pRtlIpv6AddressToStringW(&entry.RemoteAddr, remoteAddr); 

     WCHAR localEndpoint[56]; 
     WCHAR remoteEndpoint[56]; 
     swprintf_s(localEndpoint, L"[%s]:%-5u", localAddr, ntohs(entry.dwLocalPort)); 
     swprintf_s(remoteEndpoint, L"[%s]:%-5u", remoteAddr, ntohs(entry.dwRemotePort)); 

     wprintf(L"%56s %56s %10s %6u\n", 
       localEndpoint, remoteEndpoint, 
       StringFromState(entry.State), 
       entry.dwOwningPid); 
    } 

    free(table); 
    return 0; 
} 

实施例输出(匿名实际地址):

C:\>test.exe 
           Local endpoint        Remote endpoint  State PID 
            [::]:80          [::]:0  LISTEN 4 
            [::]:135          [::]:0  LISTEN 980 
            [::]:445          [::]:0  LISTEN 4 
            [::]:1025         [::]:0  LISTEN 692 
[2001:xxxx:x:xxx:x:xxxx:xxx.xx.xxx.xx]:6044     [xxxx:xxx:xxxx:xxxx::x]:443  ESTAB 3248 
[2001:xxxx:x:xxx:x:xxxx:xxx.xx.xxx.xx]:6045     [xxxx:xxx:xxxx:xxxx::x]:443  ESTAB 3248 
    [2001:xxxx:xx:x:xxxx:xxxx:xxxx:xxxx]:53759 [2001:xxxx:xx:xxxx:xxx:xxxx:xxxx:xxxx]:135 TIME_WAIT 0 
+0

谢谢你的帮助! ...这确实帮助很多! – user1831704 2013-02-20 06:23:05

0

听起来像你想要的东西像winpcap这是什么wireshark使用。

http://www.winpcap.org/

而且从ReactOS的使用netstat代码可能是有趣

http://doxygen.reactos.org/dd/d3f/netstat_8c_source.html

+0

netstat示例使用IP Helper API我认为,但我不认为我可以像使用TCPView一样获取进程ID或使用它传输的字节数量吗?对于数据包捕获和监控来说,winpcap也不是更多。当任何进程启动连接以及进程的名称或标识时,我只需要TCP和UDP端点以及那些实时端点。 – user1831704 2013-02-12 17:41:45

+0

不知道我可以鼓起一对夫妇的Linux(Nagios和Nethogs我认为)......但不知道是否有任何Windows。 – cb88 2013-02-13 21:03:02

+0

没有概率的人!谢谢您的帮助! – user1831704 2013-02-20 06:23:27