Driver development 4: NDIS filter hook driver implement ippacket Filter

Source: Internet
Author: User
Author: flashsky
Email: flashsky@xfocus.org
Site: www.xfocus.net www.shopsky.com
Reprinted, please indicate the original author's security focus

In normal Windows 2000, the main method to implement package filtering is to write the NDIS filter driver, which requires a high skill and requires a lot of details. However, for many applications, you only need to be able to more easily filter IP packets. In fact, NDIS provides a write filter hook driver for filtering IP packets. The main method is as follows:
Create a common device in the driver, and then use ioctl_pf_set_extension_pointer to hook your kernel-mode filter hook to the system's default IP address filter driver, in this way, you can implement complete packet-based analysis and filtering in your own filter hooks.
The following is a complete NDIS filter hook-driven code that rejects all external TCP connection requests with S.
Note:
1. Need to be compiled in the DDK Environment
2. You need to modify the start type of lmhk/system // CurrentControlSet // services // ipfilterdriver in the Registry to 3 so that it can be started with the system startup.
3. After the Sys File is compiled and generated, it must be copied to the WINNT/system32/DRIVERS directory.
4. You need to run a program and then manually generate the registry key
5. Use Net start fxfilthook to start the driver and use net stop fxfilthook to stop the driver.
6. This method can only filter IP packets. Other protocols are not processed by this filter hook.

// Driver header file
# Include "ntddk. H"
# Include "ntddndis. H"
# Include "pfhook. H"
# Ifndef _ nthandle_h
# DEFINE _ nthandle_h

# Define nt_device_name l "// device // fxfilthook"
# Define dos_device_name l "// dosdevices // fxfilthook"

# Define prot_tcp 6

# Include "ntddk. H"
# Include "xfilthook. H"

Typedef struct ipheader {
Uchar iph_verlen; // version and length
Uchar iph_tos; // type of service
Ushort iph_length; // total datatelength
Ushort iph_id; // Identification
Ushort iph_offset; // flags, Fragment Offset
Uchar iph_ttl; // time to live
Uchar iph_protocol; // Protocol
Ushort iph_xsum; // header checksum
Ulong iph_src; // Source Address
Ulong iph_dest; // Destination Address
} Ipheader;

Ntstatus
DriverEntry (
In pdriver_object driverobject,
In punicode_string registrypath );

Ntstatus
Createfilterhook
(In pdriver_object driverobject );

Void
Driverunload
(In pdriver_object driverobject );

Pf_forward_action
Ipfilterhook (
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 );
# Endif

// C file of the driver
# Define prot_tcp 6
# Include "ntddk. H"
# Include "ntddndis. H"
# Include "pfhook. H"
# Include "fxfilthook. H"

Pdevice_object deviceobject;
Unicode_string win32devicename;

