Analyze the organization of Windows NT2000 window objects (http:webcrazy.yeah.net)

xiaoxiao2021-03-06  39

Analysis of the organization of Windows NT / 2000 window objects

Webcrazy

http://webcrazy.yeah.net/)

Microsoft Visual Studio provides Microsoft Spy's Windows window organizations with very intuitive performance, and Window Properties under the Windows view can display a lot of content or properties of the window. This article will depart from the WINDOWS NT / 2000 kernel, indicating these important structures in Windows NT / 2000.

First, from the window organization, you know that the enumeration window can be implemented via ENUMWINDOWS, ENUMDESKTOPWINDOWS or ENUMCHILDSKTOPWINDOWS or ENUMCHILDWINDOWS. I want to really understand the details of these APIs, and you should find the internal execution of many Windows NT / 2000, so I carefully study these APIs, I will analyze the ENUMWINDOWS API under Windows 2000 Server Build 2195. Steps are described below:

1.User32.dll first calls INTERNALEMWINDOWS under User32.dll, and INTERNALENUMWINDOWS calls BuildhWndList (user32.dll).

2. BuildhWndList calls NTUSERBUILDHWNDLIST, and this function is also located in the user32.dll module.

3.ntuserbuildhwndlist just calls the INT 2E instruction, then use the ID of the ID 0x112e, which is NTUSERBUILDHWNDLIST in the Win32k.sys module, see "

Windows 2000 System Services list. From this start, you will enter the core state from the user state.

4. Win32k.sys Continue to call BuildhWndList in Win32k.sys, it should be noted that the two routines are the same name as the corresponding routines in User32.dll above, which is the reason I have always emphasized. BuildhWndList finally calls INTERNALBUILDHWNDLIST (Win32k.sys), this routine is our truly interested place. INTERNALBUILDHWNDLIST is under specific parameters (such as EnumDestopWindows API calls, EnumDestopWindows ultimately calls INTERNALBUILDHWNDLIST) is a recursive routine to implement the enumeration of the window.

