1 2 Correction / addition to Prasad's "Undocumented NT" 3 4 From: dan_ps@my-deja.com 5 Reply to: dan_ps@my-deja.com 6 Date: Sun, 23 Apr 2000 10:03:30 GMT 7 Organization: Deja.com - Before you buy. 8 Newsgroups: 9 comp.os.ms-windows.programmer.nt.kernel-mode 10 Followup to: newsgroup 11 12 13 Recently , I had a chanche to borrow "Undocumented NT" by Mr Prasad 14Dabak from one of my friends and read it. While reading the chapters 15regarding builidng your own interrupt handlers or callgates under NT , 16I found that the book glosses over very important topics such as IDT 17in SMP enviroments , and a complete wrong presentation of what structure 18a interrupt handler is supposed to build on the stack to ensure shamless 19OS functionality. Mr's Prasad choice is a straigtforward pushad , 20folowed by setting the FS segment to the ring0 PCR selector. This way 21to build a trap frame for a interrupt is still used in Windows 95 , 22but in Windows NT , the layout of a correct Trap Frame is a little bit 23more complex. 24 The correct layout for a Trap Frame is the folowing: (note that 25it consitis from two parts , a stack frame wich is built by the CPU 26according to mode in wich was the CPU when the exception or software 27interrupt was generated , and a Context Capure frame who has to be built 28by the exception handler itself ) 29 30struc KeTrapFrame 31 32.DebugEBP resd 1 ; 00 33.DebugEIP resd 1 ; 04 34.DebugArgMark resd 1 ; 08 35.DebugPointer resd 1 ; 0C 36.TempCS resd 1 ; 10 37.TempEsp resd 1 ; 14 38 39.DR0 resd 1 ; 18 40.DR1 resd 1 ; 1C 41.DR2 resd 1 ; 20 42.DR3 resd 1 ; 24 43.DR6 resd 1 ; 28 44.DR7 resd 1 ; 2C 45.GS resw 1 ; 30 46 resw 1 ; 32 47.ES resw 1 ; 34 48 resw 1 ; 36 49.DS resw 1 ; 38 50 resw 1 ; 3A 51.EDX resd 1 ; 3C 52.ECX resd 1 ; 40 53.EAX resd 1 ; 44 54.PreviousMode resd 1 ; 48 55.ExceptionList resd 1 ; 4C 56.FS resw 1 ; 50 57 resw 1 ; 52 58.EDI resd 1 ; 54 59.ESI resd 1 ; 58 60.EBX resd 1 ; 5C 61.EBP resd 1 ; 60 62.Error resd 1 ; 64 63.EIP resd 1 ; 68 64.CS resw 1 ; 6C 65 resw 1 ; 6E 66.EFLAGS resd 1 ; 70 67.ESP resd 1 ; 74 68.SS resw 1 ; 78 69 resw 1 ; 7A 70.ES_V86 resw 1 ; 7C 71 resw 1 ; 7E 72.DS_V86 resw 1 ; 80 73 resw 1 ; 82 74.FS_V86 resw 1 ; 84 75 resw 1 ; 86 76.GS_V86 resw 1 ; 88 77endstruc 78 79 Note that this is the complete layout of a TrapFrame structure. 80Depending in what mode the CPU was when the exception occured , it may 81break earlier than .GS_V86. Also , it seems that fields above .DR0 are 82required only to debug builds. The declaration is for NASM , a free X86 83assembler , but this shouldnt have any kind of importance. 84 85 Now why one should build the correct layout for this stack 86frame ? The answer is that for shamlees operation of OS , a interrupt 87handler HAS to poke into interrupted thread's KTHREAD strucure a 88pointer to current TrapFrame existing on stack. This pointer will be 89later used by several ntoskrnl API's to gain access to interrupted 90thread;s acccess registers , or to gain information about the 91interrupted thread's ring3 stack location , or simply to capture all 92this information and package it into the form of a CONTEXT structure. 93Since ntoskrnl assumes the above layout for a stack frame , using any 94other structure size or layout can lead to unforeseen consequences. 95 96 Other things wich one may want to do when building a stack 97frame are : (assumes that the handler already set the FS register to 98kernel PCR selector ) 99 100 1. Save old Exception List head , and patch -1 to FS:0 ( thus 101overriding any potentialy pre-existing SEH handlers. 102 103 2. Determine whatever the interrupted thread was runing in 104ring0 or in ring3 and save this information in PreviousMode field of 105The Trap frame. This is also important , since many internal API's will 106check the Provious mode , acting differently in each case. (check CS 107image on stack for this ) 108 109 3. Get a pointer to the top of KeTrapFrame , and patch it into 110KTHREAD structure, at KTHREAD->TrapFrame. if ya want the layout of 111TrapFrame , there are multiple places where one can get it , but Im 112willing to post it here on request. 113 114 4. In the case that the hardware stack built by CPU does not 115contain an error code , fake one ( generaly , aborts always push an 116error code on stack , some exceptions do , and traps never push an 117error code by deafult. Suplimentary information can be found in intel 118arch. reference manual . 119 120 5. Optionaly enable the interrupts trough a STI . NT uses 121usualy interrupt gates , so the CPU will clear IF upon entering an 122exception handler. Note that in the case handling the interrupt or 123exception trough a trap gate , IF will not be automaticly cleared. 124 125 If you are interesting in the code wich can actualy build such 126a structure on the stack , use a kernel debugger and Break on Int 1270x2E , and single step the code . 128 129 As last words , I want to ensure Mr Prasad of my respect , and 130the thing that the only reason for this posting is my feeling that all 131holes must be covered , for the sake of all NT driver writing comunity. 132 133 Later , Dan 134 135 136 137 138 139 140 141Sent via Deja.com http://www.deja.com/ 142Before you buy. 143