(Reproduced) Intermediate layer drive work principle

xiaoxiao2021-03-06  38

The principle of intermediate layer drive work is transferred from:

http://www.nsfocus.net/

Author: noble

Source: http://www.nsfocus.com

Date: 2005-01-06

If there is any error, please contact the author, thank you.

(1) Register common sense:

1) The registration table for the device database is:

HKLM / System / CurrentControlSet / Enum /

Enum child is a device database, all installed in the data inventory, and is recognized by the system.

All users (including administrators) cannot change the contents of the ENUM item. This is to protect the integrity of the operating system and the installed equipment. To change the settings of the device, you should use Device Manager.

In order to be realistic in the device manager, non-plug-and-play, and all devices that are not connected to the computer, you should first type in the command interpreter set devmgr_show_nonpresent_devices = 1, then start the device manager, These devices can be deleted and reconfigured in the Device Manager.

2) The registration table in which the hardware device class is:

HKLM / System / CurrentControlSet / Control / Class /

The configuration information of the hardware device class is stored under the Class item. Each child under the Class item represents a device class, the name of the subkey uses a "unique global identifier (GuIS)", which stores the configuration information of the device class. At each class identifier, there will be a child named in the 4-digit number, which represents the specific device in the device class, and other configuration data applies only to this specific device.

If the device class of the NIC is {4D36E972-E325-11CE-BFC1-08002BE10318}, and assume that the 4-in-the-name named child name is 0005.

among them

HKLM / SYSTEM / CURRENTCONTROLSET / CLASS / {4D36E972-E325-11CE-BFC1-08002BE10318} / 0005 / LINKAGE /:

EXPORT: Represents the device name of the device output in the device name space.

RootDevice: GUID represents the current device. The middle layer is driven here. There are two guids, the first is its own GUID, the second is the lower miniport of the intermediate layer driven.

Upperbind: The NDIS protocol driver or NDIS intermediate layer driven represents the upper layer. When a protocol is driven to bind the MiniPort device, the name of this protocol driven must appear in the string of Upperbind health, otherwise it cannot be binding. That is, the string of Upperbind is determined that the protocol driver (of course, the protocol that also includes the intermediate layer driver registration) and the current MiniPort device binding, that is, it determines the upper and lower layer binding relationship of NDIS.

Note: After the intermediate layer driver is added, the intermediate layer driver is only inserted into the middle of the network card and the corresponding protocol, and does not insert into the virtual network card (such as a network card device after installing the virtual machine) and the other protocol.

3) The registration table in which the driver is located is:

HKLM / System / CurrentControlSet / Services

ENUM child

Usually if an enum child is existing under a service, the service is used to control an instance of the device below, which stores the instance of the device below. Users do not try to modify the content of the child, because each system is started, the content of the child will be rewritten. Linkage child

Value item BIND

Store the minimum layer of small port device instances (ie, MINIPORT) that the protocol is located.

Payments EXPORT

The object that stores the service must be accessed, the object must already be installed in the system, and the service can be used.

Value Route

Specifies the child Linkage to get binding data there.

Parameters / adapters / child

Here, we only explain the meaning of this child in the middle layer drive. To do this, we assume that XXXX in the HKLM / System / CurrentControlSet / Services / XXXX currently discussed is the intermediate layer driver.

For intermediate layer drivers, the child contains a child, which is named after the GUID of the lower miniPort device that is binding our current intermediate layer. In my system, the effect is as follows:

{102454C2-9DB3-42A1-B4CF-6A8B67A516C0}

In {102454C2-9DB3-42A1-B4CF-6A8B67A516C0} children have a health, named Upperbindings, the healthy value is the current intermediate-driven miniPort device name, in my system, as the next health:

/ Device / {5BF5A311-13E4-4746-8865-339DDD6C73AF}

(2) Intermediate layer drive

In our function NDIS_PROTOCOL_CHARACTERISTICS-> BindAdapterHandler (), a series of function calls (such as NdisOpenProtocolConfiguration, NdisReadConfiguration) to access the registry, they are actually accessing Parameters / Adapters / {102454C2-9DB3-42A1-B4CF-6A8B67A516C0} subkey.

Note that the second parameter of the function ndis_protocol_characteristics-> bindadapterHandler () is systemspect1, if we installed XPASSTHRU, then it refers to the following strings:

Xfilter / parameters / adapters / {102454C2-9DB3-42A1-B4CF-6A8B67A516C0}

The xfilter is XPASSTHRU, and {102454C2-9DB3-42A1-B4CF-6A8B67A516C0} is different in different systems.

Function ndisopenprotocolconfiguration () actually constructs RTL_QUERY in query registry

_REGISTRY_TABLE Structure (This structure is using the function RTLQueryRegistryVALUES () query registry is used). And encapsulate this structure into the NDIS_WRAPPER_CONFIGURATION_HANDLE structure, and then the second parameter of NdisopenProtocolConfiguration () is returned.

In fact, the meaning of the RTL_Query_Registry_Table structure of ndisopenprotocolconfiguration () constructed is the Query HKLM / System / CurrentControlSet / Services / XFilter / parameters / adapters / {

Juice 102454C2-9DB3-42A1-B4CF-6A8B67A516C0} / under different (Xfilter) is different from different intermediate layers, {102454C2-9DB3-42A1-B4CF-6A8B67A516C0} is different in different systems, and below These comments). The function ndisreadconfiguration () has two functions, which first modifies in the function ndisopenprotocolconf

IGURATION () constructed RTL_Query_registry_table structure. That is, inquiry HKLM / SYSTEM