This analysis only describes the execution process of EnumWindows and other APIs. The real details should still take a look at the code. Windows NT / 2000 window is associated with specific threads, that is, each thread can have a window, the most typical example is Windows Explorer (Windows Explorer), and the Explorer process creates threads every open an Explorer window. These windows are associated. For this reason, Microsoft stores the window structure in the NTHREAD (KTEB) of the internal nuclear state (the early version of the Win32 subsystem is located in the user state, which is not explained by the Win32thread member in Ethread. Win32Thread's position in Ethread can be found by the following commands of Windbg:

>! Kdex2x86.thread

Structure Ethread (Size: 0x240) MEMBER OFFSETS:

0000 TCB (Kthread Struct)

0000 HEADER (Dispatcher_Header Struct)

.

.

.

0124 Win32thread

.

.

.

It is to point out that Win32Thread members are displayed as Service Table in Softice 4.05 for Windows NT. To facilitate the user code, it is easier to get the value of Win32thread, and Windows NT / 2000 also accesss the Win32Thread pointer in the Teb of the thread, where the Windows 2000 Server Build 2195 is located at the time of TEB. 0x40. User32.dll Gets the value of Win32thread by the following function (i386kd output): kd> x user32! PTICurrent

77DF3686 USER32! PTICURRENT

KD> u User32! PTICURRENT

User32! PTICurrent:

77DF3686 64A118000000 MOV EAX, FS: [00000018]

77DF368C 83784000 CMP DWORD PTR [EAX 0x40], 0x0

77DF3690 0F8492700200 JE USER32! PTIRRENT 0XC (77E1A728)

77DF3696 64A118000000 MOV EAX, FS: [00000018]

77DF369C 8B4040 MOV EAX, [EAX 0x40]

77DF369F C3 RET

Below is a code implementation I have implemented an enumeration of the window owned by the specific thread (I got Win32thread from KTEB):

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

//

// BUILDHWNDLIST - ENUM THREAD Windows (Softice Hwnd Command)

// ONLY TEST ON Windows 2000 Server Build 2195 Chinese Edition

// build 2195 (free)! Programmed by Webcrazy

//

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

// Welcome to

http://webcrazy.yeah.net to get more information

//

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

#define Win32thread_offset 0x124

#define hwndlist_offset 0xB8

#define hwndhandle_offset 0x0

#define hwndnext_offset 0x2c

#define hwndparent_offset 0x30

#define hWndRect_offset 0x3c

#define hwndproc_offset 0x5c

// RECT: Copied from Windef.h

Typedef struct tagRect

{

Long LEFT;

Long Top;

Long Right;

Long Bottom;

} RECT, * prect;

Typedef struct taghwndRect {

Rect windowRect;

Rect clientRect;

} HwndRect, * phwndRect;

Void BuildhWndList (Void * KTEB)

{

PVOID WIN32THREAD;

PVOID HWNDLIST;

PHWNDRECT phwndRect;

IF ((USHORT) NTBUILDNUMBER! = 2195) {

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

}

Win32thread = (PVOID) (* (CHAR *) KTEB WIN32THREAD_OFFSET);

IF (! Win32thread) {

DBGPRINT ("KTEB: 08X ISN't A Win32 Thread! / N", KTEB);

Return;

}

HWndList = (PVOID) (* (char *) Win32thread hwndlist_offset);

IF (! hwndlist) {

DBGPRINT ("KTEB: 08X ISN't A HWnd List! / N", KTEB);

Return;

}

DBGPrint ("@ kteb% 08x first hwndlist at% 08x / n", kteb, hwndlist);

DBGPrint ("HWndList HWnd Parent Window Proc Window (Client) Rect / N);

DBGPRINT ("-------------- ---------------------------------- ------- / n ");

Do {

PHWNDRECT = (PHWNDRECT) ((char *) hwndlist hWndRect_offset);

DBGPRINT ("% 08x% 08x% 08x% 08x% D,% D,% D,% D (% D,% D,% D,% D) / N",

HWndList,

* (Pulong) (char *) hwndlist hwndhandle_offset,

* (PULONG) ((char *) hwndlist hwndparent_offset),

* (22) ((char *) hwndlist hwndproc_offset),

PhWndRect-> WindowRect.Left, phWndRect-> WindowRect.top,

PhwndRect-> WindowRect.right, phWndRect-> WindowRect.Bottom,

phWndRect-> ClientRect.Left, phWndRect-> ClientRect.top,

phWndRect-> ClientRect.right, phwndRect-> clientRect.bottom);

HWndList = (PVOID) (* (char *) hwndlist hwndnext_offset);

WHILE (HWNDLIST);

}

Run an example, the output is about the following:

@Kteb ff7bb020 first hwndlist at A0312DA8

HWndList Hwnd Parent Window Proc Window (Client) Rect

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

A0312DA8 0001002A 0001000C 77DFF0DF 0, 0, 0, 0 (0, 0, 0)

A0310D50 00010022 0001000C 775331C4 0, 0, 112, 27 (4, 23, 108, 23)

A03176B8 0002004A 0001000C 77DFF0DF 0, 0, 0, 0 (0, 0, 0, 0)

A031A500 00010082 0001000C 76621AC6 44, 44, 812, 581 (48, 67, 808, 577) A0318FA8 00010062 0001000C 775676F4 0, 0, 1024, 768 (0, 0, 1024, 768)

Let's talk about Window Class again. Talking to Class, I can really think of a lot of things, such as C class, etc. As for Window Class, I don't quote the explanation of Microsoft documentation:

A Window Class Is A Set of Attributes That The System Uses as a Template To Create A Window. EVERY

Window is a member of a window class. All Window Classes Are Process Specific.

From the above description, you can also see that the Window Class is associated with a particular process. The window is associated with threads, so its structure is stored in Ethread (KTEB), and the structure of the corresponding Windows Class is stored in EPRocess (KPEB). The window structure is specified by Win32Thread, and the Window Class is specified in Win32Process. The location of Win32Process in EPRocess can also be seen by Windbg:

>! Kdextx86.processfields

EPROCESS STRUCTURE OFFSETS:

.

.

.

Win32Process: 0x214

.

.

.

Below is the code of Window Class for enumerating specific processes:

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

//

// BuildWindowClassList - Enum Process Window Class (Softice Class Command)

// ONLY TEST ON Windows 2000 Server Build 2195 Chinese Edition

// build 2195 (free)! Programmed by Webcrazy (TSU00@263.net) on 11-25-2000!

// Welcome to http://webcrazy.yeah.net to get more information

//

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

#define Win32Process_offset 0x214

#define WinPrivateClass_offset 0x38

#define winglobalclass_offset 0x3c

#define class_classstyle_offset 0x2c

#define class_windowproc_offset 0x30

#define class_modulebase_offset 0x3c

#define class_classname_offset 0x50

Void BuildWindowClassList (Void * KPEB)

{

PSINGLE_LIST_ENTRY PPRIVATECLASSLIST, PGLOBALCLASSLIST

PVOID WIN32PROCESS;

Pchar PCLASSNAME;

Win32Process = (PVOID) (* (CHAR *) KPEB WIN32PROCESS_OFFSET);

IF (! WIN32PROCESS) {

DBGPRINT ("KPEB: 08X ISN't A Win32 Process! / N", KPEB); Return;

}

PprivateClassList = (psingle_list_entry) (* (char *) Win32Process WinPrivateClass_offset);

IF (pprivateclasslist) {

DBGPRINT ("Application (KPEB: 08X) Private Class List: / N", KPEB);

DBGPRINT ("% - 35SHANDLE MODBASE WINPROC STYLES / N", "Class Name");

DBGPRINT ("% - 35s -------------- -------------- / N", "------- --- ");

Do {

PCLASSNAME = (PCHAR) (* (CHAR *) PprivateClassList Class_ClassName_offset);

DBGPRINT ("% - 35S% 08X% 08X% 08X% 08X / N", PCLASSNAME, PPRIVATECLASSLIST,

* (22) ((char *) PprivateClassList Class_ModuleBase_offset,

* (Pulong) (char *) PprivateClassList Class_WindowProc_offset,

* (Pulong) ((char *) PprivateClassList Class_ClassStyle_offset);

PprivateClassList = pprivateclasslist-> next;

} while (pprivateclasslist);

}

PGLOBALCLASSLIST = (PSINGLE_LIST_ENTRY) (* (CHAR *) Win32Process WinglobalClass_offset);

IF (pglobalclasslist) {

DBGPrint ("Application (KPEB: 08x) Global Class List: / N", KPEB);

DBGPRINT ("% - 35SHANDLE MODBASE WINPROC STYLES / N", "Class Name");

DBGPRINT ("% - 35s -------------- -------------- / N", "------- --- ");

Do {

PCLASSNAME = (PCHAR) (* (char *) PGLOBALCLASSLIST CLASS_CLASSNAME_OFFSET);

DBGPRINT ("% - 35S% 08X% 08X% 08X% 08X / N", PCLASSNAME, PGLOBALCLASSLIST,

* (Pulong) ((char *) PGLOBALCLASSLIST CLASS_MODULEBASE_OFFSET,

* (Pulong) (char *) PGLOBALCLASSLIST CLASS_WINDOWPROC_OFFSET,

* (Pulong) (CHAR *) PGLOBALCLASSLIST CLASS_CLASSSTYLE_OFFSET);

PGLOBALCLASSLIST = PGLOBALCLASSLIST-> NEXT;

WHILE (PGLOBALCLASSLIST);

}

}

The case is a result of a running instance: Application (KPEB: FF5BA3C0) Private class list:

Class Name Handle Modbase WinProc Styles

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

ConsoleimeClass A031F938 01000000 0100152E 00000000

DDemlunicoDeserver A031F8A8 77DF0000 77E2E2F9 00000000

DDemlansiserver A031F820 77DF0000 77E2E2F9 00000000

DDEMLUNICODECLIENT A031F790 77DF0000 77E2E14D 00000000

DDemlansiclient A031F708 77DF0000 77E2E14D 00000000

DDEMLMOM A031F688 77DF0000 77DFD316 00000000

Application (KPEB: FF5BA3C0) Global Class List:

Class Name Handle Modbase WinProc Styles

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

Static A031F610 77DF0000 77E000F9 00004088

IME A031F5A0 77DF0000 77DFF0DF 00004000

.

.

.

The two code segments I have given above implements the features of the HWnd and Class commands in Softice. After analyzing these two commands, you can further analyze the Windows NT / 2000 internal message mechanism, which is the foundation for Windows GUI implementation. Things that can continue excavation seem to have more and more.

Reference:

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

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

New Post(0)