• 《寒江独钓_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
    ",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
    ");
     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!
    ");
     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
    ")); 
     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
    ",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 }
  • 相关阅读:
    如何进行简单画图
    缓冲技术
    信号量机制
    进程通信
    中断技术
    操作系统原理-图书主题
    供多处理器系统中的高速缓存同步中使用的转发状态
    js几种escape()解码与unescape()编码
    MySQL 元数据
    MySQL 复制表
  • 原文地址:https://www.cnblogs.com/zwt1234/p/4452767.html
Copyright © 2020-2023  润新知