Click here to Skip to main content
11,705,610 members (50,582 online)
Click here to Skip to main content

Interrupt Hooking and retrieving device information on Windows NT/2000/XP

, 30 Jul 2003 GPL3 242.4K 5.7K 91
Rate this:
Please Sign up or sign in to vote.
This article shows you how to hook interrupts, and how to get device resource information from the registry

Introduction

Hi, this is my first article, and English is not my natural language. So first, please excuse my terrible language. This article is about hooking software/hardware interrupts and will also show you, how to retrieve device resource information from the registry. I ASSUME A LITTLE BIT OF DRIVER CODING KNOWLEDGE FOR THIS ARTICLE!

Background/How this works

Ok, now I'll explain, how interrupt hooking works. When an interrupt (software or hardware) occurs, the cpu uses the idt (interrupt descriptor table) to read the necessary information about how to handle that interrupt. You can get the table's memory address like this:

#pragma pack(1)    // 2 works, too
typedef struct tagIDT
{
    WORD    wLimit;
    DWORD    dwBase;
} IDT, *PIDT;
#pragma pack()

VOID
LoadIDT( 
        OUT    PIDT        pIdt )
{
    __asm
    {
        MOV EAX, [pIdt]  // load offset into EAX
        SIDT [EAX]
    }
}

The command SIDT saves the idt information, which consists of the idt base address and the size(limit) of the table, to the specified memory address.

Now you can read single descriptors from the table. Here is their structure:

 

#pragma pack(1)
typedef struct tagINT_VECTOR
{
    WORD    wLowOffset;        // LOWORD of the handler's offset
    WORD    wSelector;        // selector of the handler's offset
    BYTE    bAccess;        // 0-3: Type
                            // 4:    ?(=0)
                            // 5-6:    DPL
                            // 7:    Present
    BYTE    wUnused;        // 0, 0, 0, unused (binary)
    WORD    wHighOffset;    // HIWORD of the handler's offset
} INT_VECTOR, *PINT_VECTOR;
#pragma pack()

Here are the functions to load/save a descriptor:

 

VOID
LoadINTVector( 
        IN    PIDT        pIdt, 
        IN    UCHAR        iVector, 
        OUT    PINT_VECTOR    pVector )
{
    __try
    {
        DWORD dwBase = pIdt->dwBase + iVector * sizeof(INT_VECTOR);
        memcpy( pVector, (const void *)dwBase, sizeof(INT_VECTOR) );
    }
    __except( 1 )
    {
        DPRINT( "LoadINTVector: Exception\n" );
    }

    DPRINT( "LoadINTVector: Vector 0x%.2X successfully dumped\n",
       iVector );
}

VOID
SaveINTVector( 
        IN    PIDT        pIdt, 
        IN    UCHAR        iVector, 
        IN    PINT_VECTOR    pVector )
{
    __try
    {
        DWORD dwBase = pIdt->dwBase + iVector * sizeof(INT_VECTOR);
        __asm{ PUSHFD };
        __asm{ CLI };        // IMPORTANT: clear interrupt flag!!!
        memcpy( (void *)dwBase, pVector, sizeof(INT_VECTOR) );
        __asm{ POPFD };
    }
    __except( 1 )
    {
        DPRINT( "SaveINTVector: Exception\n" );
    }

    DPRINT( "SaveINTVector: Vector 0x%.2X successfully set\n", iVector );
}

 

Build-in ioctl codes:

 

  • IOCTL_HOOK_INT Hooks only one specified interrupt.
    • Parameters: IN UCHAR iVector
  • IOCTL_UNHOOK_INT Unhooks only one specified interrupt.
    • Parameters: IN UCHAR iVector
  • IOCTL_HOOK_ALL_INT Hooks all useful interrupts.
    • Parameters: none
  • IOCTL_DUMP_IDT Dumps the whole IDT table.
    • Parameters: OUT IDT_ENTRY Array[256]
  • IOCTL_GET_INT_COUNTS Retrieves the interrupt call counts.
    • Parameters: OUT __int64 Array[256]
  • IOCTL_GET_START_TIME Retrieves the time when IOCTL_HOOK_ALL_INT was called (PerformanceCounter).
    • Parameters: OUT __int64 Time

