The N-byte network maintainer is a stand-alone network security tool. In short, it is a personal firewall developed with. net. In the development of the N-byte network maintainer Version 1.0, the NDIS Hook Driver technology is used to implement the network packet filtering function, which enables the n-byte network maintainer to filter network packets at the network layer, to achieve powerful functions.
Because the software masterProgramIt is written in C #. C # does not provide the driver control function similar to the deviceiocontrol function, the driver program of NDIS Hook driver is written in C language of DDK. In order to control and communicate with each other, the following design scheme is adopted:
In the above scheme, a module responsible for communication and control between the main program and the NDIS Hook driver is required. DLL, and a module that encapsulates package information in the driver written in C # can send this driver information to the main program, the main program can identify and operate the data type in the module.
There are two problems with the use of drivers for. NET applications:
1. How to Implement the. NET application control driver function?
2. How to transfer an unmanaged data type from a driver to A. NET application?
The following is a detailed solution to these problems:
How to Implement the. NET application control driver function?
Use the driverdll. dll compiled by hosting C ++ to directly control the driver. The main program calls the method to indirectly control the driver. For example, in nbyte. in the H file, the start_ip_hook constant is defined as the parameter used to pass to the driver to enable the driver package filtering function, the ioctrl Managed class is defined in the managed C ++ module and the following method for writing parameters to the buffer zone is defined:
// Write data to the buffer zone.
DWORD writeio (DWORD code, pvoid buffer, DWORD count)
{
If (hdriverhandle = NULL)
Return error_driver_handle;
DWORD bytesreturned;
Bool returncode = deviceiocontrol (hdriverhandle,
Code,
Buffer,
Count,
Null,
0,
& Bytesreturned,
Null );
If (! Returncode)
Return error_io_ctrl;
Return success;
}
Of course it is not convenient to use this method directly, so a public function is defined to be provided to the main program for calling:
// Start packet filtering
Bool startiphook ()
{
Return (writeio (start_ip_hook, null, 0) = success );
}
In this way, as long as the ioctrl object IC is declared in the main program, you can use the IC. startiphook () can be used to enable the driver filter function. In the same way, other operations can be performed on the driver, such as adding and modifying the encapsulation filter rules.
How does one transmit an unmanaged data type from a driver to A. NET application?
To output security logs, the main program must obtain the packet information in the driver. The semaphore mechanism can be used to conveniently implement the driver and unmanagedCodeSo what about the managed code? This requires passing the unmanaged data type access_info to the. NET application. In nbyte. H, the access_info structure is defined as follows:
Typedef struct _ access_info
{
Ushort protocol;
Ulong sourceip;
Ulong destinationip;
Ushort sourceport;
Ushort destinationport;
} Access_info;
Obviously, it is not possible to directly pass the unmanaged data type. You need to convert it. First, several packet information parameters to be passed are defined in the ioctrl class:
Public _ GC class ioctrl
{
Public:
Ushort protocol; // Internet protocol type
Ulong sourceip; // source IP address
Ulong destinationip; // destination IP address
Ushort sourceport; // Source Port
Ushort destinationport; // destination port
..................
}
Then, assign values to these parameters in the getaccessinfo () function:
Void getaccessinfo ()
{
Access_info AI;
Bool result = (readio (get_info, & AI, sizeof (AI) = success );
This-> protocol = ai. Protocol;
This-> sourceip = ai. sourceip;
This-> destinationip = ai. destinationip;
This-> sourceport = ai. sourceport;
This-> destinationport = ai. destinationport;
}
Since this information is obtained in the ioctrl class, it needs to be encapsulated into a data type that is easy to process by the main program. In this way, the infoevent class is implemented in C # To encapsulate this information:
// This class encapsulates the detailed information of data packets, which can be transmitted between modules through events.
Public class infoevent: eventargs
{
String SINFO; // Private member used to store output information
Public int plength; // length of the commonfunction. Sport Array
Public ushort protocol; // network communication protocol type
Public uint sourceip; // The Source IP address of the Data Packet
Public uint destinationip; // destination IP address of the Data Packet
Public ushort sourceport; // The source port of the Data Packet
Public ushort destinationport; // destination port of the Data Packet
....................................
}
In the following information provider class of the infoprovider driver implemented by hosting C ++, an infoevent class object is passed to the main program. An event needs to be generated using a delegate:
// Declare a delegate event to transmit data to the main program.
_ Delegate void driverinfo (Object * sender, infoevent * E );
// Declare the RESPONSE event function.
_ Event driverinfo * ondriverinfo;
Then define a method in the infoprovider driver information provider class and run this method in the main program as a thread. The event function ondriverinfo is used in this method:
// The process used to obtain the driver information. The process is enabled in the main program.
Void getinfothreadproc ()
{
This-> hevent = openevent (synchronize, false, "nbevent ");
If (! IC-> getdriverhandle ())
{
Return;
}
While (true)
{
F (! Hevent)
Exitthread (0 );
Waitforsingleobject (this-> hevent, infinite );
Npackets ++;
IC-> getaccessinfo ();
IC-> resetevent ();
// Define an object that can be recognized by the main program and pass it to the main program through ondriverinfo.
Infoevent * Ie = new infoevent (IC-> protocol, IC-> sourceip, IC-> destinationip, IC-> sourceport, IC-> destinationport );
Ondriverinfo (this, ie );
}
IC-> closedriverhandle ();
Return;
}
In the main program, this process is enabled and the ondriverinfo processing function dealwithinfo is defined:
Pinfo = new infoprovider ();
// Enable the process of information exchange with the driver
Filterthread = new thread (New threadstart (pinfo. getinfothreadproc ));
Filterthread. isbackground = true;
Filterthread. Start ();
Pinfo. ondriverinfo + = new infoprovider. driverinfo (dealwithinfo );
In this way, the main program can add the processing of the infoevent object to the dealwithinfo function. The conversion of ioctrl in the intermediate module enables the. Net main program to obtain and process unmanaged Data Types in the driver.