好的,那么,我正在构建一个实用程序来监视文件系统、注册表和网络活动(进程方面的;仅针对选定进程的活动)。通过开发一个小过滤器驱动程序,我已经完成了文件系统和注册表活动部分。然而,我不确定我应该如何为网络做这件事。我想要做的很像sysinternal的TCPView所做的事情,但是我只想监视所选进程所建立的连接。以下是我希望为每个连接实时获取的内容:
-protocol (TCP或UDP)
-source端口
-remote IP和端口
-optional从监视开始的时间起在特定连接上传输的字节数
我应该使用什么?我听说过LSP,但进一步阅读后我意识到编写正常运行的LSP是非常困难的,更不用说几乎没有任何材料可供他们从头开始学习。此外,它们正在变得过时。问题是,我只有大约2-3周的时间来learn+write这个模块。由于时间的限制,我当然不想去像世界粮食计划署这样的东西,除非有一个非常好的教程,我不是在谈论MSDN文档。我不知道这是否可以使用NDIS等“轻松”完成。
无论如何,我应该做什么,我应该把精力放在哪里。我应该冒学习LSP的风险,还是NDIS会完成任务,或者其他什么。我现在有点不知所措。帮帮我!
发布于 2013-02-15 05:14:55
看看GetExtendedTcpTable和GetExtendedUdpTable。这些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发布于 2013-02-13 01:09:54
在我看来,您需要的是类似winpcap的东西,这正是wireshark所使用的。
http://www.winpcap.org/
另外,来自ReactOS的netstat代码可能会很有趣
http://doxygen.reactos.org/dd/d3f/netstat_8c_source.html
https://stackoverflow.com/questions/14837759
复制相似问题