📜 ⬆️ ⬇️

We write our intermediate driver. Part 1

Hello, dear habrayuzer!
Have you ever wondered how the sniffer works and what it is? Or how your favorite firewall protects you from trojans and other nastiness at the network level? Anyway, how does it work? I am sure that you asked yourself this kind of questions, but still, if not, then I’ll tell you in part about it. Starting from this article, we will gradually master the writing of our sniffer-like driver. Today we will look at some of the general provisions that we will need to understand everything that will happen in subsequent articles. Before reading this article, so that you begin to develop a more or less clear picture, I recommend you to read the past topic Overview of the drivers of the NDIS specification

Anyone interested is asking for cat.

I’ll say right away that the article is focused on users who have little knowledge of this topic, so I will try to explain some things in detail. Well, let's get started.

What do we need and where to start?


In many forums, very often you can see the issues of such a setting: “I am a novice programmer, I want to write drivers, but I don’t know how. Where should I start? ”Therefore, trying to describe everything consistently, I found it necessary to tell us what we need.
')
If you decide to start writing drivers, whether they are regular drivers or whether they are networked, you will definitely need to download the WDK-Windows Driver Kits (also known as NT DDK). By installing this stuff on your workhorse, you will become armed to write your driver. Together with the WDK comes its own documentation, headings, or examples (we will need them, becoming the skeleton of our future driver). Working in Visual Studio, you can also download a VS plugin called Visual DDK. This integration tool will help you write (and build) drivers directly from Visual Studio. Here you can find a brief help on the use of this tool. I want to emphasize that the installation of Visual DDK for working with drivers from the studio is not at all mandatory; you can write and assemble your drivers in VS without this tool! This is just a plugin.

We will consider an example of an intermediate driver from the WDK and modify it. Why interim? Those familiar with the previous article or simply summarizing in the NDIS specification know that the intermediate network driver combines the behavior of both protocol drivers and miniport drivers, being a layer between them. Thus, this example can cover at least partially all types of NDIS drivers.

So, the Passthru driver from the WDK will be the skeleton of our driver. By installing the WDK, you can find its source in the \ src \ network \ ndis \ passthru directory. More information about this source can be found here . What does this driver do? So far, nothing, he just is and everything. What will our driver do? It will play the role of a sniffer, accepting and sending packets, receiving information about them and possibly blocking or modifying it. To begin with, we will add some functionality to it, write a client program through which we will communicate with our driver, but this will be only in the next articles, but for now we will study a little theory.

A bit of theory


As you probably know, the DriverEntry function is an analogue of the main function in the drivers, the intermediate driver has a number of things he needs to do before starting to function. And he should do the following in DriverEntry:

That's all. Remember in the last article I wrote about the callback system of the miniport and protocol drivers? So, performing these 4 actions, the intermediate driver registers its callback functions here. If you have previously dealt with miniport and / or protocol drivers, you will notice that the NdisIMRegisterLayeredMiniport function is very similar to the NdisMRegisterMiniport function (called when a non-virtual adapter is registered), and when creating both a virtual protocol and a non-virtual protocol, one and the same same function NdisRegisterProtocol. Initially, you fill in the fields of the NDIS_PROTOCOL_CHARACTERISTICS and NDIS_MINIPORT_CHARACTERISTICS structures (the names of the used callbacks are recorded here), and then pass them as parameters to the corresponding functions.

Now let's talk a bit about sniffers.

A little bit about sniffer, quite a bit


A sniffer is a driver that intercepts and possibly modifies the network traffic of a local computer or all computers of the current network segment. I hate everything you know what it is and at least once in your life used it or at least just saw it. Let's consider the possible schemes for constructing a sniffer:
  1. The sniffer is an intermediate driver that is stuck in all the available bindings of the protocols to the adapters. This is actually the easiest way possible. In addition to the advantages, each method has its drawbacks:
    • to make new bindings work, you need to restart all network adapters present in the system;
    • if there is more than one network adapter in the system, the sniffer has to either restrict interception to only one subnetwork, or prohibit routing, or create more than one virtual adapter;
    • each time a new adapter, protocol, or intermediate driver appears in the system, it is necessary to reconfigure protocol bindings to adapters. If this is not done, the sniffer, at best, will stop intercepting some of the traffic, and at worst, it will crash the system altogether;
    • if the processor is slow, the memory is low, and the network channel is very fast, slowing down the system operation by the intermediate driver can become critical.

  2. The sniffer is a driver filter. What is meant by this? And the following is implied: we kind of join a device that we suspect (each driver has its own device), for example, on \ Device \ Tcp (this device is the driver-protocol tcpip.sys), and after that each IRP directed to this device first sent to our driver. Again the disadvantages:
    • driver filter can intercept only those information flows that are implemented through the IRP, i.e. only information flows between protocol drivers and their clients;
    • the driver-filter should be loaded before all the kernel-mode clients of the device of interest to us, otherwise some of the traffic will go past;
    • driver filter greatly slows down the system;
    • it is very difficult to properly debug the driver filter (we will talk about debugging in subsequent articles). There can be a lot of various glitches.

  3. The sniffer is a protocol driver that binds to all adapters in the system. So, almost all sniffers intercept incoming traffic, including WinPCAP and Microsoft Network Monitor ( outgoing traffic is intercepted according to scheme 5). The method is almost perfect.
  4. Sniffer is a regular driver, whose functions are called from NDIS as needed. This is how Windows XP's built-in packet filter works. No one else can work this way, since support for such a driver should be initially incorporated into NDIS by Microsoft programmers.
  5. The sniffer is a regular driver that just blatantly patches NDIS structures in which the addresses of NDIS driver callbacks are written. As a result, when calling any intercepted callback of any NDIS driver, the sniffer gets control. So almost all third-party packet filters work (OutPost for example). Only one drawback - it is not very reliable.

Mini conclusion

Well, here it is about all the basic information that we will need to write our intermediate driver. In the next article we will start writing code directly, let's talk about IRP. Next, we will also look at installing and debugging drivers. I really hope that this topic is interesting for you and if it is so, then I will gladly cover it for you.
Thank you for attention.

Source: https://habr.com/ru/post/111672/


All Articles