Analysis of Windows NT / 2000 Environment Switching
Webcrazy
TSU00@263.net)
Note: This article is initially found
Www.nsfocus.com
This article assumes that you have learned the Windows NT / 2000 system system, which has certain concepts of data structure and kernel work in Windows NT / 2000 internal KPEB / KTEB, and has a study of 80x86 protection mode, Intel / AT & T format assembly language. Skilled using Softice for Windows NT, and has been touched by Microsoft Visual Studio and the tools, and looked through the Linux kernel code. If you don't know much about these, please refer to the relevant books.
Context switch involves many aspects, this paper only discusses more data related to it, and gives some blocks to obtain this data, and lists a small amount of environmental switching code for Windows 2000. In addition, the internal data discussed in the article is from Microsoft official documentation. There is a difference between the next version of Windows NT / 2000, and even the current versions are different, so I try to list the hardware and hard involved in the article, all Due to the differences between the hardware system, the software version is different, please adjust it according to your situation.
⊙ x86 Platform Single Procedure Windows 2000 Server Build 2195
⊙ Numega Softice 4.05 for Windows NT / 2000 Build 334
⊙ Linux 2.0.30 kernel
⊙ Datarescue Ida 4.0.4.362
Microsoft Visual Studio 6.0 SP3
⊙ Windows 2000 DDK
The environmental switches generated by 80x86 have the following possibilities:
1. The current task executes a FAR CALL or JMP instruction, and the selector points to a TSS descriptor or a task door.
2. The current task executes the IRET instruction to return a previous task, and the IRET generates switching only when the NT position in the EFLAGS register 1.
3. An interrupt or abnormal situation has occurred, and the IDT item is a task door.
There is the following code in the Linux kernel:
/ *
/usr/src/linux/include/ASM-i386/system.h
List only single processor implementation code
* /
#define switch_to (prev, next) do {/
__ASM __ ("MOVL% 2," Symbol_name_str (current_set) "/ n / t" /
"LJMP% 0 / N / T" /
"CMPL% 1," SYMBOL_NAME_STR (Last_Task_USED_MATH "/ N / T" /
"JNE 1F / N / T" /
"CLTS / N" /
"1:" /
: / * No Outputs * / /
: "M" (* ((CHAR *) & next-> tss.tr) -4)), /
"R" (prev), "R" (NEXT); /
/ * Now Maybe reload the debugreg registers * / /
.
.
.
} /
} while (0)
This code uses the first case discussed above.
As we all know, Linux is an open source operating system, and Microsoft is not so "generous", but we can still have some reverse engineering, which is available on the Internet, there are already many people have studied, now take the Mark Russinovich. Part of the results
http://www.sysinternals.com/tips.htm):
//
// nt's main
// ntoskrnl main
//
Int main (boot parameters)
{
//
// Fire Up NT!
//
KisystemStartup ();
Return 0;
}
It can be seen from the NToskrnl.exe (PE format, which can be easily analyzed) is NT OSLoader to truly call the beginning of the kernel, its pair of file objects, job objects (JOBs), process objects (Process), Thread Objects, Filemapping, Event Object (Event), Mutex, Mutex, Signal (Semaphore), etc., is also responsible for thread scheduling All operating system functions such as memory management, inter-process communication allow them to work, and the thread switching code we have to discuss is also in this module.
The results of disassembly incurring with Ntoskrnl.exe with IDA, and the workload of its analysis is impossible to know. Before we discuss the Windows 2000 environment to switch the detailed code, let's take a look at the following important system data related to environmental switches:
1 process context
Process Context refers to the physical address where the page directory where the 80x86 in the protected mode memory paging mechanism is stored in the system CR3 register. The position of the WINDOWS 2000 is offset 18h after the KPEB is offset, see Softice The output result is (limited to the space, I have dropped the output results, but I still have an important data. It should be noted that it is closely related to the system environment such as the currently running program, the randomness is very strong, the same below):
: CPU // Displays the current CPU register value
Processor 00 Registers
----------------------
CS: EIP = 0008: 80069582 SS: ESP = 0010: 8046FD98
EAX = 8046BDF0 EBX = ffdff000 ECX = ffdff878 edx = 0000ba5a
ESI = 8046bdf0 EDI = 8046bb60 EBP = ffdff800 EFL = 00000213
DS = 0023 ES = 0023 fs = 0030 GS = 0000
CR0 = 8000003B PE MP TS ET NE PG
CR2 = 76ee18ec
CR3 = 00030000
|
| _ Current process CR3
CR4 = 000002d1 VME PSE MCE PGE
.
.
.
: Proc iDLE
Process Kpeb Pid Threads Pri User Time Krnl Time Status
* IDLE 8046BB60 0 1 0 00000000 0000BA5A Running
| | |
| | _IDLE process KPEB
The current process in the system (Softice is highlighted in different colors, and there is a *)
: DD 8046BB60 18 L 4 // DD Idle's KPEB 18H
0010: 8046bb78 00030000 00000000 000,000 00000000 ................
|
| _Idle process context
: addr
CR3 LDT BASE: LIMIT KPEB AddR Pid Name
00030000 Fe4e1C60 0008 System
02D59000 FF8E6540 0090 SMSS
01D41000 FF8E17E0 00ac CSRSS00686000 Fe51Bae0 00c0 Winlogon
0095D000 FF8A7AE0 00dc Services
0276E000 FF8A5D60 00E8 LSASS
00394000 FF881020 0180 SVCHOST
02CAE000 FF884020 01A4 SPOOLSV
00882000 FF85B560 01D0 MSDTC
02993000 FF83F020 0238 SVCHOST
00d2f000 ff83d760 024c llssrv
0063A000 FF837860 0274 Regsvc
02efa000 ff6ecd60 0318 DFSSVC
00A5E000 FF823A20 0328 inetinfo
03612000 FF6AF860 0384 Explorer
003A2000 FF68E460 03B4 Internat
003a7000 ff68cd60 0130 osa
008C1000 FF6769A0 03E8 SVCHOST
01BAA000 FF65A020 01C0 CMD
00822000 FF86C960 038C Conime
03362000 FF6B3540 0388 NOTEPAD
* 00030000 8046Bb60 0000 IDLE
|
| __ The current process context is consistent with the result of the previous command output.
You can use the same method to perform verification.
2. Context Switches Times thread has been operated by operating system scheduling
This value is added when the system is called each time the system is called. Visual Studio attached to Tool SPY , in Thread Properties in Thread Properties, Context Switches indicates the number of times the thread has been scheduled in the system (SPY only shows this value when running in Windows NT / 2000, and there is no). Switch Times is located at the offset 4ch of KTEB in the location of the system.
: thread idle
TID KRNL TECKBTM STKTOP StackPtr User Teb Process (ID)
0000 8046BDF0 8046D040 80470040 8046FD90 000000 Idle (00)
: DD 8046BDF0 4C L 4
0010: 8046Be3C 0000E778 00000000 0000002 00000000 x .............
|
_T pointed out that the current IDLE thread has been called 0E778H (decimal 59256). Use the E command to change and look at the output of Spy !
3. The KPEB and process names of the thread belong to the process are located in KTEB 44H and KPEB 1FCH, respectively.
See I am in "
That talk about Windows NT / 2000 internal data structure "
NSFOCUS Magazine 11).
It should be noted that the above discussion is just for Windows 2000 Server Build 2195. If your system is not something or want to know how to get these values, please refer to the following narrative method: By looking for breakthrough, just like me The described Context Switches Times is displayed in Spy , and then uses the reverse engineering method, I also use this method to get this specific location.
For example! I used to output the result of the addr command in Softice for NT (including the process context) from what is from some famous newsgroups abroad, but no one has responded to it. It may be that my English is too bad, people don't understand what it means!)
The addr command output is as shown.
Later, I still think that the CR3 (register of the transcription page directory physical address) should be related to a specific process, which should be stored in the KPEB structure (actually this). And if this is true, it is not as long as enumeration (Enum) all KPEB in the system, you can get all CR3 values (of course, the premise is to find its relative KPEB offset value), the corresponding use I am "
That talk about Windows NT / 2000 internal data structure "
Can I remove the process name of all processes? (PID is also the same).
After analyzing the function of enumerating the system process in psapi.dll (Enumprocesses et al.), I found that the first process of the system startup SYSTEM's KPEB is stored at the address indicated by PsinitialSystemProcess exported in ntoskrnl.exe, and the system Each KPEB is coupled by a linked list, as for the definition of the list in NTDEF.H in Windows 2000 DDK:
Typedef struct _list_entry {
Struct _List_ENTRY * FLINK;
Struct _List_ENTRY * BLINK;
} List_entry, * pLIST_ENTRY, * RESTRICTED_POINTER PRLIST_ENTRY
With KPEB, track the corresponding code (this disassembly code will be listed below), you can find the CR3 value at 18H at 18H.
The above operation, in Windows 9x can be implemented by the undoCuMENTED function (Noname, Softice Export list in the Noname, Softice Export list) in the Windows 9x, but because Windows 9x is different from NT / 2000 kernel, Softice for 9x and NT The format output from the addr command is completely different. As for the Windows NT / 2000, I don't know if there is a ready-made function, at least now I have not found it, this is the topic.
Because the above narrative is still abstract, I still put the Softice's output results, more to understand:
: DD PsinitialsystemProcess L 4
0008: 8046A844 Fe4e1c60 E1000968 00000000 00000000 `.n.h .........
|
| _System's KPEB
: DD @ psinitialsystemprocess 18 L 4
0008: Fe4e1c78 00030000 00000000 000,000 00000000 ................
|
| _System process Context
: DD @ psinitialsystemProcess 9C L 4 // 9ch is the location of PID relative to KPEB
0008: Fe4e1cfc 00000008 FF8E65E0 8046A180 00000000 ..... E .... f ..... |
| _System process PID
: DD @ psinitialsystemProcess 1FC L 10 // 1FCH is the location of Process Name relative to KPEB
0008: Fe4e1e5c 74737953 00006d65 000000 00000000 system ..........
|
System Process Process Name_ |
:? @ (@ Psinitialsystemprocess a0) -a0
/ / Calculate the KPEB of the next process pointing to the system, 0A0H is the offset of the chain structure relative to KPEB
FF8E6540 4287522112 (-7445184) " 巈 @"
|
The next KPEB pointing to the _System process KPEB, can know SMSS.exe from Process Name (see below)
: DD @ (@ psinitialsystemprocess a0) -A0 18 L 4
0008: ff8e6558 02d59000 02d5a000 00000000 000,0000000000000000000000000000000000000 ................
|
| _SMSS.EXE process context
: DD @ (@ psinitialsystemprocess a0) -a0 9c L 4
0008: ff8e65dc 00000090 FF8E1880 Fe4e1D00 00000518 .......... n .....
|
| _SMSS.EXE PID
: DD @ (@ psinitialsystemprocess a0) -a0 1FC L 10
0008: FF8E673C 73736D73 6578652E 000000 00000000 SMSS.exe ........
|
SMSS.EXE process process name_ |
: DD @ (@ (@ psinitialsystemprocess a0)) - A0 18 L 4
.
(You can use the same way with the same way to track the end of the chain))
.
Implementing the code segment is as follows:
/ *
Due to the following code segments, the system data structure is required, that is, it is required to run in the RING 0 state.
In order to be in the NT / 2000 device driver. Due to the architecture of the device driver, the length of the code determined
Length, only the key code segments are listed here, you can find this WDM book, place this block into your code,
Or contact me directly (
TSU00@263.net).
* /
.
.
.
PLIST_ENTRY KPEBLISTHEAD, KPEBLISTPTR; / / PLIST_ENTRY Definition See
Ulong kpeblistoffset = 0xA0; / / Define the offset value of the linked list relative to KPEB
Ulong processnameoffset = 0x1fc; // Define the offset value of ProcessName relative to KPEB
Ulong processContextOffset = 0x18; // Define the offset value of Process Context relative to KPEB
Ulong pidoffset = 0x9c; // Defines the offset value of the PID relative KPEB
IF ((USHORT) NTBUILDNUMBER! = 2195) {
DBGPRINT ("Only Test On Windows 2000 Server Build 2195! / N");
Return;
}
DBGPrint ("/ n cr3 / t / tkpeb addr / TPID / T Name");
DBGPRINT ("/ n --- / t / t ------ / t --- / t ---- / n");
Kpeblisthead = kpeblistptr = (pLIST_ENTRY) ((char *) psinitialsystemprocess kpeblistoffset);
While (Kpeblistptr-> Flink! = kpeblisthead) {
Void * KPEB;
Char processname [16];
Ulong processContext;
Ulong PID;
// Take KPEB
KPEB = (void *) ((char *) kpeblistptr) - kpeblistoffset;
// Take ProcessName
MEMSET (ProcessName, 0, Sizeof (ProcessName);
Memcpy (ProcessName, ((char *) KPEB) ProcessNameOffset, 16);
// Take Process Context
ProcessContext = * (Ulong *) ((Char *) KPEB) ProcessContextOffset;
// Take the PID
PID = * (Ulong *) ((char *) KPEB) PIDOFFSET;
/ / Output to Debugger
DBGPRINT ("% 08X / T% 08X / T% 04x / T% S / N", ProcessContext, KPEB, PID, ProcessName;
/ / Point to the next chain list
Kpeblistptr = kpeblistptr-> flink;
}
.
.
.
After compiling and running with Checked, the debugger output is as follows (it is a bottom-up EnumProcesses implementation method):
CR3 KPEB ADDR PID NAME
---------- - ------
00030000 Fe4e1C60 0008 System
02D59000 ff8e7920 0090 smss.exe
003C1000 Fe520520 00ac CSRSS.EXE
026C6000 Fe51A020 00A8 WINLOGON.EXE
03209000 FF8A8D60 00DC Services.exe
.
. slightly
.
The reason why I spend so big to tell the process of Context, it seems that the theme of the environment is not consistent, mainly due to the closure of Windows NT / 2000, I think I really want to understand the environment switch, the Linux platform is easier Understand, it is important to know how to achieve some important data structures related to this, and then link with the X86 platform architecture, you can better help yourself. Using the similar methods described above, you can also find a lot of KPEB / KTEB important information, such as process priorities (KPEB 62H), time used in internal nuclear state and user state (KPEB 38h and KPEB 3CH), Thread ID (KTEB 1E4H), etc., compare comparisons with Linux Task_Struct.
I have talked so much, I still talk about the environment switching code in Windows 2000.
So what happens in Windows NT / 2000? It has been described in this DDK FAQ:
Q: What are the causes of a context switch in Windows NT?
A: There all two is switched.1.the thread yields it's quantum by blocking on Something (Event, Semaphore, etc.).
2.The time period is up.this is caused by a Timer Interrupt.
KidispatchInterrupt is the NT / 2000 timing for environmental switching routines, and below is listed below:
The code to implement similar function in Linux is located in /usr/src/linux/kernel/sched.c
00403A58 KidispatchInterrupt Proc Near
00403a58
00403A58 VAR_C = DWORD PTR-0CH
00403A58 var_8 = dWord PTR-8
00403A58 VAR_4 = DWORD PTR-4
00403a58
00403A58 MOV EBX, DS: 0FFDFF01CH
00403A5E LEA EAX, [EBX 800H]
00403A64 CLI
00403A65 CMP EAX, [EAX]
00403A67 JZ Short Loc_403A86
00403A69 PUSH EBP
00403A6A PUSH DWORD PTR [EBX]
00403A6C MOV DWORD PTR [EBX], 0FFFFFFFH
00403A72 MOV EDX, ESP
00403A74 MOV ESP, [EBX 81CH]
00403A7A PUSH EDX
00403A7B MOV EBP, EAX
00403A7D CALL SUB_460BA4
00403A82 POP ESP
00403A83 POP DWORD PTR [EBX]
00403A85 POP EBP
.
(Limited to space, this is slightly part, interested in step track)
.
; Another CR3 switching code:
The code implemented this function in Linux is located in /usr/src/linux/include/ASM-I386/PGTABLE.H
Implemented by macro definition set_page_dir, please refer to it.
At this time, the EDI storage kPeb (with Softice is followed by Softice), and the EAX is executing process Context.
This sentence combines MOV CR3, and EAX can track the specific location of CR3 in KPEB, I am tracking from here.
00403B87 MOV EAX, [EDI 18h]
00403B8A MOV EBP, [EBX 40H]
00403B8D MOV ECX, [EDI 30h]
00403B90 MOV [EBP 1CH], EAX
00403B93 MOV CR3, EAX; Eax-> CR3
00403B96 MOV [EBP 66H], CX
00403B9A XOR EAX, EAX
00403B9C CMP [EDI 20H], AX
Turning the error handling, if necessary, KebugCheck will also call, and a terrible blue screen crash.
00403BA0 JNZ SHORT LOC_403BCE
; LDTR blank selector
00403ba2 LLDT AX
00403ba5 Lea ECX, [ECX]
00403ba7
00403ba7 LOC_403BA7:; code xref: .text: 00403b7dj
00403ba7; .text: 00403BFAJ
; Add Context Switches Times
00403BA7 Inc DWORD PTR [ESI 4CH]
00403BAA Inc DWORD PTR [EBX 5C0H]
00403BB0 POP ECX00403BB1 MOV [EBX], ECX
00403BB3 CMP BYTE PTR [ESI 49H], 0
00403BB7 JNZ SHORT LOC_403BBD
00403bb9 POPF
00403bba xor Eax, EAX
00403bbc Retn
00403BBD LOC_403BBD:; code xref: .text: 00403bb7j
00403bbd POPF
00403BBE JNZ Short Loc_403BC3
00403BC0 MOV Al, 1
00403BC2 RETN
00403BC3 LOC_403BC3:; code xref: .text: 00403bbej
00403BC3 MOV CL, 1
00403BC5 Call DS: HalRequestsoftwareInterrupt
00403BCB XOR EAX, EAX
00403bcd Retn
.
.(slightly)
.
I have not yet been annotated, mainly some of the code is related to the code running environment, such as the error check (including validity, security, etc.), and I have not listed the code, if you are interested SoftICE Step Track You can find a lot of NT internal mechanisms.
Windows 2000 is a preemptive multi-threaded operating system, and there is no specific method of thread scheduling. True thread scheduled switching, but also considering many factors, such as thread state (whether it can be scheduling, etc.), thread priority, Affinity, etc., these specific important information, are also NTOSKRNL.EXE modules Processing, I can also be listed here in detail. This article only discusses how to get this information, but if you want to know more, it can still be further analyzed according to the discussion in the text.
I have exposed to a single-chip microcontroller, and I have seen it from the beginning to design a OS (may be just a few instructions, single-chip masters don't have a laughter), but when I have been touched by NT Kernel, I feel that I am a laughter. However, when contacting the NT core, you can refer to the Linux code, after all, their principles should be the same, although Linux is not a micro-kernel OS, and NT / 2000 is. Personally think that Linux's Task_Struct and NT's KPEB, the Bottom HALF mechanism in Linux is similar to NT's DPC (delay process call), and the like (although there is still a big difference in mechanism implementation). Since Microsoft does not provide any official document and the complexity of the NT core (there have been a criticized NT's microennote, I can't guarantee its absolute correctness if you find any mistakes. What is the suggestion, please tell it, thank you!
Reference:
1.jeffrey richter
<< Programming Applications for Microsoft Windows, Fourth Edition >>
2.Linux related documentation
3.Mark Russinovich related documentation
4.INTEL CORP << Intel Architecture Software Developer's Manual, VOLUME 3 >>