Listing 3: idt.h Code to hook interrupt
#ifndef _IDT_H_ #define _IDT_H_ #define DISABLE_INTS KIRQL __Dioldirql__; \ KeRaiseIrql( HIGH_LEVEL, &__Dioldirql__ ); \ _asm { pushfd } \ _asm { cli } #define ENABLE_INTS {_asm popfd } \ KeLowerIrql(__Dioldirql__); // NT Uses the following values for it's 32-bit flat selectors #define NT_CS (0x8) #define NT_UCS (0x1B) #define NT_DS (0x23) #define NT_FS (0x30) // x86 specific constants used to TEST where an interrupt originated #define X86_VM (0x20000) // V8086 mode #define X86_USER (0x1) // Selector with bit 1 or 2 // set => user mode #pragma pack( push, PREIDT ) typedef struct NT_IDT { WORD wLoOfs; // Low Word of the ISR's offset WORD wSelector; // ISR's selector....should be 8 under NT WORD wFlags; // Flags...should almost always be 8E00 // for 32-bit code on NT. WORD wHiOfs; // Hi Word of ISR's offset // This hooks an IDT Entry to point to a new offset. // It leaves the current protection settings as they // are. Additionally, it returns the flat offset to the // old ISR handler. To set completely new protection // flags use Set() below. void Hook( PVOID newOfs, PVOID pOldOfs=NULL ) { DISABLE_INTS if ( pOldOfs != NULL ) *(PDWORD)pOldOfs = (wHiOfs<<16) + wLoOfs ; wLoOfs = WORD(newOfs) ; wHiOfs = WORD(((DWORD)newOfs)>>16) ; ENABLE_INTS } // This hooks an IDT Entry to a completely new interupt gate. // Unlike NT_IDT::Hook(), this explicitly sets the gate's // protection, both at the gate level & implicitly with the // code selector passed. void Set( PVOID ofs, WORD protection=0x8E00, WORD sel=NT_CS) { DISABLE_INTS wLoOfs = WORD(ofs) ; wSelector = sel; wFlags = protection; wHiOfs = WORD(((DWORD)ofs)>>16) ; ENABLE_INTS } NT_IDT operator=(NT_IDT *r_idt) { DISABLE_INTS wLoOfs = r_idt->wLoOfs; wSelector = r_idt->wSelector; wFlags = r_idt->wFlags; wHiOfs = r_idt->wHiOfs; ENABLE_INTS return *this; } NT_IDT operator=(NT_IDT r_idt) { DISABLE_INTS wLoOfs = r_idt.wLoOfs; wSelector = r_idt.wSelector; wFlags = r_idt.wFlags; wHiOfs = r_idt.wHiOfs; ENABLE_INTS return *this; } BOOL IsValid() const { return ( (wHiOfs) && (wSelector==NT_CS) ); } } NT_IDT, *PNT_IDT; #pragma pack( pop, PREIDT ) #pragma warning( disable : 4035 ) // Turn off no return // value warning // Get's the IDT base for the current processor inline PNT_IDT __fastcall GetIDTBase() { __asm { mov eax, _PCR KPCR.IDT } } #pragma warning( default : 4035 ) #endif //End of File