/*
目的:演示FwpsAleEndpointEnum的用法。
注意:编译的平台和运行的平台。
说明:Ale的Endpoint,这是什么呢?
类似TCPView.exe不停的显示和更新,
当然这个函数每次获取的值/数量也是不同的。
made by correy
made at 2016.08.31.
homepage:http://correy.webs.com
*/
#include <ntifs.h>
#include <windef.h>
#include <ntddk.h>
#include <ntstrsafe.h>
#include <Fwpsk.h>
#include <initguid.h> //静态定义UUID用的,否则:error LNK2001。
#include <Fwpmk.h>
#include <ndis.h>
#include <Wsk.h>
#include <ipmib.h>
#include <netpnp.h>
#include <ntintsafe.h>
#include <intrin.h> //VS2012编译。
#include <immintrin.h>//VS2012编译。
//#include <mmintrin.h> //WDK 编译。
//#include <emmintrin.h>//WDK 编译。
//#include <xmmintrin.h>//WDK 编译。
#pragma warning(disable:4100) //未引用的形参
#pragma warning(disable:4214) //整形以外的位域类型
#pragma warning(disable:4121) //封装要区分成员对齐方式
#define TAG 'test' //test
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms738518%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
//其实:IPV4的只需This buffer should be large enough to hold at least 16 characters.
#define MAX_ADDRESS_STRING_LENGTH 64
wchar_t * get_protocol_name(UINT8 protocol)
{
wchar_t * protocol_name = 0;
switch(protocol)
{
case IPPROTO_TCP:
protocol_name = L"TCP";
break;
case IPPROTO_UDP:
protocol_name = L"UDP";
break;
case IPPROTO_IPV4:
protocol_name = L"IPV4";
break;
case IPPROTO_IPV6:
protocol_name = L"IPV6";
break;
case IPPROTO_ICMP:
protocol_name = L"ICMP";
break;
case IPPROTO_IGMP:
protocol_name = L"IGMP";
break;
case IPPROTO_ICMPV6:
protocol_name = L"ICMPV6";
break;
default:
protocol_name = L"未知";//也可打印一个数值。
break;
}
return protocol_name;
}
//DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
}
//DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry(__in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath)
{
HANDLE gEngineHandle;
NTSTATUS Status = STATUS_SUCCESS;
FWPM_SESSION0 session = {0};
FWPS_ALE_ENDPOINT_ENUM_TEMPLATE0 enumTemplate;//编译为WIN 7版本,VISTA是没有这个变量的。
HANDLE enumHandle;
FWPS_ALE_ENDPOINT_PROPERTIES0 **entries;
UINT32 numEntriesReturned;
UINT32 calloutIndex = 0;
UNICODE_STRING appId = {0};
//KdBreakPoint();
__debugbreak();
DriverObject->DriverUnload = Unload;
session.flags = FWPM_SESSION_FLAG_DYNAMIC;
Status = FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &session, &gEngineHandle);
ASSERT (NT_SUCCESS(Status));
RtlZeroMemory(&enumTemplate, sizeof(FWPS_ALE_ENDPOINT_ENUM_TEMPLATE0));
Status = FwpsAleEndpointCreateEnumHandle0(gEngineHandle, &enumTemplate, &enumHandle);//Available starting with Windows 7
ASSERT (NT_SUCCESS(Status));
Status = FwpsAleEndpointEnum0(gEngineHandle, enumHandle, 0xFFFFFFFF, &entries, &numEntriesReturned);//Available starting with Windows 7
ASSERT (NT_SUCCESS(Status));
KdPrint(("numEntriesReturned:0x%x.\n\n\n", numEntriesReturned));
for( ; calloutIndex < numEntriesReturned; calloutIndex++)
{
KdPrint(("calloutIndex:0x%x.\n",(calloutIndex + 1)));
if (entries[calloutIndex]->ipVersion == FWP_IP_VERSION_V4)
{
UINT32 l4a = RtlUlongByteSwap((ULONG)entries[calloutIndex]->localV4Address);
UINT32 r4a = RtlUlongByteSwap((ULONG)entries[calloutIndex]->remoteV4Address);
wchar_t localV4Address[MAX_ADDRESS_STRING_LENGTH] = {0};
wchar_t remoteV4Address[MAX_ADDRESS_STRING_LENGTH] = {0};
RtlIpv4AddressToString((const struct in_addr *)&l4a, localV4Address);
RtlIpv4AddressToString((const struct in_addr *)&r4a, remoteV4Address);
KdPrint(("ipVersion:FWP_IP_VERSION_V4.\n"));
KdPrint(("localV4Address:%ws.\n", localV4Address));
KdPrint(("remoteV4Address:%ws.\n", remoteV4Address));
}
else if (entries[calloutIndex]->ipVersion == FWP_IP_VERSION_V6)
{
/*
这个IPV6的地址的字节序需要转换不?
最大是RtlUlonglongByteSwap,64-bit,但是IPv6 is 128 bits。
难道要用这个函数两次,两次的也不符合,自己写个函数?自己可以验证下。
*/
wchar_t localV6Address[MAX_ADDRESS_STRING_LENGTH] = {0};
wchar_t remoteV6Address[MAX_ADDRESS_STRING_LENGTH] = {0};
RtlIpv6AddressToString((const struct in6_addr *)&entries[calloutIndex]->localV6Address, localV6Address);
RtlIpv6AddressToString((const struct in6_addr *)&entries[calloutIndex]->remoteV6Address, remoteV6Address);
KdPrint(("ipVersion:FWP_IP_VERSION_V6.\n"));
KdPrint(("localV6Address:%ws.\n", localV6Address));
KdPrint(("remoteV6Address:%ws.\n", remoteV6Address));
}
else
{
KdBreakPoint();
}
KdPrint(("ipProtocol:%ws.\n", get_protocol_name(entries[calloutIndex]->ipProtocol)));
KdPrint(("localPort:%d.\n", entries[calloutIndex]->localPort));
KdPrint(("remotePort:%d.\n", entries[calloutIndex]->remotePort));
KdPrint(("localTokenModifiedId:0x%x.\n", entries[calloutIndex]->localTokenModifiedId));
KdPrint(("mmSaId:0x%x.\n", entries[calloutIndex]->mmSaId));
KdPrint(("qmSaId:0x%x.\n", entries[calloutIndex]->qmSaId));
KdPrint(("ipsecStatus:0x%x.\n", entries[calloutIndex]->ipsecStatus));
KdPrint(("flags:0x%x.\n", entries[calloutIndex]->flags));
appId.Buffer = (PWCH)&entries[calloutIndex]->appId.data[0];
appId.Length = (USHORT)entries[calloutIndex]->appId.size;
appId.MaximumLength = appId.Length;
KdPrint(("appId:%wZ.\n", &appId));//进程的完整路径(NT式的设备路径)。一个特殊是:System。
KdPrint(("\n"));
}
FwpmFreeMemory((VOID**)&entries);
Status = FwpsAleEndpointDestroyEnumHandle0(gEngineHandle, enumHandle);//Available starting with Windows 7
ASSERT (NT_SUCCESS(Status));
FwpmEngineClose0(gEngineHandle);
return Status;
}
没有评论:
发表评论