/ Currentcontrolset / services / xfilter / parameters / adapters / {102454C2-9DB3-42A1-B4CF-6A8B6

Based on the basis of 7A516C0}, a health is added to hklm / system / currentcontrolset / services / xfilter / parameters / adapters / {102454C2-9DB3-42A1-B4CF-6A8B67A516C0} / Upperbindings. The function ndisreadConfiguration () then calls the function RTLQueryRegistryVALUES () queries the new constructed of this registry and stores the result in the second parameter when the function ndisreadConfiguration () is called. In my system, RTLQueryRegistryValues ​​() reads this new construction of this registry is: / device / {5BF5A311-13E4-4746-8865-339DDD6C73AF} (later we call RESULT1), it is actually us The device output of the registered intermediate layer driver (which is constructed is / device / guid).

In fact, the equipment we read this intermediate layer driver (ie, the numerical value we just read ", RESULT1) only used in the back function ndisiminitializedeviceInstanceex (), and Result1 is the first as a function ndisiminitializeDeviceInstanceex () Two parameters.

There is a place to be confused here, that is, in the function bindadapterHandler (), once the function ndisopenadapter () is called, why should I call a function ndisiminitializedEviceInstanceex () to initialize our middle layer to drive her own MiniPort (because functions NdisiminitializedEviceInstanceex () parameters are Result1, while Result1 represents our intermediate-driven miniPort. In order to explain this reason, let's first assume it.

We assume that our system has an intermediate layer driver (assuming to XPASSTRHU), in the above figure, PROT-IM and MiniPort-IM represent the protocol driver and small port driver of our intermediate layer driver, Prot-TCPIP representative true The protocol driver, the MiniPort-NIC representative is really a small port driver for the NIC.

When PROT-TCPIP needs to send data, the function ndissend () is called, in fact, it will call the sending data function in the MiniPort-IM, but the MiniPort-IM and MiniPort-NIC have no contact, and the data cannot be sent according to regularity to miniport-nic of. But we can see that Prot-IM can send data with MiniPort-NIC, so we must link MiniPort-IM and PROT-IM. In addition, when MiniPort-NIC needs to submit data to Prot-TCPIP, only data can be submitted to Prot-IM, and Prot-IM can only be linked by MiniPort-IM to Prot-TCPIP.

So you must link PROT-IM and MinIPort-IM. Some people say that these two things are all in our middle-level drive registration. Is it also impossible to contact? Yes, but no matter what you have to pass by you can contact them! Below we will introduce the contact method.

In XPASSTHRU as an example, we have a ADAPT structure in its function protocolbindadapter () (this structure is defined by the user). When calling the function ProtocolBindAdapter () calls the function NdisOpenAdapter () to bind is & Adapt-> BindingHandle as a function NdisOpenAdapter () third argument, so Adapt-> BindingHandle points to the NDIS_OPEN_BLOCK1 (note that call functions NdisOpenAdapter ( The third parameter at the time of returning the NDIS_OPEN_BLOCK pointer after the binding is bound). The function protocolbindadapter () will then call the function ndisiminitializeDeviceInstanceex (), which will further call the NDIS_MINIPORT_CHARACTERISTISTISTICS-> InitializeHandler () function of the XPASSTHRU. Above we discussed that the second parameter in NdisiminitializedEviceInstanceex () is a small port-driven device instance (ie, the above RESULT1) registered with the XPASSTHRU. In the function ndisiminitializeDeviceInstanceEx (), the corresponding MiniPort structure is found according to the device name (RESULT1), and the pointer is passed to the NDIS_MINIPORT_CHARACTICS-> INITIALIPORT_CHARACTICS-> INITIALIPORT_CHARACTERISTICS-> INITIALIGIPORTLER () function (referred to as the initializehandler () function). In the initializehandler () function, the MiniPort structure is further assigned to Adapt-> MiniPortHandle (Adapt is the structure that is allocated in the function protocolbindadapter ()).

Such data structures include two pointers, one pointing to NDIS_Open_Block1, the other pointing to MiniPort-IM, and ndis_open_block1 and prot-imin are closely linked, so Adapt is closely linked to Prot-Im and MiniPort-Im. . Also note that NDIS_MINIPORT_BLOCK-> DeviceContext is to our Adapt structure, which is completed in the function ndisiminitializedeviceInstanceEx (). Talking about it is also the binding from Adapt-> MiniPorthandle to MiniPort in the function ndisiminitializeDeviceInstanceex (), so the interconnection of Adapt and MiniPort is completed in the function ndisiminitializeDeviceInstanceex ().

The function initializeHandler () can use the handle of the handle to get our Adapt structure. The function of this function is NdisimGetDeviceContext (). The parameter of this function is a ndis_handle type, but this parameter is converted into a NDIS_MINIPORT_BLOCK structure. And return NDIS_MINIPORT_BLOCK-> DEVICECONTEXT.

In the function ndisopenadapter (), in addition to the completion mentioned above, the point to NDAPT-> BindingHandle to NDIS_OPEN_BLOCK1, but also completed the pointing by ndis_open_block1-> protocolbindingcontext to Adapt, the function ndisopenadapter () was completed. Adapt and NDIS_Open_Block1 are connected to each other (ie, pointers point each other).

Speaking here, our above picture is improved as shown below:

Here's you can do some hook, such as hook to the Open_BLOCK structure, Hook to Adapt, etc., this is not introduced here, huh, huh.

转载请注明原文地址:https://www.9cbs.com/read-72131.html

New Post(0)