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

posted @ 2020-10-24 21:09  一条小鳄鱼  阅读(817)  评论(0)    收藏  举报