суббота, 10 июля 2010 г.

IDT x64 win7

Некоторое время назад потребовалось мне узнать формат IDT и структуру _KINTERRUPT для 64битной windows. После недолгого гугления нашел вот этот замечательный пост. Радоваться правда пришлось недолго, ибо все что там описано соответствует исключительно 64битным xp и w2k3. В vista, windows7 (а равно и в более толстой сестре-близнеце ея w2008r2) структура _KINTERRUPT поменялась и выглядит сейчас так:

struct _KINTERRUPT_vista {
{
/* 0x00 */  short        Type;
/* 0x02 */  unsigned short  Size;
/* 0x08 */  PBYTE        Flink;
/* 0x10 */  PBYTE        Blink;
/* 0x18 */  PBYTE        ServiceRoutine;
/* 0x20 */  PBYTE        MessageServiceRoutine;
/* 0x28 */  unsigned long   MessageIndex;
/* 0x30 */  PBYTE        ServiceContext;
/* 0x38 */  unsigned __int64    SpinLock;
/* 0x40 */  DWORD        TickCount;
/* 0x48 */  unsigned __int64    ActualLock;
/* 0x50 */  PBYTE        DispatchAddress;
/* 0x58 */  DWORD        Vector;
/* 0x5c */  BYTE         Irql;
/* 0x5d */  BYTE         SynchronizeIrql;
/* 0x5e */  BYTE         FloatingSave;
/* 0x5f */  BYTE         Connected;
/* 0x60 */  BYTE         Number;
/* 0x61 */  BYTE         ShareVector;
/* 0x64 */  DWORD        Mode;
/* 0x68 */  DWORD        Polarity;
/* 0x6C */  DWORD        ServiceCount;
/* 0x70 */  DWORD        DispatchCount;
/* 0x78 */  unsigned __int64    Rsvd1;
/* 0x80 */  PBYTE        TrapFrame; // ptr to KTRAP_FRAME
/* 0x88 */  PBYTE        Reserved;
}; /* size: 0x90 */
 


struct _KINTERRUPT_w7
{
/* 0x00 */  short        Type;
/* 0x02 */  unsigned short  Size;
/* 0x08 */  PBYTE        Flink;
/* 0x10 */  PBYTE        Blink;
/* 0x18 */  PBYTE        ServiceRoutine;
/* 0x20 */  PBYTE        MessageServiceRoutine;
/* 0x28 */  unsigned long   MessageIndex;
/* 0x30 */  PBYTE        ServiceContext;
/* 0x38 */  unsigned __int64    SpinLock;
/* 0x40 */  DWORD        TickCount;
/* 0x48 */  unsigned __int64    ActualLock;
/* 0x50 */  PBYTE        DispatchAddress;
/* 0x58 */  DWORD        Vector;
/* 0x5c */  BYTE         Irql;
/* 0x5d */  BYTE         SynchronizeIrql;
/* 0x5e */  BYTE         FloatingSave;
/* 0x5f */  BYTE         Connected;
/* 0x60 */  unsigned long   Number;
/* 0x64 */  BYTE         ShareVector[4];
/* 0x68 */  DWORD        Mode;
/* 0x6c */  DWORD        Polarity;
/* 0x70 */  DWORD        ServiceCount;
/* 0x74 */  DWORD        DispatchCount;
/* 0x78 */  unsigned __int64    Rsvd1;
/* 0x80 */  PBYTE        TrapFrame; // ptr to KTRAP_FRAME
/* 0x88 */  PBYTE        Reserved;
}; /* size: 0x90 */


Соотв-но раньше DispatchAddress был по смещению 0x40 и переход на него выглядел как:

push rax
push rbp
mov rbp, rip-0x79 ; 0x70 - sizeof(_KINTERRUPT), 0x9 - offset RIP from KiInterruptTemplate
jmp qword ptr [rbp+0x40] ; _KINTERRUPT.DispatchAddress


Поскольку в vista/windows7 изменилось как смещение на DispatchAddress так и размер _KINTERRUPT, то сейчас ф-ция обработчика прерывания KiInterruptTemplate выглядит так:

push rax
push rbp
mov rbp, rip-0x99 ; 0x90 - sizeof(_KINTERRUPT_w7), 0x9 - offset RIP from KiInterruptTemplate
jmp qword ptr [rbp+0x50] ; _KINTERRUPT_w7.DispatchAddress


Весьма странно что сии полезные сведения гугл отказался мне выдавать - неужто и впрямь никто не озаботился описать сокровенные знания ?

Комментариев нет:

Отправить комментарий