This is a mirror of official site: http://jasper-net.blogspot.com/

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

| Sunday, January 30, 2011
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:

Collapse
#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);


Read more: Codeproject

Posted via email from Jasper-net

0 comments: