hook KeyboardClassServiceCallback 的一点注释
lkd> !drvobj kbdclass
Driver object (89567940) is for:
\Driver\Kbdclass
Driver Extension List: (id , addr)
Device Object list:
894ad030 89567310 // Kbdclass == 89567310 另外一个是鼠标
lkd> !devstack 89567310
!DevObj !DrvObj !DevExt ObjectName
> 89567310 \Driver\Kbdclass 895673c8 KeyboardClass0
895674f8 \Driver\i8042prt 895675b0 // 在deviceextension(895675b0)里寻找 KeyboardClassServiceCallback
8a0ba030 \Driver\ACPI 8a192978 00000072
!DevNode 8a0ba180 :
DeviceInst is "ACPI\PNP0303\4&2f7db942&0"
ServiceName is "i8042prt"
lkd> dd 895675b0
895675b0 895674f8 8949e008 00000000 8a0ba030
895675c0 8a0ba030 00000000 00000001 00040001
895675d0 00000000 895675d4 895675d4 00000000
895675e0 00000001 00000000 00000000 00000000
895675f0 00000001 00000000 000a0008 00000000
89567600 89567600 89567600 00000000 00000000
89567610 00000000 00000000 00000000 00000000
89567620 01000013 00000000 00000000 b8a382b5
lkd> dd 89567630
89567630 895674f8 00000000 00000000 00000000
89567640 01000013 00000000 00000000 b8a38164
89567650 895674f8 00000000 00000000 00000000
89567660 01000013 00000000 00000000 b8a383fd
89567670 895674f8 00000000 00000000 00000000
89567680 00000000 00000000 00000000 00000000
89567690 00000000 00000000 00000000 00000000
895676a0 0000000b 89567310 b8ba4192 00000002 // *UsingDeviceExt == Kbdclass (0x89567310)
// *(UsingDeviceExt+4) == KeyboardClassServiceCallback ( 0xb8ba4192 )
代码来自于 :https://www.cnblogs.com/zwt1234/p/4453597.html
下面主要分析其中寻找KeyboardClassServiceCallback地址的这段代码,先看图,图片是在xp下,用OSR的工具DeviceTree得到的 【http://www.osronline.com/article.cfm^article=97.htm】
查找KeyboardClassServiceCallback的过程就是通过比较找到i8042ptr的【DEV(unnamed)-> AttachedDevice】== 键盘类驱动【\driver\kbdclass->DeviceObject】的过程, 以图为例就是\device\KeyboardClass0,这样得到了DEV(unnamed)这个DeviceObject,然后在它的DeviceExtension中去寻找KeyboardClassServiceCallback的地址
if(pAttachedKbdDevice==pAttached) //【DEV(unnamed)-> AttachedDevice】== 【\driver\kbdclass->DeviceObject】
// pAttachedKbdDevice = 【\driver\kbdclass->DeviceObject】 其中的 \device\KeyboardClass0
// pAttached = 【DEV(unnamed)-> AttachedDevice】 其中的 \device\KeyboardClass0
{
UsingDeviceExt=(PBYTE)pUsingDeviceObject->DeviceExtension; // 此时的pUsingDeviceObject = 【DEV(unnamed)】这个DeviceObject
// 下面就是在他的DeviceExtension里面寻找KeyboardClassServiceCallback了
//遍历找到的端口驱动设备扩展下的每个指针
for (i=0;i<4096;i++,UsingDeviceExt += sizeof(PBYTE))
{
if (!MmIsAddressValid(UsingDeviceExt))
{
pUsingDeviceObject=pUsingDeviceObject->AttachedDevice;
goto Label_Continue;
}
//在端口驱动的设备扩展中,找到了类驱动的设备对象,填好类驱动设备对象后继续
/*文章里有这么个结构
typedef struct _KBD_CALLBACK
{
PDEVICE_OBJECT classDeviceObject;
KEYBOARDCLASSSERVICECALLBACK serviceCallBack;
BOOLEAN bSearch;
}KBD_CALLBACK,PKBD_CALLBACK;
*/
pTemp = *(PVOID*)UsingDeviceExt;
if (pTemp == pAttachedKbdDevice) // 判断是否 ptemp == \device\KeyboardClass0
// 如果相等的话那说明找到了,则pTemp = classDeviceObject, ptemp+4 = serviceCallBack
{
g_KbdCallBack.classDeviceObject = (PDEVICE_OBJECT)pTemp;
DbgPrint("classDeviceObject %8x\n",pTemp);
pTemp = *(PVOID*)(UsingDeviceExt+4); // 这里 ptemp = serviceCallBack = KeyboardClassServiceCallback
// 下面就是验证KeyboardClassServiceCallback这个函数是否在Kbdclass.sys的地址里了,因为KeyboardClassServiceCallback是由Kbdclass.sys提供的
if ((pTemp > KbdDriverStart)&&(pTemp < (PBYTE)KbdDriverStart+KbdDriverSize)&&MmIsAddressValid(pTemp))
{
// 至此,都找到了,下面就修改了
//记录回调函数的地址
g_KbdCallBack.serviceCallBack = (KEYBOARDCLASSSERVICECALLBACK)pTemp;
g_KbdCallBack.bSearch=TRUE;
status=STATUS_SUCCESS;
DbgPrint("serviceCallBack :%8x\n",pTemp);
DbgPrint("替换函数");
pOldFucAddr=(PVOID*)(UsingDeviceExt+4);
InterlockedExchangePointer((PVOID*)(UsingDeviceExt+4),MyCallBackFun); // 修改
goto Label_Exit;
}
break;
}
} // end for
}
另外 \device\KeyboardClass0 这个DeviceObject的_DEVOBJ_EXTENSION中的AttachedTo也指向【DEV(unnamed)】,双向的
【DEV(unnamed)】-> AttachedDevice 指向 \device\KeyboardClass0
【\device\KeyboardClass0】-> _DEVOBJ_EXTENSION-> AttachedTo 指向 【DEV(unnamed)】
参考 https://www.cnblogs.com/achillis/p/10181180.html