Download DownloadSource DownloadfireWALLAPPLICATION
Introduction If you decide to develop a firewall for the Linux system, you will find a lot of related information and all free code. But when people want
When developing a firewall on the Windows platform, it is a bit difficult, so the poor little information information is as for free code, almost no
possible. So I decided to write this about developing a simple function on the Windows 2000 / XP platform to help those who have
People with interest. Background Microsoft has included a new network driver class: Filter-Hook Driver.
Use it you can build interfaces of all communications. Filter-hook driver is as I said, Filter-Hook Driver is introduced in Microsoft's Windows 2000 DDK. But actually it
Not a new network driver class, it is just a driver for IP filtering. In fact, Filter-Hook Driver is not a network driver class, which belongs to the core drive model. In this Filter-Hook Driver
In we only enable a callback function, we just register this callback function in Filter-Hook Driver. When we realize and register
After the callback function, the IP filter driver calls it when the packet arrives and send it. We summarize the implementation step as the following steps: 1. Create a Filter-Hook Driver. Here you must build a core mode driver, you will optional, DOS name, and its
It is not necessarily necessary, but I suggest you do this. 2. If we want to install the filter function, we must first get an IP filter-driven pointer. This is the second step. 3, we have got a pointer, now we can correct our filter function function correctly. We will send a specific IPR, inside
The pointer to our filter function will be included. 4, filter pack! ! ! 5. After we complete the filtered, we must log out of the filter function function. We can register an empty pointer to replace our filter function pointer
. Oh, just five steps, it seems to be very simple, but how do I generate a core model driver? How to get IP filtering
What about pointer? How to .........., a little bit, I will explain all the steps above and list the source code example. Establishing a core mode Drive Filter-Hook Driver is a core mode driver, so we will create a driver for a core mode. But this article
Not "Teach you how to develop core drivers in 5 minutes", I will assume that readers have more than those of them. The Filter-Hook drive is a typical core drive structure. 1. We will establish a typical driver entry for the driver, setting a standard distribution routine for IRP (Dispatch, Load,
Unload, create ...), to facilitate the establishment of a symbolic connection with the application communication. 2, the standard distribution routine will manage the IRP. Before you write the code, I suggest you build an IOCTL for the application to manipulate the drive. at me
In the example, I implemented 4 IOCTL encodings: start_ip_hook (register a filter function function), stop_ip_hook (Logout Filter
Can function), add_filter (install a new filter rule), Clear_Filter (clear all filter rules) 3. For our driver, we must implement one or more filter function functions. I suggest you use a program to generate a typical core driver framework, so you only need to fill in your function code or more
If I use Quicksys to generate my example project. You will see my own drive structure, as shown below:
NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) {// .... dprintf ( "DrvFltIp.SYS: entering DriverEntry / n"); // we have to create the device RtlInitUnicodeString (& deviceNameUnicodeString, NT_DEVICE_NAME); ntStatus = IoCreateDevice (DriverObject, 0, & deviceNameUnicodeString, FILE_DEVICE_DRVFLTIP, 0, FALSE, & deviceObject); if (NT_SUCCESS (ntStatus)) {// Create a symbolic link that Win32 apps can specify to gain access // to this driver / device RtlInitUnicodeString (& deviceLinkUnicodeString, DOS_DEVICE_NAME ); ntStatus = IoCreateSymbolicLink (& deviceLinkUnicodeString, & deviceNameUnicodeString); // .... // Create dispatch points for device control, create, close DriverObject-> MajorFunction [IRP_MJ_CREATE] = DriverObject-> MajorFuncti. on [IRP_MJ_CLOSE] = DriverObject-> MajorFunction [IRP_MJ_DEVICE_CONTROL] = DrvDispatch; DriverObject-> DriverUnload = DrvUnload; (! NT_SUCCESS (ntStatus))} if {dprintf ( ". Error in initialization Unloading ..."); DrvUnload (DriverObject) ;} return ntStatus;} NTSTATUS DrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {// .... switch (irpStack-> MajorFunction) {case IRP_MJ_CREATE: dprintf ( "DrvFltIp.SYS: IRP_MJ_CREATE / n"); break; Case IRP_MJ_CLOSE: DPRINTF ("drvfltip.sys: IRP_MJ_CLOSE / N"); Break;
case IRP_MJ_DEVICE_CONTROL: dprintf ( "DrvFltIp.SYS: IRP_MJ_DEVICE_CONTROL / n"); ioControlCode = irpStack-> Parameters.DeviceIoControl.IoControlCode; switch (ioControlCode) {// ioctl code to start filtering case START_IP_HOOK: {SetFilterFunction (cbFilterFunction); break; } // ioctl to stop filtering case STOP_IP_HOOK: {SetFilterFunction (NULL); break;} // ioctl to add a filter rule case aDD_FILTER: {if (inputBufferLength == sizeof (IPFilter)) {IPFilter * nf; nf = (IPFilter *) obuffer; addfiltertolist (nf);} Break;} // ooctl to free filter rule list case clear_filter: {clearfilterlist (); break;} default: IRP-> iostatus.status = status_invalid_parameter; dprintf ( "DrvFltIp.SYS: unknown IRP_MJ_DEVICE_CONTROL / n"); break;} break;} ntStatus = Irp-> IoStatus.Status; IoCompleteRequest (Irp, IO_NO_INCREMENT); // We never have pending operation so always return the status code. return ntStatus;} VOID DrvUnload (IN PDRIVER_OBJECT DriverObject) {UNICODE_STRING deviceLinkUnicodeString; dprintf ( "DrvFltIp.SYS: Unloading / n"); SetFilterFunction (NULL); // Free any resources ClearFilterList (); // Delete the symbolic link RtlInitUnicodeString ( & DeviceLinkunicodeString, DOS_DEVICE_NAME); IodeleteSymbolicLink (& DeviceLinkunicodeString);
// delete the device object odeletedevice (driverObject-> deviceObject);} We have completed the driver body code, and will be the filter hook code. Registering the filter function in the code above, we have seen the call setFilterFunction (...) function, now we will implement this registration IP
Valid function, he will be implemented in the following steps. 1. First, we must get an IP filter-driven pointer, which is required to drive properly and have run. Now suppose
Before this driver, my user application will load and start IP filtering. 2, we must establish a specific IRP containing the control code for ioctl_pf_set_extension_point. We have to send parameters
Such as the PF_SET_EXTENSION_HOOK_INFO structure contains the filter function pointer. If you want to uninstall a function, you have to take the same step to transfer
A NULL pointer replaces the filter function. 3. Transfer the original IRP to the device driver. Here is a big problem with the drive, it is only one filter function function to be installed at a time. So if other applications have been installed, then
What will not be installed. The next code I will present the function.
NTSTATUS SetFilterFunction (PacketFilterExtensionPtr filterFunction) {NTSTATUS status = STATUS_SUCCESS, waitStatus = STATUS_SUCCESS; UNICODE_STRING filterName; PDEVICE_OBJECT ipDeviceObject = NULL; PFILE_OBJECT ipFileObject = NULL; PF_SET_EXTENSION_HOOK_INFO filterData; KEVENT event; IO_STATUS_BLOCK ioStatus; PIRP irp; dprintf ( "Getting pointer to IpFilterDriver / n "); // first of all, we have to get a pointer to ipFilterDriver Device RtlInitUnicodeString (& filterName, DD_IPFLTRDRVR_DEVICE_NAME); status = IoGetDeviceObjectPointer (& filterName, STANDARD_RIGHTS_ALL, & ipFileObject, & ipDeviceObject); if (NT_SUCCESS (status)) {// initialize the struct with functions parameters filterData.ExtensionPointer = filterFunction; // we need initialize the event used later by // the ipFilterDriver to signal us // when it finished its work KeInitializeEvent (& event, NotificationEvent, FALS E); // we build the irp needed to establish fitler function irp = IoBuildDeviceIoControlRequest (IOCTL_PF_SET_EXTENSION_POINTER, ipDeviceObject, if (irp = NULL!) {// we send the IRP status = IoCallDriver (ipDeviceObject, irp); // and finally, We wait // "Acknowledge" of ipfilter driver if (status == status_pending) {WaitStatus = KewaitForsingleObject (& Event, Executive, KernelMode, false, null); if (WaitStatus! =
STATUS_SUCCESS) dprintf ( "Error waiting for IpFilterDriver response.");} Status = ioStatus.Status; if (NT_SUCCESS (status!)) Dprintf ( "Error, IO error with ipFilterDriver / n");} else {// if we cant allocate the space, // we return the corresponding code error status = STATUS_INSUFFICIENT_RESOURCES; dprintf ( "error building ipFilterDriver IRP / n");} if (ipFileObject = NULL!) ObDereferenceObject (ipFileObject); ipFileObject = NULL; ipDeviceObject = NULL; } Else Dprintf ("ERROR While Getting The Pointer / N); Return Status;} You can see when we complete the processing filter function function, we must reference file objects to get the device driver pointer. When IPFilter
I use an event to notify the IRP process. Filtering function We understand how to develop drivers and how to install filter functions, but we still don't know the filter function. I have said that this function is always called when it is sent or sent to a packet. The system determines how to handle the number according to its return value
According to the package. Below is the state of the function
typedef PF_FORWARD_ACTION (* PacketFilterExtensionPtr) (// Ip Packet Header IN unsigned char * PacketHeader, // Packet. Do not include Header IN unsigned char * Packet, // Packet length. Do not Include length of ip header IN unsigned int PacketLength , // Index number for the interface adapter // over which the packet arrived IN unsigned int RecvInterfaceIndex, // Index number for the interface adapter // over which the packet will be transmitted IN unsigned int SendInterfaceIndex, // IP address for the interface // Adapter That Received The Packet In ipaddr recvlinknexthop, // ip address for the interface adapter // That Will Transmit The Packet in ipaddr sendlinknexthop
Pf_forward_action is an enumeration type PF_FORWARD: Specifying an IP filter driver immediately returns the packet to an IP stack. For the local package, IP will be sent to the top of the stack. If you want to send it to another computer, the IP package will also be sent immediately. PF_DROP: Specifies that the IP filter driver immediately discards the packet from the IP stack. The IP packet will be lost. PF_pass: Specify the IP filter driver filtering the package and returns the response result to the IP stack. IP filtering How to deal with this packet depends on his right
Pack the setting of the filtered API. When the filter hook finds that he cannot handle the packet to pay the IP filtering to process this package when it is handed over. Although the text of DDK only introduces the above three return values, it will find another value for returning when you view the PFHOK.H file.
That is pf_ICMP_NO_DROP. I suspect that this value is similar to the discard package and provides ICMP package error message. As you can see in the definition of the filter function function, the package and his header are passed by a pointer. So you can modify the package
Head or content then transfer it away. This is very useful when writing, such as a NAT program. If we change its target address, then the packet
Will transfer the direction you change. In my implementation, the filter function function compares the rules defined by each filter rule function in the rule linked list. This rule
The linked list will be created when you receive a START_IP_HOOK control code at runtime. This will see it in the source code. In my first version, I only achieve a relatively simple version, so many people are inquiring if I can help them develop
A more practical application. So I am now upgraded a relatively complex version. There is a small package filter application in this new example.
. In this new application, you can join some of your universal firewall rules. In the first version, this app has two parts. User Application: It is an MFC application to manage various filtering rules. This application sends a variety of filtering rules to the application
And decide when starting to start filtration. Filtering Actions are divided into a filtering rule in accordance with your needs. Send Add or Remove Commands to increase or delete this filtering rule. Installation rules. When you define a filter rule, press the installation and pressing twisting to send him to the drive. Start filtration. You only need to press the start button to start filtering. Filter driver: The driver is filtered in accordance with the filtering rules sent by the user application, and each packet sent and received. Filter hook drivers must be in the same directory with the user application. Why use this method to develop a firewall? Of course, it is not the only way to develop firewalls under Windows, and other NDIS firewalls, TDI firewalls, Winsock layer fireproof
Wall, package filtration API, etc. from multiple methods. So I will explain some of the advantages and disadvantages that use the filter hook drive to develop firewalls. Develop firewall procedures based on filter hook methods, there is better elasticity. You can filter all IP packets before entering the IP stack. Of course
You can't filter the more data of the next number, such as NIC hardware frames. Then you need to write NDIS driver to filter it, then you will get better
Flexibility but it is also more difficult to develop. Based on the filter hook method to develop a firewall program is not a simple and effective way. Installing and implementing a firewall only a few simple
process. Of course, the package filter API will be simpler, but you will lose more flexibility, you can't change the package at will. Conclusion: Filter hook driver is not the best way to develop firewalls, but it is not the worst. So why can't you list it as a development?
What about the commercial software? The answer is simple, but this driver is not the best, but it is not the worst. I mentioned again that it is only because of filtering hook driver.
Install one at a time. We can develop a better, it can be filtered for hundreds of applications, which will not be used with other
Filtering program conflicts. In the microsoft document, there is another shortcoming of this method. That is although the DDK document says you can send and receive packets.
It is not true for what you want. You can arbitrarily change all received packets, but can only change the IP, TCP, UDP, and ICMP headers. I don't know why? Microsoft also introduced another unlimited firewall hook driver for the WindowsXP system. Its load is very simple, but Microsoft and
It is not recommended to use it to develop. Because it runs on the upper layer of the network stack, it is too high. Maybe this driver will be in the next version of Windows
disappear. Conclusion OK, all of them are finished. I know this is not the best way to develop a firewall (I have mentioned its advantages and disadvantages). But I think this is
All a good starting point for the firewall developing feeling, or because of reading this article, it is more interesting to the firewall. I hope that you have already understood the Filter-Hook Driver and prepare to develop a more powerful firewall.