Before we get into the nitty-gritty of learning how to use DKOM techniques, it is important to understand DKOM's benefits and its drawbacks. On the positive side, DKOM is extremely hard to detect. Under normal circumstances, altering kernel objects such as processes or tokens requires going through the Object Manager in the kernel. The Object Manager is the central point of access to kernel objects. It provides functionality common to all objects, such as creation, deletion, and protection. Direct Kernel Object Manipulation bypasses the Object Manager, thereby bypassing all access checks on the object.
However, DKOM has its own set of problems, one of which is that it is extremely fragile. Because of this fragility, before altering a kernel object a programmer must understand several things about the object:
What does the object look like, or what are the members of the structure? This can sometimes be the most difficult question to answer. When most of the research began for this book, the only way to answer this question was to spend a lot of time working within Compuware's SoftIce or another debugger. Recently, Microsoft made this job a little easier. Using WinDbg, which is free for download from Microsoft's Web site, you can display the object members by typing dt nt!_Object_Name. For example, to list all the members of the EPROCESS structure, type dt nt!_EPROCESS. Figuring out what Microsoft calls the object is still a problem, and not all objects are "documented" in WinDbg.
How does the kernel use the object? You will not understand how or why to modify the object until you understand how it is used by the kernel. Without a thorough understanding of how it is used, you will undoubtedly make a lot of incorrect assumptions about the object.
Does the object change between major versions of the operating system (such as Windows 2000 and Windows XP), or between minor service-pack releases? Many of the objects you will use with DKOM change between versions of the operating system. The objects are designed to be opaque to the programmer, but since you will be modifying them directly, you must understand any such changes and take them into account. Since you will not be working through any function call to modify the objects, backward compatibility is not guaranteed.
When is the object used? We do not mean when in the temporal sense of the word, but rather, the state of the operating system or machine when the object is used. This is important because certain areas of memory and certain functions are not available at different Interrupt Request Levels (IRQLs). For example, if a thread is running at the DISPATCH_LEVEL IRQL, it cannot access any memory that would cause a page fault in the kernel.
Another limitation of DKOM is that you cannot use it to accomplish all of a rootkit's purposes. Only the objects that the kernel keeps in memory and uses for accounting purposes can be manipulated. For example, the operating system keeps a list of all the processes running on the system. As we will see in this chapter, these can be manipulated to hide processes. On the other hand, there is no object in memory representing all the files on the file system. Therefore, DKOM cannot be used to hide files. More-traditional methods, such as hooking or using a layered file filter driver, must be used to hide files. (These techniques are covered in Chapters 4 and 6, respectively).
Despite these limitations, DKOM can be used to successfully accomplish the following:
Now that you are aware of DKOM's benefits and limitations, let's use the technique to modify some kernel objects.