Driver application technology in .NET framework
- Key technical analysis of the development of single-machine version of the network firewall with .NET and NDIS HOOK DRIVER
The N-Byte network watchman is a single-machine version of the network security tool developed by our team. In short, it is a personal version of the personal version of the .NET. In the development of N-Byte Network Watcher 1.0, we used NDis Hook Driver technology to implement network package filtering, which enables our N-Byte network watchmakers to filter network packages in the network layer, thereby achieving powerful functions .
Since the main program of our software is written in C #, there is no driver control function with similar Deviceiocontrol function functions in C #, and the driver under Ndis Hook Driver technology is written in the C language under DDK, in order to enable the master The program controls and communicates with the driver, we use the following designs:
In the above scheme, we need a module DriverDll.dll responsible for the main program and the NDIS Hook Driver driver communication and control, and the module of the package information in a package 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.
We face two questions on the .NET application using the driver.
1. How to implement the function of the .NET application to control the driver?
2. How to pass unmanaged data types from the driver to the .NET application?
The following is a detailed solution for these issues:
How to implement the function of the .NET application to control the driver?
We use DriverDll.dll written by managed C to implement direct control of the driver, and the main program implements indirect control over the driver by calling the method. For example, we define the Start_IP_HOOK constant in the nbyte.h file to use parameters for the driver to open the driver package filtering, and we define the IOCTRL managed category in the managed C module and define the following to buffers. Write parameters:
/ / Write data to the buffer.
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 define a public function to provide the main program call:
// Start packet filtering
Bool Startiphook ()
{
Return (WriteIO (Start_ip_hook, null, 0) == Success
}
In this way, as long as the object IC of IOCTRL is declared in the main program, it can be opened via IC.Startiphook (), and the driving of the driver filtering can be implemented, and the driver can be used to perform other operations, such as add, modify Packet filtering rules.
How to pass unmanaged data types from the driver to the .NET application?
In order to be able to output a security log, we must let the main program get the package information in the driver. Use the semaphore mechanism that can easily implement the information transfer between the drivers and the non-hosting code, then? This requires the .NET application to deliver unmanaged data types access_info. In nbyte.h, we define this Access_info structure: typedef struct _access_info
{
Ushort protocol;
Ulong sourceIP;
Ulong destinationip;
Ushort sourceport;
USHORT DESTINATIONPORT;
Access_info;
Obviously, it is not possible to transfer the non-hosting data type directly, we need to convert it. First, we define a few package information parameters to be passed in the Ioctrl class:
Public __gc class octrl
{
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 these parameters 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, you need to package them to be easily handled by the master program, so that I use C # to implement the InfoEvent class to encapsulate this information:
// This class encapsulates the details of the packet, which can be passed between its modules through the event.
Public Class InfoEvent: Eventargs
{
String sinfo; // The private member used to store the output information
Public int startth; //commonfunction.sport array length
Public ushort protocol; // Network Communication Protocol Type
Public uint sourceIP; // Packet source IP
Public uint destinationip; // Destination IP of Packet
PUBLIC USHORT SOURCEPORT; / / Packet source port
Public Ushort DestinationPort; // Destination Port of Packet
..................................
}
Below the InfoProvider Driver Information Provider class that is implemented with hosted C to the main program, you need to use a commission to generate an event:
// Declare the commissioned event to transfer 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, run this method in the main program, using the event function OnDriverInfo in this method:
// The process used to get the driver information will turn on the process in the main program.
Void getInfothreadproc ()
{
This-> hevent = Openevent (Synchronize, False, "Nbevent");
IF (! IC-> getDriverhandle ())
{
Return;
}
While (True)
{
f (! hever)
EXITTHREAD (0);
WaitforsingleObject (this-> hevent, infinite);
Npackets ;
IC-> getaccessinfo ();
IC-> resetEvent ();
/ / Define an object that a primary program can identify and pass overDriverInfo to the main program.
InfoEvent * ie = new infoEvent (IC-> Protocol, IC-> SourceIP, IC-> DestinationIP, IC-> Sourceport, IC-> DestinationPort);
OnDriverInfo (this, IE);
}
IC-> ClosedriverHandle ();
Return;
}
In the main program, I will open this process and define the handlers of the OndriverInfo deAlwithInfo:
Pinfo = new infoProvider ();
/ / Turn on the process of switching information with the drive
FilTerthread = New Thread (new threadstart (Pinfo.getInfothreadProc);
FilTerthread.isbackground = true;
FilTerthread.start ();
Pinfo.ondriverinfo = new infoProvider.driverinfo (DeALWITHINFO);
This master program can add the processing of the InfoEvent object in the DealWithInfo function. It can be seen that through the conversion of the intermediate module IOCTRL, the acquisition and processing of the non-managed data type in the driver is implemented. Net main program.