《寒江独钓_Windows内核安全编程》中修改类驱动分发函数

最近在阅读《寒江独钓_Windows内核安全编程》一书的过程中,发现修改类驱动分发函数这一技术点,书中只给出了具体思路和部分代码,没有完整的例子。

按照作者的思路和代码,将例子补充完整,发现将驱动安装在WIN7 32位环境下,键盘失效。

经调试发现,可能的原因是替换了\\Driver\\Kbdclass类驱动的所有分发函数导致,如果只替换分发IRP_MJ_READ的函数,不会有问题,以下为代码

  1 //替换分发函数  来实现过滤
  2 #include <wdm.h>
  3 #include <Ntddkbd.h>
  4 // Kbdclass驱动的名字
  5 #define KBD_DRIVER_NAME  L"\\Driver\\Kbdclass"
  6 //旧的函数地址
  7 PDRIVER_DISPATCH OldDispatchFun[IRP_MJ_MAXIMUM_FUNCTION+1];
  8 extern POBJECT_TYPE *IoDriverObjectType;
  9 PDRIVER_DISPATCH OldDIspatchRead;
 10 // 这个函数是事实存在的,只是文档中没有公开。声明一下
 11 // 就可以直接使用了。
 12 NTSTATUS
 13 ObReferenceObjectByName(
 14                         PUNICODE_STRING ObjectName,
 15                         ULONG Attributes,
 16                         PACCESS_STATE AccessState,
 17                         ACCESS_MASK DesiredAccess,
 18                         POBJECT_TYPE ObjectType,
 19                         KPROCESSOR_MODE AccessMode,
 20                         PVOID ParseContext,
 21                         PVOID *Object
 22                         );
 23 //新的分发函数地址
 24 NTSTATUS c2pDispatchGeneral( 
 25                                  IN PDEVICE_OBJECT DeviceObject, 
 26                                  IN PIRP Irp 
 27                                  ) 
 28 {
 29     PIO_STACK_LOCATION irpStack=IoGetCurrentIrpStackLocation(Irp);
 30     DbgPrint("irpStack->MinorFunction=%x\n",irpStack->MinorFunction);
 31     return OldDIspatchRead(DeviceObject,Irp);
 32     //return OldDispatchFun[irpStack->MinorFunction](DeviceObject,Irp);
 33 }
 34 #define  DELAY_ONE_MICROSECOND  (-10)
 35 #define  DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
 36 #define  DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)
 37 //卸载时候   要替换回来
 38 VOID  c2pUnload(IN PDRIVER_OBJECT DriverObject) 
 39 {
 40     NTSTATUS Status = STATUS_UNSUCCESSFUL;
 41     int nIndex = 0;
 42     PDRIVER_OBJECT KeyBoardDriverObject = NULL;
 43     UNICODE_STRING KeyBoardName;
 44     LARGE_INTEGER Delay;
 45 
 46     RtlInitUnicodeString(&KeyBoardName, L"\\Driver\\Kbdclass");
 47 
 48     Status = ObReferenceObjectByName(&KeyBoardName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType,
 49         KernelMode, NULL, &KeyBoardDriverObject);
 50 
 51     if (!NT_SUCCESS(Status))
 52     {
 53         DbgPrint("UnloadDriver Get Keyboard Driver Object Error\n");
 54         return;
 55     }
 56 
 57 
 58     //交换原来的分发函数
 59     
 60     // for (nIndex; nIndex < IRP_MJ_MAXIMUM_FUNCTION; nIndex++)
 61     // {
 62         // InterlockedExchangePointer(&KeyBoardDriverObject->MajorFunction[nIndex], OldDispatchFun[nIndex]);
 63     // }
 64     InterlockedExchangePointer(&KeyBoardDriverObject->MajorFunction[IRP_MJ_READ], OldDIspatchRead);
 65     DbgPrint("Change MajorFunction Successful!\n");
 66 
 67     Delay = RtlConvertLongToLargeInteger(5* DELAY_ONE_MILLISECOND);
 68     // 延时等待完成
 69     KeDelayExecutionThread(KernelMode, FALSE, &Delay);
 70     ObReferenceObject(KeyBoardDriverObject);
 71 }
 72 //驱动程序入口
 73 NTSTATUS DriverEntry( 
 74                      IN PDRIVER_OBJECT DriverObject, 
 75                      IN PUNICODE_STRING RegistryPath 
 76                      ) 
 77 { 
 78     ULONG i; 
 79     NTSTATUS status; 
 80 
 81     UNICODE_STRING uniNtNameString; 
 82     //返回kdbclass驱动对象
 83     PDRIVER_OBJECT KbdDriverObject = NULL; 
 84 
 85     KdPrint(("MyAttach\n")); 
 86 
 87     // 初始化一个字符串,就是Kdbclass驱动的名字。
 88     #if DBG
 89     _asm int 3;
 90 #endif
 91     RtlInitUnicodeString(&uniNtNameString, KBD_DRIVER_NAME); 
 92     // 请参照前面打开设备对象的例子。只是这里打开的是驱动对象。
 93     status = ObReferenceObjectByName ( 
 94         &uniNtNameString, 
 95         OBJ_CASE_INSENSITIVE, 
 96         NULL, 
 97         0, 
 98         *IoDriverObjectType, 
 99         KernelMode, 
100         NULL, 
101         &KbdDriverObject 
102         ); 
103     // 如果失败了就直接返回
104     if(!NT_SUCCESS(status)) 
105     { 
106         DbgPrint("MyAttach: Couldn't get the MyTest Device Object %x\n",status); 
107         return( status ); 
108     }
109     else
110     {
111         // 这个打开需要解应用。早点解除了免得之后忘记。
112         //解释为  可能导致DriverObject引用计数加1
113         
114     }
115     
116 
117 
118     OldDIspatchRead=KbdDriverObject->MajorFunction[IRP_MJ_READ];
119     InterlockedExchangePointer(&KbdDriverObject->MajorFunction[IRP_MJ_READ],c2pDispatchGeneral); 
120     ObDereferenceObject(KbdDriverObject);
121     // 卸载函数。
122     DriverObject->DriverUnload = c2pUnload; 
123 
124 
125     return status; 
126 }

 

posted @ 2015-04-24 10:42  银翼的魔术师  阅读(731)  评论(0编辑  收藏  举报