Analytic extension mechanism of the IDT Windows2000: Brief Download the complete source code for this article original source: http: //www.fz5fz.org/Archives/21.htm Introduction Today we talk about the extension mechanism interrupts under Windows 2000, to state clearly mentioned in this article The technology is not discovered, but it is only a little in learning the Windows kernel process. The purpose is to provide a practical information for friends who have just stepped into the bottom of Windows. At the same time, they also record their own learning. process. If you are a Windows Kernel master, you still hope that you can give you a lot of yourself; if you are also an initiator, you also welcome our FZ5FZ website to exchange discussions! Ok, let's go directly into the topic. If you don't know much about the interruption, it will be an exciting journey. 1. The Windows Trap Mechanism Introduction Traps is an indispensable system mechanism in the Windows system. When an interrupt (hardware interrupt or software interrupt) occurs, the processor captures this action and transfer the control of the system to a fixed handler to perform the corresponding operation processing. Before the processor starts processing, the processor environment parameters must be saved in the stack in the stack to use the system to restore. The system is implemented in a manner called trap frame, which saves the environmental data of all threads in the system to the kernel stack. After execution, the outlet mechanism is restored by the stack. The execution point in the system control process. Trap mechanisms in the kernel are divided into interrupts and exceptions. The interrupt is an asynchronous event that occurs in the system, which is independent of the processor status of the current system. At the same time, the interruption in the system can be divided into maskable interrupts and unmatched interrupts. The abnormality is a synchronous event, and the abnormality can be reproduced in a particular case, and the interrupt cannot be. Interrupts can also be divided into hardware interrupts and software interrupts. It is clear that the hardware interrupt is related to hardware, such as some of the operations executed by the I / O device, processor clock or hardware ports. The software interrupt is introduced by interrupting instruction INT XX. It is often a code that the application enters the operating system after the user mode is executed. At this time, the system provides users with a wide variety of system services. For example, we last mentioned system service calls, in Windows NT / 2000, is implemented by software interrupt INT 0x2e (System Service Interrupt), although Microsoft is used in Windows XP / 2003 To provide system services for users to "fast system call interface", there are still a large number of interrupt services still exist in systems. 2. Interrupt processing and its related procedures We discuss this data structure associated with specific processors, so there will be some portions of portions, this article only for Intel's X86 Family processor, and the program comes with this article also supports Performed normally on the Intel X86 processor. What is IDT? IDT (Interrupt Descriptor Table) is called an interrupt descriptor table. It is an array that can accommodate 8192 units. Each member in the array is a segment descriptor called "gate" length of 8 bytes. In the IDT door, it can be divided into three types: Interrrupt Gate, Trap Gate, and Task Gate, but mainly interrupt gate and trap door. And only a little difference between them, we only care about the interrupt door in IDT, if you are interested in this, please refer to the Intel processor's related document "Intel Architecture Software Developer ''s Manual, Volume 3 ".
At the same time, there is an interrupt descriptor table register (IDTR) in the system, which includes the base address of the system interrupt descriptor table and the limit information of the IDT, which is closely related to a compilation instruction SIDT. In the following, we will see that it is the basis and key to we achieve various interrupt descriptors! Another point is to be aware that after the page, segmentation, and virtual storage mechanisms are introduced in the Windows system, this scheduling mechanism is existed, and the code and data that need to be executed are transferred to memory, and the data that does not need to be adjusted. Deposit (auxiliary memory, such as hard disk, etc.). If we find that the data we need is not in the memory when performing some code, it will issue a "wrong page interrupt". At this time, the system will search for this interrupt ISR (Interrupt Service Routine, interrupt service case). Cheng), perform corresponding transfer work. Everyone can imagine what kind of result if our interrupt descriptor table is called out to abortion? At that time, the system will not be able to locate the "Listance Interrupt" service routine, and the system will crash! In the interrupt descriptor table, we just mentioned an interested register IDTR, of course, we are more concerned about the data segment segment selector in the IDT, the code segment selector, interrupt execution code offset The amount (offset) and the descriptor privilege level parameter of the interrupt descriptor. Let's take a look at the execution process of interrupt instructions, we should know that the application executes under user mode (Ring 3), and the interrupt descriptor table is in the system address space that can be accessed in kernel mode (Ring 0). After the software interrupt occurs, the processor first retrieves the incoming interrupt number parameters in the IDT. After finding the inlet unit of the response, check the permission level parameters of the interrupt door, see if it is Allowing the application to Ring 3, such an operating system retains the power to interrupt the software interrupt call control, but hardware interrupts and exceptions are not paying attention to the permissions. If the current privilge level, the value is greater than the permissions required by the interrupt gate descriptor (Descriptor privilege, the permissions will cause a general protection fault, and vice versa, the processor switching From the user stack to the kernel stack. Now is the time to save the thread environment, the processor will press the stack in the stack pointer (SS: ESP) and standard interrupt frames (EFLAGS and CS: EIP) in user mode. The processor then enters our interrupt service routine, and then returns to the called application after performing the related code processing. When the instruction IRETD is executed, the system stores the thread environment data stored in the stack, and then the subsequent code of the application will then perform the application after the interrupt command is executed. 3. Interrupt related data structure First we introduce the relevant data structure of a key assembly instruction SIDT we mentioned earlier. After executing the instruction SIDT, the system will save the base address and restriction of the interrupt descriptor table (a total length of six bytes) in the variable pointer points to the instruction, which is the entrance of our IDT operation. Typedef struct _idtr {
/ / Define the limitations of the interrupt descriptor table, length two bytes;
Short idtlimit;
/ / Define the base address of the interrupt description table, length four bytes;
Unsigned int IDTBASE;
} Idtr, * pidtr; When we get the Idt's entry, we will retrieve the IDT unit corresponding to the interrupt number we need to handle in the interrupt descriptor. The unit contains many data structures we need to pay attention to, where we are the most Caring for code segment selectors, interrupt code execution offset and privilege level, then we give its definition first, we will discuss their specific applications in detail below. Typedef struct _idtenTry {
// Interrupt 16 bits of the bottom of the code offset;
UNSIGNED SHORT OFFSETLOW;
// selector, that is, the register;
UNSIGNED Short Selector;
// Reserved position, always zero;
UNSIGNED Char Reserved;
Type of the door in IDT: including interrupt door, trap door and task door;
Unsigned char TYPE: 4;
// segment signage;
Unsigned char segmentflag: 1;
// The permission level of the interrupt door, 0 indicates the kernel level, and 3 means user-level;
UNSIGNED Char DPL: 2;
// Render the flag;
Unsigned char present: 1;
// Interrupt the high 16 bits of the execution code offset;
UNSIGNED SHORT OFFSTHIGH;
} IDTENTRY, * PIDTENTRY
4. Creating a software interrupt hook as a normal Windows programmer, perhaps you need to be familiar with the basic functions of the system, as well as skilled mastery of general program development. But for an idea of Windows core-level analytics developers, it is very necessary to understand the underlying system under the system, and it is also very important. Hook creates a great opportunity for us, which makes us understand the idea of internal operational mechanisms. At the same time, writing a system-related monitoring program can automatically record and analyze the internal operation of the system. Of course, we cannot be limited to the system's understanding, we are more eager to implement the modifications and expansion of the system, change the original operational characteristics of the system, injecting the functional components we need, so that the system is more suitable for ourselves, and we most hope to see Operation. As we talked about the creative system service call to intercept system service calls, the system service is implemented by system service interrupt, int 0x2e, can also achieve monitoring by interception software interruption Modify the function of the system service call. Here we mainly discuss the creation of hooks for software interrupts, but it is also an exception to hardware interrupts and exceptions, we can also apply the methods mentioned herein to hardware interrupts and exceptions. For example, we can also write the kernel keyboard logger by intercepting the keyboard-driven interrupt call, which can be used directly to perform each keystroke and release, but this also needs to be used to provide us with The function related to the hardware interrupt hook. 5, how to create a software interrupt hook? In fact, the process of creating software interrupt hooks should be more obvious. Here we will briefly introduce the process of creating hooks and then perform specific explanations with actual code. First we get the IDT's base address IDTBASE, then search for the iDT base IDTBASE, then search us in the interrupt descriptor table, I need hook's interrupt number hookintidi, it should It is an integer in 0-255, although the latest Intel processor claims to support 8192 interrupt descriptor units, but due to certain limiting reasons, only 256 interrupt description doors can only be processed. After finding the interrupt description door we need HOOK, save its original interrupt code offset (32 bits) to a global variable Oldisr to use us when performing interrupt or recovery IDT. The execution code offset of the corresponding interrupt number in this new IDT pointing to our own processing code. In our processing code newisr, pay attention to save some thread environments, after processing the executor we have additionally added (Monitor, monitor registry related 16 system service calls), restore the site and perform the interrupt gate code. In this way, I can't see any additional processing in the interruption door, I feel that there is no two days ago! If we just handle the previous program code we have added without continuing to perform the previous program code corresponding to the interrupt gate, the system will chaos even crash! Also when we uninstall our software interrupt hook, it is a reverse job. First obtain the base address of the IDT, then assign the old execution code address offset saved in the global variable to the Offsetlow / OffsetHigh of the corresponding interrupt number. Probably the process is almost the same, the relevant procedure is T-hookint, let's take a look at the code! Voidhookint (Void)
{
/ / Save the base address of the IDT entry and the data structure of the restriction information;
IDTR IDTR;
// Remove the pointer of the IDT array, and you can find the interrupt door corresponding to the HOOK interrupt number;
PidtenTry IDTentry; // Compilation Directive SIDT to get IDT entry information;
__ASM SIDT IDTR;
// give an IDT base address value;
IDTENTRY = (PIDTENTRY) idtr.idtbase;
/ / Save the interrupt number hookintid corresponding to the execution code offset pointed to by the interrupt gate, in order to perform interrupt processing or recovery;
Oldismr = ((unsigned int) idtent "dffsethigh << 16) │ (idTentry [hookintid] .offsetlow);
// Off-interrupt
__asm CLI
/ / Update 16 bits of the bottom of the execution code offset;
IDTENTRY [hookintid] .offsetlow = (unsigned short) newisr;
/ / Update 16 bits of execution code offset;
IDTENTRY [hookintid] .offsethiGH = (unsigned int) NEWISR >> 16);
// open interrupt
__ASM STI;
}
Void
UnHookint (Void)
{
IDTR IDTR;
PidtenTry IDTENTRY;
__ASM SIDT IDTR;
IDTENTRY = (PIDTENTRY) idtr.idtbase;
__asm CLI
// Restore the interrupt number hookintid corresponds to the bottom 16 bits of the code offset;
IDTENTRY [hookintid] .offsetlow = (unsigned short) Oldism
// Restore the interrupt number hookintid corresponds to the interrupt gate to execute the code offset height 16 bits;
IDTENTRY [hookintid] .offsethiGH = (unsigned int) ((unsigned int) Oldismr >> 16)
__ASM STI;
}
Void
__fastcall
Monitor ()
{
......
// Due to the interruption number of our handle, it is 0x2e,
/ / Correspond to System Service Interrupt,
// distinguish system service call by obtaining values in the EAX register;
__ASM MOV DWSERVICEID, EAX;
// Execute the kernel function to get the ID number of the current process;
DWProcessID = (unsigned int) psgetcurrentprocessid ();
// Enhance the current IRQL to prevent being interrupted;
KeraiseiRQL (High_level, & OldiRQL);
Switch (dWServiceID)
{
// If the value corresponding to the EAX is 0x23,
// The ZWCReateKey system service call corresponding to Windows2000;
Case 0x23:
DBGPRINT ("Processid:% D ZwcreateKey / N", DWProcessID;
Break;
......
DEFAULT:
Break;
}
// Restore the original IRQL;
KELOWERIRQL (Oldirql);
}
6. The role of adding software interrupts and principles By adding software interrupts, we can extend the functionality of the system and change many of the system's operational behavior. In the previous, we introduced the new system service call to the system to extend the system. You can also reach the purpose of adding system service calls by adding a new software interrupt, and we can perform Ring 0 level in the new interrupt handler. Code, what is a gratifying! In fact, in IDT, 256 interrupt door units are not fully utilized, and there are some interrupts that will be used in the future, we can add some mechanisms to these unused interrupts to me. In fact, the process of adding software interrupts and the addition of our detailed additive software interrupt hooks have a lot of similarities, so I don't do a very detailed introduction. Also, first get the base address of the IDT, then find the interrupt door descriptor corresponding to the interrupt number we will add, then assign a value to the associated parameters, making it a veritable software interrupt gate. At this time, we can use the interrupt command int XX in the application to call our own service programs in the door. 7. Add software interrupt implementation process related programs for t-addig (add interrupt Gate), let's take a look at the code Ha ~ ntstatusInstallug ()
{
......
// Determine if the interrupt we want to add has been occupied;
IF (idtence [addintid] .offsetlow! = 0
││ idtence [addint] .offsethigh! = 0)
{
Return status_unsuccessful;
}
// Copy the original interrupt gate description information;
RTLCopyMemory (& OldIdtentry, & idTENTRY [AddIndId], SIZEOF (OldIdtentry);
// Off-interrupt
__asm CLI
/ / Update 16 bits of the bottom of the execution code offset;
IDTENTRY [AddInt] .offsetlow = (unsigned short) interruptServiceeroutine
// The segment selector of the destination code segment, CS is 8;
IDTENTRY [AddIntiD] .selector = 8;
// Reserved position, always zero;
IDTENTRY [AddIntid] .Reserved = 0;
// door type, 0xe represents the breaking door;
IDTENTRY [AddIntiD] .type = 0xE;
// segmentflag set 0 code as a segment;
IDTENTRY [AddIntiD] .SEGMENTFLAG = 0;
// Descriptor permission level is 3, allowing the user mode program to call this interrupt;
IDTENTRY [AddIntiD] .dpl = 3;
// Render the flag, set to one;
IDTENTRY [AddIntiD] .present = 1;
/ / Update 16 bits of execution code offset;
IDTENTRY [AddInd] .offseThigh = (unsigned int) InterruptServiceeroutine >> 16);
// open interrupt
__ASM STI
Return status_success;
}
Void
REMOVEIG ()
{
......
__asm CLI
// Restore our modified interrupt door descriptor;
RTLCopyMemory (& iDTentry), & OldIdtentry, Sizeof (OldIdTentry);
__ASM STI
}
Externvoid
_CDECL
InterruptServiceRoutine (Void)
{
Unsigned int command;
/ / Get the value in the EAX register, accept command parameters incorporated from user mode;
__ASM MOV Command, EAX;
/ / Execute the kernel code to get the operating system version number;
DBGPRINT ("NTBUILDNUMBER ==% D / N", (unsigned short) NTBUILDNUMBER);
// Interrupt return;
__ASM IRETD;
}
After writing here, we only introduced some basic methods of extended IDT, of course, there are still a lot of more deeper, more dedicated to our research, need everyone trying to explore. For example, we can extend T-hookint, not just system service calls related to monitoring system registry operations, but in Windows XP / 2003, due to some changes in its intrinsic mechanism, the system service call is not Such a reality. Of course, there is also an IDT-based core-based lattice, which can provide any user with any user with any user with the SYSTEM privilege level of Command. In short, exploring the travelers of the Windows kernel mystery have not ended, perhaps this can only be settled once. Appendix: Since this article is more, there is no post here, welcome friends who are interested to go to our homepage, thank you ~ About us: FZ5FZ mainly engaged in network / system security learning and research, in-depth programming technology Analysis and discussion, adhere to the original, pursue sharing. FZ5FZ Homepage: http://www.fz5fz.org