// Driver entry point
Ntstatus
DriverEntry (
In pdriver_object driverobject,
In punicode_string registrypath
)
{
Ntstatus status = STATUS_SUCCESS;
Unicode_string ntdevicename;

Rtlinitunicodestring (& ntdevicename, nt_device_name );
// Create a filter hook driver
Status = iocreatedevice (driverobject, 0, & ntdevicename, file_device_unknown, 0, true, & deviceobject );
If (! Nt_success (Status )){
Goto error;
}
Rtlinitunicodestring (& win32devicename, dos_device_name );
// Create a filter hook driver symbol connection
Status = iocreatesymboliclink (& win32devicename, & ntdevicename );
If (! Nt_success (Status) // if we couldn't create the link then
{// Abort installation.
Goto error;
}
// Declare the uninstall routine
Driverobject-> driverunload = driverunload;
// Create a hook
Status = createfilterhook (driverobject );
If (! Nt_success (Status) // if we couldn't create the link then
{// Abort installation.
Iodeletesymboliclink (& win32devicename );
Goto error;
}
Return (STATUS_SUCCESS );
Error:
If (deviceobject)
Iodeletedevice (deviceobject );
// Dbuplint ("Leave DriverEntry failed/N ");
Return status;
}

Ntstatus
Createfilterhook (in pdriver_object driverobject)
{
Pirp nirp;
Ntstatus status = STATUS_SUCCESS;
Pfile_object filtfileob;
Unicode_string ntdevicename;
Pdevice_object filtdeviceob;
Pf_set_extension_hook_info filthook;
Io_status_block filtstatus;

Rtlinitunicodestring (& ntdevicename, l "// device // ipfilterdriver ");
// Put the hook function into the structure
Filthook. extensionpointer = ipfilterhook;
// Obtain the device pointer driven by the system ipfilterdriver.
Status = iogetdeviceobjectpointer (& ntdevicename, file_generic_read | file_generic_write, & filtfileob, & filtdeviceob );
If (status! = STATUS_SUCCESS)
Return status;
// Bind the device pointer from the filter hook to the system ipfilterdriver driver
Nirp = iobuilddeviceiocontrolrequest (
Ioctl_pf_set_extension_pointer,
Filtdeviceob,
& Filthook,
Sizeof (pf_set_extension_hook_info ),
Null,
0,
False,
Null,
& Filtstatus );
If (nirp = NULL)
Return filtstatus. status;
// The scheduling system ipfilterdriver device re-operates the IRP
Return (iocalldriver (filtdeviceob, nirp ));
}

Void
Driverunload (in pdriver_object driverobject)
{
// Just like loading, the hook function is put null in the hook function structure, so that the system ipfilterdriver can uninstall the loaded hook function.

Pirp nirp;
Ntstatus status = STATUS_SUCCESS;
Pdevice_object filtdeviceob;
Pfile_object filtfileob;
Pf_set_extension_hook_info filthook;
Io_status_block filtstatus;
Unicode_string ntdevicename;

Rtlinitunicodestring (& ntdevicename, l "// device // ipfilterdriver ");
Filthook. extensionpointer = NULL;
Status = iogetdeviceobjectpointer (& ntdevicename, file_generic_read | file_generic_write, & filtfileob, & filtdeviceob );
If (status = STATUS_SUCCESS)
{
Nirp = iobuilddeviceiocontrolrequest (
Ioctl_pf_set_extension_pointer,
Filtdeviceob,
& Filthook,
Sizeof (pf_set_extension_hook_info ),
Null,
0,
False,
Null,
& Filtstatus );
If (nirp! = NULL)
Iocalldriver (filtdeviceob, nirp );
}
Iodeletesymboliclink (& win32devicename );
Iodeletedevice (deviceobject );
Return;
}

Pf_forward_action
Ipfilterhook (
Unsigned char * packetheader,
Unsigned char * packet,
Unsigned int packetlength,
Unsigned int recvinterfaceindex,
Unsigned int sendinterfaceindex,
Ipaddr recvlinknexthop,
Ipaddr sendlinknexthop
)
{
// Filter the hook function. Here, only the TCP protocol is used to determine whether the data arrives and the SYN flag is used for filtering. You can modify your own filter to determine and process the filter as needed.
If (ipheader *) packetheader)-> iph_protocol = prot_tcp)
{
// Packet [13] = 0x2 indicates the SYN flag in TCP.
// Sendinterfaceindex = invalid_pf_if_index indicates that the package arrives instead of being sent. Therefore, filtering will not affect the packet distribution, but the packet with external SYN requests will be rejected.
If (packet [13] = 0x2 & sendinterfaceindex = invalid_pf_if_index)
Return pf_drop;
}
Return pf_forward;
}

// A simple program for establishing the registry key

Unsigned char Sysdir [256];
Unsigned char drivcedir [256];
Int reghandeldev (char * exename)
{
// Modify the Registry to start an nthandle driver
Char subkey [200];
Int buflen;
Hkey hkresult;
Char data [4];
DWORD isok;
Buflen = sprintf (subkey, "system // CurrentControlSet // services // % s", exename );
Subkey [buflen] = 0;
Isok = regcreatekey (HKEY_LOCAL_MACHINE, subkey, & hkresult );
If (isok! = Error_success)
Return false;
Data [0] = 3;
Data [1] = 0;
Data [2] = 0;
Data [3] = 0;
Isok = regsetvalueex (hkresult, "Start", 0,4, (const unsigned char *) data, 4 );
Data [0] = 1;
Isok = regsetvalueex (hkresult, "type", 0, 4, (const unsigned char *) data, 4 );
Isok = regsetvalueex (hkresult, "errorcontrol", 0, 4, (const unsigned char *) data, 4 );
Getsystemdirectory (Sysdir, 256 );
Buflen = sprintf (drivcedir, "% S // drivers // fxfilthook. sys", Sysdir );
Buflen = sprintf (subkey ,"//?? // % S ", drivcedir );
Subkey [buflen] = 0;
Isok = regsetvalueex (hkresult, "ImagePath", 0, 1, (const unsigned char *) subkey, buflen );
Regclosekey (hkresult );
Buflen = sprintf (subkey, "// registry // machine // system // CurrentControlSet // services // % s", exename );
Subkey [buflen] = 0;
Return true;
}

Int main (INT argc, char * argv [])
{
// Register the driver
If (reghandeldev ("fxfilthook") = false)
Return false;
Return true;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.