img uuty

int 2e进内核

发表于2005/4/5 22:25:00  4452人阅读

分类: 日记

一直很奇怪为啥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

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>



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.

0 0



取 消