C # development network firewall technology analysis
Author: Unknown
N-BYTE Network Watcher is a single-machine version of the network security tool, in short, is a personal version of the personal version of the. In the development of N-BYTE Network Watcher 1.0, Ndis Hook Driver technology uses NDIS Hook Driver technology to implement network packet filtering, which enables N-BYTE network watchmakers to filter network packages in the network layer, thereby achieving powerful functions.
Since the main program of the software is written in C #, there is no drive device 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 main program The control and mutual communication of the driver uses the following design:
In the above scheme, 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 The program can identify and operate the data type in the module.
On the .NET application uses drivers, face two questions:
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?
DRIVERDLL.DLL written in hosted C implements direct control of the driver, and the main program implements indirect control over the driver by calling the method. For example, in the NByte.h file, the Start_IP_HOOK constant is used as a parameter to turn on the driver package to open the driver package filter, which defines the IOCTRL hosted class in the managed C module and defines the following to the buffer write. Parameter method:
/ / 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, you must give the main program to 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, this is defined in this Access_info structure:
Typedef struct _access_info
{Ushort Protocol; Ulong Sourceip; Ulong DestinationPort; Ushort DestinationPort;} Access_info; Obviously, directly transmitting the non-managed data type is not possible, need to be converted. First, in the octrl class define a few package information parameters to be passed:
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 these parameters to these parameters in the getAccessinfo () function:
Void getAccessinfo () {Access_info ai; Bool Result = (Readio) == 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 encapsulate the data type that is easy to handle in a master program so that the InfoEvent class is implemented with C # 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; // Used to store the private member of the output information public INT PLENGTH; //commonfunction.sport array length public ushort protocol; // network communication protocol type public uint source sourceIP; // data packet of PUBLIC UINT SOURCEIP; // Source IP Public Uint DestinationIP; // Destination IP Public Ushort Source Region; // 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 (!) EXITTHREAD (0); WaitForsingleObject (this-> hevent, infinite); npackets ; IC-> getAccessinfo (); IC-> resetEvent (); // Define a primary program can be identified Object, pass the OnDriverInfo 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, this process will be turned on 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.