To call these ioctl codes, open the driver like this:

 

DWORD dwOut; 
HANDLE hDriver = CreateFile( <a>\\\\.\\InterruptHook</a>, 
     GENERIC_READ |GENERIC_WRITE, 0, 
     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 

DeviceIoControl( hDriver, IOCTL_X, inbuffer, inbufferlen, 
        outbuffer, outbufferlen, &dwRet, NULL ); 

 

Retrieving device information from the registry

Ok, this is quite easy. Have a look at the registry at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum! There you'll find several subkeys like "ACPI" or "STORAGE". These subkeys have further subkeys, which are kinda classes, I don't know exactly what they do. They have subkeys, too, representing device drivers! Their subkey "Control" may include a value called "AllocConfig" (type REG_RESOURCE_LIST). REG_RESOURCE_LIST is not documented by microsoft!

It's a structure defined in ntddk.h:

 

typedef struct _CM_RESOURCE_LIST {
  ULONG                          Count;
  CM_FULL_RESOURCE_DESCRIPTOR List[1];
} CM_RESOURCE_LIST, *PCM_RESOURCE_LIST;

typedef struct _CM_FULL_RESOURCE_DESCRIPTOR {
  INTERFACE_TYPE            InterfaceType;
  ULONG                        BusNumber;
  CM_PARTIAL_RESOURCE_LIST  PartialResourceList;
} CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;

typedef struct _CM_PARTIAL_RESOURCE_LIST {
  USHORT  Version;
  USHORT  Revision;
  ULONG  Count;
  CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
} CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;

typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {
    UCHAR Type;
    UCHAR ShareDisposition;
    USHORT Flags;
    union {
        struct {
            PHYSICAL_ADDRESS Start;
            ULONG Length;
        } Generic;
        struct {
            PHYSICAL_ADDRESS Start;
            ULONG Length;
        } Port;
        struct {
            ULONG Level;
            ULONG Vector;
            ULONG Affinity;
        } Interrupt;
        struct {
            PHYSICAL_ADDRESS Start;
            ULONG Length;
        } Memory;
        struct {
            ULONG Channel;
            ULONG Port;
            ULONG Reserved1;
        } Dma;
        struct {
            ULONG Data[3];
        } DevicePrivate;
        struct {
            ULONG Start;
            ULONG Length;
            ULONG Reserved;
        } BusNumber;
        struct {
            ULONG DataSize;
            ULONG Reserved1;
            ULONG Reserved2;
        } DeviceSpecificData;
    } u;
} CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;

You can find a documentation of these structures here.

 

About the GUI

The GUI just refreshes the interrupt call count every 50ms and displays it. CPS means CALLS PER SECOND! Open a context menu when selecting an IRQ entry from the list!

Info on compiling

  • The GUI can be compiled by Visual Studio 6.0 or higher.
  • For the driver, you'll need the Windows NT(or higher) DDK(order it from Microsoft).

To compile it, use the DDK build environment, change to the source directory and type "build -cZ". If you don't have the DDK, use the compiled driver from the binary zip file. Here a little comment about the Visual Studio 6.0 C++ compiler/preprocessor:

When compiling my software, the compiler seems to interpret the CTL_CODE macro wrong, so I had to use the hexadecimal values instead of the macro.

Known Issues

  • My floppy disk doesn't work anymore after hooking the interrupts (reboot solves the prob)
  • Spy++ ends in bluescreen when hooking a windows procedure (reboot...)
  • Please send me feedback about other issues!!!

DISCLAIMER

USE THIS SOFTWARE ON YOUR OWN RISK!!! I DON'T KNOW WHAT HAPPENS TO OTHER COMPUTERS! NO WARRANTY FOR POSSIBLE DAMAGES!!!

History

  • July 31th, 2003 - Posted this article on CodeProject

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

Alexander M.,
Germany Germany
I'm a lazy coder who started coding at the age of 8 and I live in (c)old Germany Frown | :(
I'm a university student at LMU munich (http://www.lmu.de/).
Course of studies: computer science of course Wink | ;)

