一直很奇怪为啥ntdll里的 int 2e是咋进入内核的,不是说中断在ring 3下都不能用的吗? 可这样ntdll不也不中了? 回头用个程序一试 int 0x2e 果然没事,没出错,,int 0x20 就会出错,但出错的具体过是cpu的事,用sice也只是显示错在那一条,后来在书上找到了(linux的书 ...)
Makes sure the interrupt was issued by an authorized source. First, it compares the Current Privilege Level (CPL), which is stored in the two least significant bits of the cs register, with the Descriptor Privilege Level (DPL) of the Segment Descriptor included in the GDT. Raises a "General protection" exception if the CPL is lower than the DPL because the interrupt handler cannot have a lower privilege than the program that caused the interrupt. For programmed exceptions, it makes a further security check. It compares the CPL with the DPL of the gate descriptor included in the IDT and raises a "General protection" exception if the DPL is lower than the CPL. This last check makes it possible to prevent access by user applications to specific trap or interrupt gates.
原来这段话总是理解不好,现在才有点明白,现在的windows程序,ring 3下的用的全都是cs 001B,ds,es 0023 的描述符,而内核的cs是0008,所以在int 0x2e的时候,CPL = 3 > DPL = 0,固定是不行,然后就再检查门描述符的DPL,2e的描述符的DPL = 3,所以int 0x2e可以执行了,,看看具体的可能会好一点
kd> !pcr
PCR Processor 0 @ffdff000
NtTib.ExceptionList: b96aac68
NtTib.StackBase: b96aadf0
NtTib.StackLimit: b96a8000
NtTib.SubSystemTib: 00000000
NtTib.Version: 00000000
NtTib.UserPointer: 00000000
NtTib.SelfTib: 7ffde000
SelfPcr: ffdff000
Prcb: ffdff120
Irql: 00000000
IRR: 00000000
IDR: ffff24e0
InterruptMode: 00000000
IDT: 80036400
GDT: 80036000
TSS: 8028c000
CurrentThread: fe8ec820
NextThread: 00000000
IdleThread: 8046c8c0
DpcQueue:
得到IDT地址80036400
2e的位置 80036400 + 2e*8 = 80036570
kd> dd 80036570
80036570 00083ea0 8046ee00 00086e40 80468e00
80036580 00088128 80068e00 0008a3e4 817c8e00
80036590 000834f4 80468e00 0008b844 817c8e00
800365a0 0008bdc4 817c8e00 00083512 80468e00
800365b0 0008351c 80468e00 00083526 80468e00
800365c0 00082db0 80068e00 0008e044 81888e00
800365d0 00083544 80468e00 0008da04 817c8e00
果然 segment:0008 offset 80463eA0 DPL 111 = 3
kd> ln 80463eA0
(80463ea0) nt!KiSystemService | (80463f75) nt!KiServiceExit
Exact matches:
nt!KiSystemService = <no type information>
idt在系统中的位置是不变的,至少我重起以后还是一样,,idt的位置存在idtr寄存器中
As mentioned in the earlier section Section 4.2.3, Intel provides three types of interrupt descriptors: Task, Interrupt, and Trap Gate Descriptors. Task Gate Descriptors are irrelevant to Linux, but its Interrupt Descriptor Table contains several Interrupt and Trap Gate Descriptors. Linux classifies them as follows, using a slightly different breakdown and terminology from Intel:
Interrupt gate
An Intel interrupt gate that cannot be accessed by a User Mode process (the gate's DPL field is equal to 0). All Linux interrupt handlers are activated by means of interrupt gates, and all are restricted to Kernel Mode.
System gate
An Intel trap gate that can be accessed by a User Mode process (the gate's DPL field is equal to 3). The four Linux exception handlers associated with the vectors 3, 4, 5, and 128 are activated by means of system gates, so the four assembly language instructions int3, into, bound, and int $0x80 can be issued in User Mode.
Trap gate
An Intel trap gate that cannot be accessed by a User Mode process (the gate's DPL field is equal to 0). Most Linux exception handlers are activated by means of trap gates.