Key Technologies for implementing NDIS Hook Firewall

Source: Internet
Author: User

Key Technologies for implementing NDIS Hook Firewall

Firewall cannot be mentioned when talking about network security. At present, most firewalls in China adopt the TDI technology, and NDIS can be regarded as a relatively advanced technology (if you don't think so, it can only mean that I am outdated, haha) technical details about implementing the NDIS firewall are missing on the Internet. after two days of searching materials and analyzing the existing source code, coupled with the basis of the previous NDIS programming, I quickly got a preliminary understanding of this technology.

The detailed analysis only involves how to hook the kernel functions exported to NDIS. sys. As for how to handle the hook function, it depends on the specific functional requirements. We hope that the following technical details can solve your problem.

Implementation ideas:
(1) similar to user-mode application, we need to get the memory base address of the file where the hook function is located.

(2) Determine whether the first two bytes of the base address are 'mz', and then use the last member e_lfanew of the DOS header structure to obtain pimage_nt_headers.
The address of the function export directory.

(3) In NDIS. find the target function ndisregisterprotocol in the export directory of SYS, find the target function, and get the target function address. save the original function address and replace it with our own new_ndisregisterprotocol.

(4) implement different filtering based on specific functional requirements.

There is no way to explain it. It is richer and more attractive than displaying the implementation code. The following describes the implementation code.

(1)
For example, you can use the depends.exe tool to view the function exported by NDIS. SYS. You can find that ndisregisterprotocol is included, and we will hook this function.

First, obtain the memory base address of NDIS. sys.
Here, the native API zwquerysysteminformation is used to obtain information about the kernel modules loaded by the system.

The system module information structure is as follows:

Typedef struct _ system_module_information {
Ulong reserved [2];
Pvoid base;
Ulong size;
Ulong flags;
Ushort index;
Ushort unknown;
Ushort loadcount;
Ushort modulenameoffset;
Char imagename [255];
} System_module_information, * psystem_module_information;

The memory base function of the specified module is as follows:

Void * find_system_dll (const char * name)
{
Ulong I, n, * q;
Psystem_module_information P;
Void * base;
 
/*
* Obtain the memory size required for system module information.
*/
Zwquerysysteminformation (systemmoduleinformation, & N, 0, & N );
Q = (ulong *) exallocatepool (pagedpool, N );
Zwquerysysteminformation (systemmoduleinformation, Q, N * sizeof (* q), 0 );

 
/*
* Zwquerysysteminformation: the number of modules and information of each module are returned in the memory change.
* The number of modules is the first four bytes of memory, followed by the arrangement of information about all modules
*/
P = (psystem_module_information) (q + 1 );

Base = NULL;
For (I = 0; I <* q; I ++)
{
/*
* For example: imagename: Windows/system32/NDIS. sys, modulenameoffset is 0x11.
*/
If (_ stricmp (P [I]. imagename + P [I]. modulenameoffset, name) = 0)
{
/*
* Obtain the memory base address of the NDIS. SYS module.
*/
Base = P [I]. base;

Kdprint ("[ndis_hk] find_system_dll: % s; base = 0x % x; size = 0x % x/N", name, base, P [I]. size ));
Break;
}
}

Exfreepool (Q );

Return base;
}

(2)We have obtained the memory base address of the NDIS. SYS module. The following figure shows the virtual address of the exported function directory based on the PE file format.
 

(3)Find the target function ndisregisterprotocol, obtain the address of the target function in the system kernel, save and replace the original address.

/*
* Base: the memory base address of the NDIS. SYS module.
*
* FN: name of the function to be hooked
*
* New_fn: New Function address
*/

Void * fix_export (char * base, const char * fN, void * new_fn)
{
Pimage_dos_header dos_hdr;
Pimage_nt_headers nt_hdr;
Pimage_export_directory export_dir;
Ulong * fn_name, * fn_addr, I;

/*
* Check whether the file is valid. The first two bytes are 'mz' and the value is 0x5a4d in the order of little-Endian.
*/
Dos_hdr = (pimage_dos_header) base;

If (dos_hdr-> e_magic! = Image_dos_signature)
Return NULL;

/*
* The last member of the DOS header obtains the offset of the NT header from the file, and then calculates the virtual address of the NT header.
*/
Nt_hdr = (pimage_nt_headers) (base + dos_hdr-> e_lfanew );

Export_dir = (pimage_export_directory) (base + nt_hdr-> optionalheader. datadirectory [image_directory_entry_export]. virtualaddress );
 
 
/*
* Obtain the address of the exported function name array. Each element in the array is the address of the exported function name (pointer to the exported function name)
*/
Fn_name = (ulong *) (base + export_dir-> addressofnames );
/*
* Each element in the fn_addr array is the address of the exported function address.
*/
Fn_addr = (ulong *) (base + export_dir-> addressoffunctions );
 
 
For (I = 0; I <export_dir-> numberofnames; I ++, fn_name ++, fn_addr ++)
{
If (strcmp (FN, base + * fn_name) = 0)
{
/*
* Obtain the virtual memory address corresponding to the function name.
*/
Void * old_addr = base + * fn_addr;

/*
* Replace the original function address with our new function address (relative to the base address of the export module ).
*/
Replace_value_safe (fn_addr, (char *) new_fn-base );

Return old_addr;
}
}

Return NULL;
}

Boolean replace_value_safe (ulong * ADDR, ulong value)
{
MDL * MDL;
Ulong * pai_addr;

MDL = ioallocatemdl (ADDR, sizeof (value), false, false, null );
If (MDL = NULL)
Return false;
 
/*
* Checks whether the specified operation is supported and locks the page to avoid page missing errors.
* If the detected operation is not supported by this function, an exception is thrown. Therefore, try/try t to handle the exception.
*/
_ Try
{
MMP robeandlockpages (MDL, kernelmode, iomodifyaccess );
 
} _ Handler T (exception_execute_handler)
{
Kdprint ("[ndis_hk] replace_value_safe: FIG! /N "));
Return false;
}

Pai_addr = (ulong *) mmgetsystemaddressformdl (MDL );

/*
* Modify the function address
*/
* (Ulong *) pai_addr = value;

Mmunlockpages (MDL );
Iofreemdl (MDL );
Return true;
}

(4)Filter in new functions

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.