I'm also very interested in system programming, assembler and SIMD... but they are not listed as interests choices here :(

You may also be interested in...

Comments and Discussions

 
SuggestionToo simple for SMP machines Pin
Haftmann, Henrik11-Mar-15 6:37
memberHaftmann, Henrik11-Mar-15 6:37 
Questionchanging the code INT_VECTOR_HANDLER Pin
FirstSKY18-Jun-12 2:25
memberFirstSKY18-Jun-12 2:25 
GeneralMy vote of 5 Pin
manoj kumar choubey1-May-12 23:40
membermanoj kumar choubey1-May-12 23:40 
QuestionBig Kernel Pimping Pin
TheRaven18-Sep-11 13:56
memberTheRaven18-Sep-11 13:56 
Nice!
Might need a touch updated in areas, but the methodologies will be largely intact. Definitely stuff of a good to know nature and in some industry segments must know.

5-stars
I was unaware of that...

Generalin windows 98 Pin
zon_cpp19-Jan-08 19:48
memberzon_cpp19-Jan-08 19:48 
GeneralRe: in windows 98 Pin
Alexander21-Jan-08 3:33
member Alexander21-Jan-08 3:33 
GeneralRe: in windows 98 Pin
zon_cpp21-Jan-08 20:56
memberzon_cpp21-Jan-08 20:56 
GeneralCode doesnt work Pin
teomannaskali10-Dec-07 12:59
memberteomannaskali10-Dec-07 12:59 
GeneralRe: Code doesnt work Pin
Alexander21-Jan-08 3:37
member Alexander21-Jan-08 3:37 
Generalnew case Pin
samira samehforooghy25-Aug-07 19:30
membersamira samehforooghy25-Aug-07 19:30 
GeneralRe: new case Pin
Alexander M.27-Aug-07 15:29
memberAlexander M.27-Aug-07 15:29 
GeneralRe: new case Pin
samira forooghi27-Aug-07 22:41
membersamira forooghi27-Aug-07 22:41 
Questionany way to interrupts access [modified] Pin
samira samehforooghy8-Aug-07 1:11
membersamira samehforooghy8-Aug-07 1:11 
AnswerRe: any way to interrupts access Pin
Alexander M.16-Aug-07 15:46
memberAlexander M.16-Aug-07 15:46 
GeneralRe: any way to interrupts access Pin
samira samehforooghy25-Aug-07 19:32
membersamira samehforooghy25-Aug-07 19:32 
AnswerRe: any way to interrupts access [modified] Pin
Member 92216454-Aug-12 22:07
memberMember 92216454-Aug-12 22:07 
GeneralWindows hangs! Pin
oliwan1-Nov-06 4:53
memberoliwan1-Nov-06 4:53 
GeneralRe: Windows hangs! Pin
Alexander M.1-Nov-06 5:08
memberAlexander M.1-Nov-06 5:08 
GeneralRe: Windows hangs! Pin
oliwan1-Nov-06 5:22
memberoliwan1-Nov-06 5:22 
GeneralInterrupt 0x07 - No coprocessor available Pin
samu13-Jun-06 1:52
membersamu13-Jun-06 1:52 
GeneralRe: Interrupt 0x07 - No coprocessor available Pin
Alexander M.13-Jun-06 10:39
memberAlexander M.13-Jun-06 10:39 
GeneralMemory Hook Pin
catalin180410-May-06 4:56
membercatalin180410-May-06 4:56 
GeneralRe: Memory Hook Pin
Alexander M.11-May-06 1:17
memberAlexander M.11-May-06 1:17 
QuestionInterrupt when cd eject button pressed Pin
werner2715-Apr-06 5:52
memberwerner2715-Apr-06 5:52 
AnswerRe: Interrupt when cd eject button pressed Pin
Alexander M.15-Apr-06 10:41
memberAlexander M.15-Apr-06 10:41 
QuestionNo Details Pin
easter_200728-Feb-06 9:49
membereaster_200728-Feb-06 9:49 
AnswerRe: No Details Pin
Alexander M.2-Mar-06 4:08
memberAlexander M.2-Mar-06 4:08 
GeneralCrash Pin
foo232211-Oct-05 5:26
sussfoo232211-Oct-05 5:26 
GeneralRe: Crash Pin
Alexander M.11-Oct-05 5:54
memberAlexander M.11-Oct-05 5:54 
GeneralRe: Crash Pin
Anonymous11-Oct-05 8:59
sussAnonymous11-Oct-05 8:59 
GeneralRe: Crash Pin
Anonymous12-Oct-05 1:00
sussAnonymous12-Oct-05 1:00 
Questionwhat's wrong with me? Pin
dearsohucom7-Jul-05 15:53
memberdearsohucom7-Jul-05 15:53 
AnswerRe: what's wrong with me? Pin
Alexander M.8-Jul-05 23:27
memberAlexander M.8-Jul-05 23:27 
QuestionAlso I can not hook IRQ0 ? Pin
Anonymous4-Jul-05 7:21
sussAnonymous4-Jul-05 7:21 
AnswerRe: Also I can not hook IRQ0 ? Pin
Alexander M.5-Jul-05 3:05
memberAlexander M.5-Jul-05 3:05 
AnswerRe: Also I can not hook IRQ0 ? Pin
angello14-Mar-07 6:31
memberangello14-Mar-07 6:31 
GeneralRe: Also I can not hook IRQ0 ? Pin
angello16-Mar-07 2:11
memberangello16-Mar-07 2:11 
Generalinterrupt gate descriptor Pin
benchi13-Apr-05 2:29
memberbenchi13-Apr-05 2:29 
GeneralRe: interrupt gate descriptor Pin
Alexander M.13-Apr-05 3:04
memberAlexander M.13-Apr-05 3:04 
QuestionWhy I can not hook IRQ0(system timer) by using your program? Pin
ILYTT12-Apr-05 17:26
memberILYTT12-Apr-05 17:26 
AnswerRe: Why I can not hook IRQ0(system timer) by using your program? Pin
Alexander M.13-Apr-05 2:47
memberAlexander M.13-Apr-05 2:47 
GeneralRe: Why I can not hook IRQ0(system timer) by using your program? Pin
ILYTT13-Apr-05 14:54
memberILYTT13-Apr-05 14:54 
GeneralRe: Why I can not hook IRQ0(system timer) by using your program? Pin
Anonymous30-Apr-05 3:42
sussAnonymous30-Apr-05 3:42 
Generalwhy floppy does not work... Pin
benchi5-Apr-05 1:36
memberbenchi5-Apr-05 1:36 
GeneralRe: why floppy does not work... Pin
Alexander M.5-Apr-05 7:47
memberAlexander M.5-Apr-05 7:47 
GeneralHooking the Multimedia Timer Pin
hasi2514-Feb-05 23:44
memberhasi2514-Feb-05 23:44 
GeneralRe: Hooking the Multimedia Timer Pin
Alexander M.15-Feb-05 5:54
memberAlexander M.15-Feb-05 5:54 
GeneralHook to a SCSI driver for the IRP_MJ_SCSI irp Pin
Ramesh Karnati6-Feb-05 23:34
memberRamesh Karnati6-Feb-05 23:34 
GeneralRe: Hook to a SCSI driver for the IRP_MJ_SCSI irp Pin
Alexander M.7-Feb-05 3:22
memberAlexander M.7-Feb-05 3:22 
QuestionHow to detect the activity of audio device? Pin
Jesa19-Jan-05 22:25
memberJesa19-Jan-05 22:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150819.1 | Last Updated 31 Jul 2003
Article Copyright 2003 by Alexander M.,
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid