Analysis of Windows NT2000 kernel objects (http:webcrazy.yeah.net)

xiaoxiao2021-03-06  40

Analysis of Windows NT / 2000 kernel object organization

Webcrazy

http://webcrazy.yeah.net/)

Object Manager has an extremely important location in the Windows NT / 2000 core, and one of its most important functions is to organize management system kernel objects. In Windows NT / 2000, the kernel object manager has introduced a large number of object-oriented ideas, that is, all kernel objects are encapsulated inside the Object Manager, except for the object manager, and some other people who want to reference kernel objects. The system is opaque, that is, you need to access these structures through the Object Manager. Microsoft's high-core driver code follows this principle (the user code cannot directly access this data), and she provides a series of routines that start with OB for us to use. But nor is it that only the object manager is that these functions can access these data. I have access to these structures directly. In this case, we can only pray that Microsoft always keeps these objects, the object structure is constant, which is generally unobstructed, so I offer the code for learning Windows. NT / 2000 kernel is used without other practical applications.

Let's talk about the name of the name of the kernel, named objects exist in the system global named kernel area, similar to the traditional DOS directory and file organization, and the object manager also manages these objects, so that the kernel object can be quickly retrieved. This advantage is easy to reflect, the object retrieval speed, this will greatly improve system performance, for example, such as Process A Almost use a file, ie A in the kernel has a kernel object pointing to this file ( FILE_OBJECT, and if another process B also tries to access this file, b By opening this file through the CreateFile API, the system guide the object manager finds an object storage space. If this object already exists, check whether or not Excused, if it is, the failure, otherwise, increase the reference count or handle count of this object. There is nowhere in the system in the system, because all the operational data structures that protect all Structure, Structure_Descriptor, etc. in Windows NT / 2000 are treated as object processing, such as common process objects (EPROCESS / KPEB), Thread object (ethread / kteb), driver object (driver_Object), and more. Of course, this tree structure tissue kernel has named objects, and another advantage is to make all named object organizations are very organized, such as device objects under / device, and the object type name is in / ObjectTypes. Wait. This will also achieve the object of the user process that can only access / ?? and / basenaMedObjects, and the kernel code does not have any restrictions. As for how to organize these named objects inside, in fact, Windows NT / 2000 is directed to the root directory by the Directory object pointing to the kernel variable obprootdirectoryObject, and use hashtable to organize these named kernel objects. Let's take a look at the analysis of i386kd, let us take a look at the code I wrote.

KD>! Object /

Object: 8148E210 TYPE: (814C5820) Directory

ObjectHeader: 8148E1F8

Handlecount: 0 Pointercount: 39

Directory Object: 00000000 Name: /

99 Symbolic Links Snapped THROUGH THIS DIRECTORY

Hashbucket [00]: 8148A350 DIRECTORY 'ArcName'

814A8F10 Device 'NTFS'

Hashbucket [01]: E2390040 Port 'SELSACOMMANDPORT'

Hashbucket [03]: E1012030 Key '/ registry'

Hashbucket [06]: E1394560 Port 'XACTSRVLPCPORT'

Hashbucket [07]: E13682E0 Port 'DBGUIAPIPORT'

Hashbucket [09]: 84305760 DIRECTORY 'NLS'

.

.

.

KD>! Object 814a8f10

Object: 814a8f10 type: (814B5AC0) Device

ObjectHeader: 814A8EF8

Handlecount: 0 Pointercount: 2

Directory Object: 8148E210 Name: NTFS

The implementation code is as follows:

// -----------------------------------------------

//

// Dump Windows 2000 KERNEL OBJECT

// ONLY TEST ON Windows 2000 Server Chinese Edition

// build 2195 (free)! Programmed by Webcrazy

//

TSU00@263.net) on 11-04-2000!

// Welcome to

http://webcrazy.yeah.net!

//

// -----------------------------------------------

