2017年1月13日星期五

PacketFilterExtensionPtr.C

/*
文件名:PacketFilterExtensionPtr.C

说明:经常看到WDK的Hook Drivers,Filter-Hook Drivers,一直没有深入研究,直到今天。

参考:
1.WDK
2.http://newbiecoder.0ginr.com/blog/?p=550#comment-122368
3.开源防火墙NetDefender的IP过滤驱动模块
4.http://myblog-maurice.blogspot.jp/2012/02/sniffer.html

注意:
1.IpFilterDriver模块默认安装,但是没有运行。
2.或许是上面的原因,这个模块/功能会被删除/禁用掉。

made by correy
made at 2017.01.09.
homepage:http://correy.webs.com
*/

#include <ntifs.h>
#include <windef.h>
#include <ntddk.h>
#include <ntstrsafe.h>
#include <assert.h>
#include <Ntdddisk.h>

#include <ndis.h>
#include <Pfhook.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) //封装要区分成员对齐方式
#pragma warning(disable:4189) //局部变量已初始化但不引用


#define TAG 'test' test


PF_FORWARD_ACTION PacketFilterExtension(
    IN unsigned char  *PacketHeader,
    IN unsigned char  *Packet,
    IN unsigned int  PacketLength,
    IN unsigned int  RecvInterfaceIndex,
    IN unsigned int  SendInterfaceIndex,
    IN IPAddr  RecvLinkNextHop,
    IN IPAddr  SendLinkNextHop
    )
{
    return PF_FORWARD;
}


NTSTATUS StopIpFilter()
{
    NTSTATUS status = STATUS_SUCCESS;
    UNICODE_STRING IpFilterDriver = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\IpFilterDriver");//默认情况下,注册表已经存在,但是没有启动。
    UNICODE_STRING IpFilterDevice = RTL_CONSTANT_STRING(DD_IPFLTRDRVR_DEVICE_NAME);
    PDEVICE_OBJECT deviceObject;
    PFILE_OBJECT fileObject;
    PF_SET_EXTENSION_HOOK_INFO psehi = {0};
    KEVENT event;
    IO_STATUS_BLOCK ioStatusBlock;
    PIRP irp;

    status = IoGetDeviceObjectPointer(&IpFilterDevice, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
    ASSERT(NT_SUCCESS(status));

    psehi.ExtensionPointer = NULL;

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    irp = IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER, deviceObject, &psehi, sizeof(PF_SET_EXTENSION_HOOK_INFO), NULL, 0, FALSE, &event, &ioStatusBlock);
    if (!irp)
    {
        ObDereferenceObject(fileObject);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = IoCallDriver(deviceObject, irp);
    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
        status = ioStatusBlock.Status;
    }
    ASSERT(NT_SUCCESS(status));

    ObDereferenceObject(fileObject);

    status = ZwUnloadDriver(&IpFilterDriver);
    if (!NT_SUCCESS(status))
    {
        KdPrint(("ZwLoadDriver fail with 0x%x.\r\n", status));
        return status;
    }

    return status;
}


NTSTATUS StartIpFilter(PacketFilterExtensionPtr PacketFilter)
{
    NTSTATUS status = STATUS_SUCCESS;
    UNICODE_STRING IpFilterDriver = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\IpFilterDriver");//默认情况下,注册表已经存在,但是没有启动。
    UNICODE_STRING IpFilterDevice = RTL_CONSTANT_STRING(DD_IPFLTRDRVR_DEVICE_NAME);
    PDEVICE_OBJECT deviceObject;
    PFILE_OBJECT fileObject;
    PF_SET_EXTENSION_HOOK_INFO psehi = {0};
    KEVENT event;
    IO_STATUS_BLOCK ioStatusBlock;
    PIRP irp;

    status = ZwLoadDriver(&IpFilterDriver);
    if (!NT_SUCCESS(status))
    {
        KdPrint(("ZwLoadDriver fail with 0x%x.\r\n", status));
        return status;
    }

    status = IoGetDeviceObjectPointer(&IpFilterDevice, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
    ASSERT(NT_SUCCESS(status));

    psehi.ExtensionPointer = PacketFilter;

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    irp = IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER, deviceObject, &psehi, sizeof(PF_SET_EXTENSION_HOOK_INFO), NULL, 0, FALSE, &event, &ioStatusBlock);
    if (!irp)
    {
        ObDereferenceObject(fileObject);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    status = IoCallDriver(deviceObject, irp);
    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
        status = ioStatusBlock.Status;
    }
    ASSERT(NT_SUCCESS(status));

    ObDereferenceObject(fileObject);

    return status;
}


//DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
    StopIpFilter();
}


NTSTATUS DriverEntry(__in struct _DRIVER_OBJECT  * DriverObject, __in PUNICODE_STRING  RegistryPath)
{
    NTSTATUS status = STATUS_SUCCESS;

    //KdBreakPoint();
    __debugbreak();

    DriverObject->DriverUnload = Unload;

    status = StartIpFilter(PacketFilterExtension);
    if (!NT_SUCCESS(status))
    {
        KdPrint(("StartIpFilter fail with 0x%x.\r\n", status));
        return status;
    }

    return status;
}

没有评论:

发表评论