不抽烟,少喝酒,多运动,多思考,多努力

仅仅是为了记录自己想记下的一些东西,方便自己以后查看
得到i8042prt!I8042KeyboardInterruptService 地址的好方法

键盘钩子比较麻烦的就是得到KeyboardInterruptService 的地址,有什么方法呢?lkd> !idt

Dumping IDT:

37: 806d0728 hal!PicSpuriousService37
3d: 806d1b70 hal!HalpApcInterrupt
41: 806d19cc hal!HalpDispatchInterrupt
50: 806d0800 hal!HalpApicRebootService
62: 84d587ec atapi!IdePortInterrupt (KINTERRUPT 84d587b0)
63: 84cebdd4 USBPORT!USBPORT_InterruptService (KINTERRUPT 84cebd98)
          USBPORT!USBPORT_InterruptService (KINTERRUPT 84ce4988)
          USBPORT!USBPORT_InterruptService (KINTERRUPT 84cddb78)
          USBPORT!USBPORT_InterruptService (KINTERRUPT 84cd6d10)
          USBPORT!USBPORT_InterruptService (KINTERRUPT 84ccfd98)
73: 84d08044 VIDEOPRT!pVideoPortInterrupt (KINTERRUPT 84d08008)
82: 84d58044 atapi!IdePortInterrupt (KINTERRUPT 84d58008)
83: 84dbf67c atapi!IdePortInterrupt (KINTERRUPT 84dbf640)
          atapi!IdePortInterrupt (KINTERRUPT 84dbf3d0)
92: 84c0a044 serial!SerialCIsrSw (KINTERRUPT 84c0a008)
93: 84c0bdd4 i8042prt!I8042KeyboardInterruptService (KINTERRUPT 84c0bd98)
a3: 84c0b044 i8042prt!I8042MouseInterruptService (KINTERRUPT 84c0b008)

lkd> dt _KINTERRUPT 84c0bd98
nt!_KINTERRUPT
   +0x000 Type             : 22
   +0x002 Size             : 484
   +0x004 InterruptListEntry : _LIST_ENTRY [ 0x84c0bd9c - 0x84c0bd9c ]
   +0x00c ServiceRoutine   : 0xf76cc495 /*就是这儿了*/    unsigned char i8042prt!I8042KeyboardInterruptService+0
   +0x010 ServiceContext   : 0x84d5da88
   +0x014 SpinLock         : 0
   +0x018 TickCount        : 0xffffffff
   +0x01c ActualLock       : 0x84d5db48 -> 0
   +0x020 DispatchAddress : 0x80541aa0     void nt!KiInterruptDispatch+0
   +0x024 Vector           : 0x193
   +0x028 Irql             : 0x8 ''
   +0x029 SynchronizeIrql : 0x9 ''
   +0x02a FloatingSave     : 0 ''
   +0x02b Connected        : 0x1 ''
   +0x02c Number           : 0 ''
   +0x02d ShareVector      : 0 ''
   +0x030 Mode             : 1 ( Latched )
   +0x034 ServiceCount     : 0
   +0x038 DispatchCount    : 0xffffffff
   +0x03c DispatchCode     : [106] 0x56535554

当然还可以特征码搜索啦!也麻烦!

rootkit上那个键盘王子介绍了一种很妙的方法!上代码。

PKINTERRUPT GetI8042PrtInterruptObject(void)
{
PDEVICE_OBJECT pDeviceObject = NULL; // Keyboard DeviceObject
PFILE_OBJECT   fileObject;
UNICODE_STRING keyName;
// PPORT_KEYBOARD_EXTENSION KeyboardExtension;
PKINTERRUPT ReturnValue = NULL;
  
RtlInitUnicodeString( &keyName, NT_KEYBOARD_NAME0 );

// Getting the DeviceObject top-of-the-stack of the kbdclass device
IoGetDeviceObjectPointer(&keyName,
         FILE_READ_ATTRIBUTES,
         &fileObject,
         &pDeviceObject);

// if fails
if( !pDeviceObject )
{
   return NULL;
}

// Tracking the DeviceStack
//
//
// If it is not a i8042prt
while( pDeviceObject->DeviceType != FILE_DEVICE_8042_PORT )//下一个就是了,0x27
{
   // go to the lower level object
   if (((PR_DEVOBJ_EXTENSION)pDeviceObject->DeviceObjectExtension)->AttachedTo)
    pDeviceObject = ((PR_DEVOBJ_EXTENSION)pDeviceObject->DeviceObjectExtension)->AttachedTo;
   else // here is lowest-level and couldn't find i8042prt
      return NULL;
}
//
// pDeviceObject == i8042prt's DeviceObject
//
ReturnValue = (PKINTERRUPT)((PPORT_KEYBOARD_EXTENSION)pDeviceObject->DeviceExtension)->InterruptObject;

return ReturnValue;
}

主函数中调用

   ADDR= (ULONG)GetI8042PrtInterruptObject( );
    dprintf("keyboatserv.SYS: 0X%08X\n", ADDR);
// +0x00c ServiceRoutine   : 0xf76cc495     unsigned char i8042prt!I8042KeyboardInterruptService+0
// 找到了函数的地址了;
I8042KeyboardInterruptServiceADDR=(ULONG)((PKINTERRUPT)GetI8042PrtInterruptObject()->ServiceRoutine);
dprintf("keyboatserv.SYS: 0X%08X\n", I8042KeyboardInterruptServiceADDR);

要用的结构

typedef struct _R_DEVOBJ_EXTENSION
{
CSHORT Type;
USHORT Size;
PDEVICE_OBJECT DeviceObject;
ULONG   PowerFlags;
PVOID Dope;
ULONG ExtensionFlags;
PVOID DeviceNode;
PDEVICE_OBJECT AttachedTo;
ULONG StartIoCount;
ULONG StartIoKey;
ULONG StartIoFlags;
PVOID Vpb;
} R_DEVOBJ_EXTENSION, *PR_DEVOBJ_EXTENSION;

typedef struct _PORT_KEYBOARD_EXTENSION {
    // Pointer back to the this extension's device object.
    PDEVICE_OBJECT      Self;
    PKINTERRUPT    InterruptObject;
} PORT_KEYBOARD_EXTENSION, *PPORT_KEYBOARD_EXTENSION;
typedef struct _KINTERRUPT {
    CSHORT   Type;
    CSHORT      Size;
    LIST_ENTRY          InterruptListEntry;
    ULONG               ServiceRoutine;
    ULONG               ServiceContext;
    KSPIN_LOCK          SpinLock;
    ULONG               TickCount;
    PKSPIN_LOCK         ActualLock;
    PVOID               DispatchAddress;
    ULONG         Vector;
    KIRQL               Irql;
    KIRQL               SynchronizeIrql;
    BOOLEAN             FloatingSave;
    BOOLEAN             Connected;
    CHAR                Number;
    UCHAR                ShareVector;
    KINTERRUPT_MODE     Mode;
    ULONG               ServiceCount;
    ULONG               DispatchCount;
    ULONG               DispatchCode[106];
} KINTERRUPT, *PKINTERRUPT;

有了函数地址大家就自己发挥了啊!什么模拟按键,读取端口。

还可以接着找鼠标的函数了,那就方便了啊

posted on 2009-04-27 23:18  adward  阅读(1222)  评论(1编辑  收藏  举报