Ulong obprootdirectoryObject = 0x8148E210; // fetch from symbol file

Void DumpDirectoryObject (PVOID DIRECTORYOBJECT)

{

Ulong hashbucket;

Ulong * hash;

For (hashbucket = 0; hashbucket <= 0x24; hashbucket )

{

Hash = (ulong *) (Ulong) DirectoryObject Hashbucket * 4);

IF (* Hash == 0) Continue;

DBGPrint ("/ n hashbucket [% 02x] / n", hashbucket;

DO

{

Punicode_String Obname, ObTypename;

Pvoid ​​Object, ObpreHeader, ObstandardHeader;

Hash = (ulong *) (* hash);

Object = (pvoid) (* (ulong *) ((ulong) hash 4));

OBPREHEADER = (PVOID) (ULONG) Object-0x28);

Obstandardheader = (pvoid) ((Ulong) Object-0x18);

Obname = (PUNICODE_STRING) ((Ulong) OBPREHEADER 4);

DBGPrint ("/ TDUMP Object: 08X / N", (Ulong) Object);

DBGPRINT ("/ T Name:% S", OBNAME-> BUFFER;

Obtypename = (PUNICODE_STRING) ((ULONG) (ULONG *) ((Ulong) ObstandardHeader 8)) 0x40);

DBGPrint ("/ t type:% s (% 08x) / n", obtypename-> buffer, * (ulong *) ((Ulong) ObstandardHeader 8);

DBGPRINT ("/ T Pointercount:% D Handlecount:% D / N", * (Ulong *) ObstandardHeader,

* (Ulong *) (Ulong) ObstandardHeader 4)));

} while (* hash! = 0);

}

}

Void DumpObject (PVOID Object)

{

Punicode_String Obname, ObTypename;

Unicode_String Temp;

Pvoid ​​ObpreHeader = (PVOID) (ULONG) Object-0x28),

Obstandardheader = (pvoid) ((Ulong) Object-0x18);

IF ((USHORT) NTBUILDNUMBER! = 2195) {

DBGPRINT ("Only Test On Windows 2000 Server Build 2195! / N");

Return;

}

Obname = (PUNICODE_STRING) ((Ulong) OBPREHEADER 4);

DBGPRINT ("Dump Object:% 08x / N Name:% S", (Ulong) Object, Obname-> buffer;

Obtypename = (PUNICODE_STRING) ((ULONG) (ULONG *) ((Ulong) ObstandardHeader 8)) 0x40);

DBGPRINT ("Type:% S (% 08x) / N", Obtypename-> buffer, * (ulong *) ((Ulong) ObstandardHeader 8));

DBGPRINT ("PointerCount:% D Handlecount:% D / N", * (Ulong *) ObstandardHeader,

* (Ulong *) (Ulong) ObstandardHeader 4)));

RTLINITUNICODESTRING (& Temp, L "DIRECTORY");

IF (! rtlcompareunicodeString (& Temp, Obtypename, False)

DUMPDIRECTORYObject (Object);

}

Void dumprootdirectoryObject ()

{

DumpObject ((pvoid) obprootdirectoryObject);

}

I have seen the output of Windbg's output or use Softice's objdir command, you should know the use of the code, so I will not introduce. This code directly reads the system global naming object area, without considering synchronization, etc., and does not add one to PointerCount when referenced by reference object members, and there is no Callback function defined in Object_Type, so that the user drives code or operations When there is some additional apps, it may cause an error, but because I have a clearer definition of the data structure of the target area, I will help the core object organization that understands Windows NT / 2000 is more helpful, so I will It lists (this code I understood it for a long time). In the code, I use the PVOID pointer and convert the pointer to the ulong type and add the offset address of the structure directly. Do not use such syntax if (Ulong *) OB , so you can extract some structural important members directly from the code, but this also causes the code to be less concise. Regarding the most important Windows NT / 2000 kernel variable of OBProotDirectoryObject, I extract it directly from the Symbols file, you must adjust it according to the actual situation. Or use ObreferenceObjectByname to be obtained. In fact, there are many applications that can enumerate this listing, except for Windbg / i386kd! Object, Softice's Objdir command, and other DDK Objdir.exe, Mark Russinovich WinObj.exe, etc. If you search for a named object storage area, you can implement the enumeration of the System Device (DRIVER) object, you can implement the functionality of the Device and Driver commands in Softice. It must be pointed out that not all Device objects are located under / device, nor all the Driver objects are located under / driver, so you must find the entire space by recursive call DumpDirectoryObject, I don't know why Microsoft does not limit Device and Driver objects. Storage location.

