In-depth understanding and use of the Windows NT driver execution context (1)

Source: Internet
Author: User
Tags readfile

Deep understanding and useWindows NTExecution context of the driver

Original: open system resources, Inc.
Compile: codewarrior @ Fudan CSE

 

To understand the Windows NT driver, one of the most important concepts is the execution context in which the driver runs ). A deep understanding of this concept and careful application of your knowledge about it can help you write faster and more efficient drivers. This section includes the following topics: l what is the impact of context l several different contexts l how to maximize the use of context l summary for NT standard kernel-state drivers, an important detail is the context of a specific function execution in the driver. Traditionally, most file system developers are concerned about this, however, if you have a strong understanding of the "execution Context", you will benefit from all types of kernel-state drivers of NT. A deep understanding of the execution context and careful use of it can ensure the design of a driver with higher performance and lower operating costs. In this article, we will explore the concept of execution context. At the end of this article, we will cite a driver that allows the user program to run in kernel mode and obtain all privileges of the system as an example of what we will introduce. What is the execution context?When we mention the context of a routine, we refer to its thread and process execution environment. In NT, this environment is composed of the current thread environment block Teb and the process environment block peb. Therefore, the context includes virtual memory settings (which physical memory block corresponds to which virtual memory address) and handle conversion (because the handle is associated with the process) A set of schedulers, stacks, General registers, and floating-point registers. When we ask "in which context is a specific kernel routine executed", we actually ask, "which thread is currently specified by the NT kernel scheduler ?" Because each thread belongs to only one process, the current thread implies a clear process. In short, the "current thread" and "current process" are all different from other threads and processes (handles, virtual memory, scheduler status, registers ). For kernel-mode driver programmers, the virtual memory context may be one of the most useful aspects of the term "context. Recall that nt maps user processes to 2 GB at the low end of the virtual address space, and maps the code of the operating system to 2 GB at the high end of the virtual address space. When a thread in a user process is executing, its virtual address range is from 0 to 2 GB, and all the addresses above 2 GB are set to deny access, this prevents users from directly accessing the operating system code and data structure. When the operating system code is being executed, its virtual address range is from 0-4 GB, the current user process (if there is such) it is mapped to the address range of 0-2 GB. In NT v3.51 and v4.0, the Code mapped to the high-end 2 GB remains unchanged. However, the Code mapped to the lower 2 GB address space is changing, depending on which process is being executed. Let's take a step further than the above description. In the memory layout such as NT, a valid user virtual address X (X should be less than or equal to 2 GB) in the given process P ), then it corresponds to the same physical memory location as the kernel virtual address X. Of course, only when P is the current process (and because of this) this conclusion is correct when the physical page of process P is mapped to the 2 GB virtual address space at the low end of the operating system. The last sentence mentioned above is described as follows: "The above conclusion is correct only when P is the context of the current process ". Therefore, the user virtual address and the kernel virtual address's high-end 2 GB actually correspond to the same physical location, if the process context is the same. The User Virtual Address Space and kernel virtual address space mentioned here are two different concepts, the kernel virtual address space and the user virtual address space are not a simple division of the entire 4 GB space. In fact, the kernel virtual address space refers to the 0-4 GB virtual address range seen from the kernel perspective; the user address space refers to the virtual address range of 0-4 GB from the perspective of user-State processes-although for user-State processes, the 4 GB virtual address space in which the 2 GB or higher is displayed is denied access. The author will use a picture to explain it later. For the kernel, the low virtual address space of the kernel 2 GB is constantly changing, because of the process scheduling, only when the current scheduling process P is executed, the virtual address x corresponds to the same location in the physical memory ). For kernel-state driver programmers, the details about the context they are interested in are thread scheduling context ). When a thread is waiting (for example, using the Win32 function waitforsingleobject (...) Wait for an unfired object). The information about the waiting target is stored in the scheduling context of the thread. If the waiting conditions cannot be met, the thread will be removed from the ready queue. After the waiting conditions are met, the thread will return to the ready queue. Context also affects the use of the handle. Because the handle is associated with a specific process, the handle created in the context of a process cannot be used in the context of another process. Several different contextsKernel-state routines are executed in one of the following three contexts: L system process context l a specific user thread (and process) context l any user thread (and process) during the execution of the context, each part of the kernel-state driver may be executed in any of the preceding three contexts. For example, driver DriverEntry (...) The function always runs in the context of the system process. The system process context does not have the user thread context associated with it (there is no Teb), and no user-state process is mapped to the virtual address space of the kernel: recall that the virtual address space of the kernel is also from 0 to 4 GB ). On the other hand, DPC (such as the DPC of the driver used for ISR or timer functions) runs in unrelated user thread context. This means that during DPC execution, any user thread may be the "current" thread ), that is to say, any user process may be mapped to the low-end 2 GB in the kernel virtual address space. The context of the driver distribution routine execution may be particularly fascinating. In many cases, the distribution routine of the kernel-state driver is executed in the context of the user thread that generates the call. Figure 1 explains why. When a user thread sends an I/O function call for a device-for example, the Win32 function readfile (…) is called (...) -- May cause a system service request. On intel architecture processor, such requests are implemented through software interruptions. The software interrupt passes through the interrupt door, And the interrupt door switches the current privilege of the processor Figure 1Level CPL to kernel mode, which triggers an action to switch to the kernel stack and then calls the system service dispatcher ). Then, the system service dispatcher calls the functions provided by the operating system to process the requested system service. Use readfile (...) For example, this function is the ntreadfile (…) of the I/O subsystem (...), Ntreadfile (...) The function creates an IRP and checks readfile (...) The file object referenced by the file handle passed in the request is associated with the driver in the kernel, and then the distribution routine that the driver processes "read" is called. All of these occur at the passive_level interrupt request level. During the process described above, no user requests are scheduled or queued. Therefore, the user thread and process context will not change. In this example, the distribution routine of the driver is executed when the readfile (…) is issued (...) The context of the called user thread. This indicates that when the "read" Distribution Function of the driver is executed, the user thread is executing the kernel-state driver code. So is the distribution routine of the driver always executed in the context of the user thread that sends the request? Not necessarily. Section 16.4.1.1 of the 4.0 kernel-mode driver development guide tells us that "only the top-level nt drivers, such as file system drivers, it is certain that their distribution routines are called in the context of such user mode threads." But strictly speaking, this is not completely true (we can see this in our example). One thing we can be sure of is: FSD is called in the context of the user thread sending the request. The fact is that when a user sends an I/O request, if a driver is called immediately and does not pass the request to other drivers, it can be guaranteed that the driver is called in the context of the user thread sending the request, including FSD. However, this fact also means that most of the standard kernel-state drivers compiled by users directly provide some functions to user applications, such as processing control devices, the distribution functions of these drivers are called in the context of the user thread that sends the request. In fact, there is only one case where the distribution routine of the driver is not called in the context of the user thread that generates the call, that is, the user's request is first sent to a higher-level driver, such as the file system driver. If a higher-level driver sends a request to the system worker thread, the context changes accordingly. When an IRP is finally passed down to a lower-layer driver, it cannot be ensured that the context in which the higher-level driver executes the forwarded IRP action is the context of the user thread sending the request. Lower-layer drivers will therefore be executed in any thread context. A general rule is that if a device is directly accessed by the user, no intervention from other drivers will be performed in the middle of the process, the distribution routine of the driver of the device is usually run in the context of the user thread that sends the request. When this happens, some interesting results will be generated, which allows us to do something equally interesting.

 

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.