The named kernel objects talked above can be shared between processes, which is the most basic principle of LPC (LOCAL Procedure Call) in Windows NT / 2000, and LPC is called the kernel object called Port. Why is a named object to share between processes, but the unnamed objects you want to talk about can't share between processes? Through my understanding, I think that since both are located on the high end of the system core 4G memory, theoretical should be Sharing between processes. Just because Microsoft provides objects, such as ObReferenceObjectByname, the object name is found directly, and the ObreferenceObjectByHandle provided does not specify the parameters of the process, so unnamed objects cannot be shared this extent. In addition, Microsoft does not provide another one of the most important reasons for this parameter I think it should be more robust and stable. Let me talk about the "handle" to manage the mechanism of the unnamed kernel object.

Why introduce the concept of "handle"? To prevent user code from damage to kernel objects, Windows NT / 2000 can be used through "handle" mechanism to avoid directing the kernel object pointer to the user process, and "handle" except this function In addition, it also manages all kernel objects that process specific to each other, of course, unnamed objects. The proc command in Softice is add -O option to get all the handles owned by a particular process. However, when searching for a specified handle, Softice is inconvenient during use, I have tried to convert the Windbg Extension DLL into Softice use .sys file, but often appear during use problem. Later, after analyzing the ObreferenceObjectbyHandle kernel routine, I defined the following macros in Softice (About ObreferenceObjectByHandle Analysis Process and Code I don't listed, you can carefully track tracking): // Define macro Handle

// Handle

// Parameter KPEB Specifies a specific process, Handle Index is a handle index

: macro handle = "Addr% 1; what (@ (@ (@ (@ (% 1 128) 8))) (% 2 >> 2) * 8)) | 80000000 ;."

Macro: 'Handle' Defined

/ / Display the handle object pointer and object type name of Handle INDEX in the System process

: Handle DWORD (@psinitialsystemprocess) 4

THE VALUE 8148EBC8 IS (a) kernel process object (handle = 0004) for system (08)

-------- -----------------------------------

| _ 手柄 head address | _ handle corresponding object type | | _ 指 指 This handle is affiliated with the System process

| _Handle Index

This macro I was passed on Microsoft Windows 2000 Server Build 2195 Chinese Edition. As shown above, only the target pointer is displayed and the object type name. To view more detailed information. You can only go deep into the kernel object head and the object structure or use Windbg! Handle command. This macro has clearly understood the structure of the handle of the process, and many of the objects have applied in the code I have provided above. I don't list the specific implementation code. It is recommended to see Mark Russinovich Handlex. .

About the Windows NT / 2000 kernel object organization mentioned in the title also has a lot of content, such as the security settings of the kernel object, etc., limited to horizontal and energy, and I can't write here. In addition, it should be proposed that this article does not involve the GDI object of the user mode, etc., which also have another way in the organization. During the analysis of Windows NT / 2000, I preliminate MuCrosoft Design Many advanced ideas of Windows NT / 2000, and it is also increasingly understanding the difficulty of analysis. I hope you can communicate with you after you have experience, or contact me (

TSU00@263.net)!

Reference:

1.David solomb "inside windows nt, 2nd edition"

2.Mark Russinovich related documentation

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

New Post(0)