设为首页 收藏本站
查看: 1143|回复: 0

[经验分享] 梦织未来Windows驱动编程 第05课 小结(读取另一驱动,遍历所有驱动)

[复制链接]

尚未签到

发表于 2017-6-29 20:34:34 | 显示全部楼层 |阅读模式
读取另一驱动
  驱动通过"\\Driver\\XueTr"获取到了XueTr工具的驱动,并Hook了XueTr驱动的分发函数。
  具体的驱动代码如下:


DSC0000.gif DSC0001.gif


1 //FilterDriver.c
2 //2016.07.15
3
4 #include "ntddk.h"
5
6 NTKERNELAPI
7 NTSTATUS
8 ObReferenceObjectByName(
9     IN PUNICODE_STRING ObjectName,
10     IN ULONG Attributes,
11     IN PACCESS_STATE PassedAccessState OPTIONAL,
12     IN ACCESS_MASK DesiredAccess OPTIONAL,
13     IN POBJECT_TYPE ObjectType,
14     IN KPROCESSOR_MODE AccessMode,
15     IN OUT PVOID ParseContext OPTIONAL,
16     OUT PVOID *Object
17     );
18
19 extern POBJECT_TYPE *IoDriverObjectType;
20
21 //global
22 PDRIVER_OBJECT g_FilterDriverObject;
23 PDRIVER_DISPATCH gfn_OrigReadCompleteRoutine;
24
25 //我们的驱动分发函数
26 NTSTATUS FilterReadCompleteRoutine(
27     __in struct _DEVICE_OBJECT *DeviceObject,
28      __inout struct _IRP *Irp)
29 {
30     KdPrint(("IRP_MJ_DEVICE_CONTROL coming."));
31
32     //处理完毕后,要调用原分发例程
33     return gfn_OrigReadCompleteRoutine(DeviceObject, Irp);
34 }
35
36 //驱动卸载函数
37 VOID UnFilterDriverRoutine(__in struct _DRIVER_OBJECT *DriverObject)
38 {
39     //此内存可读时,恢复
40     if (MmIsAddressValid(gfn_OrigReadCompleteRoutine))
41     {
42         KdPrint(("UnFilterDriverRoutine Success."));
43
44         //卸载时恢复原分发例程
45         g_FilterDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = gfn_OrigReadCompleteRoutine;
46     }
47 }
48
49 //过滤函数
50 NTSTATUS FilterDriverQuery()
51 {
52     NTSTATUS Status;
53     UNICODE_STRING usObjectName;
54     
55     RtlInitUnicodeString (&usObjectName, L"\\Driver\\XueTr");
56
57     //根据驱动名称获得驱动对象
58     Status = ObReferenceObjectByName (
59         &usObjectName,
60         OBJ_CASE_INSENSITIVE,    //大小写不敏感
61         NULL,
62         0,    //访问权限,0是所有权限
63         *IoDriverObjectType,
64         KernelMode,    //处理器模式
65         NULL,
66         (PVOID*)&g_FilterDriverObject
67         );
68     if (!NT_SUCCESS(Status))
69     {
70         KdPrint(("Filter Failed!"));
71         return Status;
72     }
73
74     KdPrint(("0x%X", g_FilterDriverObject));    //打印驱动对象地址
75
76     //保存原分发例程,并修改为我们的函数
77     gfn_OrigReadCompleteRoutine = g_FilterDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
78     g_FilterDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)FilterReadCompleteRoutine;
79
80     ObDereferenceObject(g_FilterDriverObject);    //清除引用计数
81
82     return STATUS_SUCCESS;
83 }
84
85
86 //驱动程序入口函数
87 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
88 {
89     pDriverObject->DriverUnload = UnFilterDriverRoutine;
90     FilterDriverQuery ();
91
92     return STATUS_SUCCESS;
93 }
FilterDriver.c  其中,ObReferenceObjectByName函数能够根据驱动名获取到相应的驱动对象,函数原型如下:



1 NTKERNELAPI
2 NTSTATUS
3 ObReferenceObjectByName(
4     IN PUNICODE_STRING ObjectName,
5     IN ULONG Attributes,
6     IN PACCESS_STATE PassedAccessState OPTIONAL,
7     IN ACCESS_MASK DesiredAccess OPTIONAL,
8     IN POBJECT_TYPE ObjectType,
9     IN KPROCESSOR_MODE AccessMode,
10     IN OUT PVOID ParseContext OPTIONAL,
11     OUT PVOID *Object
12     );
  由于ObReferenceObjectByName函数没有文档化,但是被导出了。所以我们需要在代码中对ObReferenceObjectByName函数进行声明。
  另外调用ObReferenceObjectByName函数后,要调用ObDereferenceObject来清除对象的引用计数,否则会造成内存泄漏。
  根据XueTr获取到XueTr的驱动对象地址是0x84F79858,大小是0x00068000
DSC0002.png

  根据WinObj工具获得XueTr驱动的路径为"\\Driver\\XueTr"
DSC0003.png

  用InstDrv安装并启动驱动FilterDriver.sys后,DbgView输出0x84F79858,此地址与上面用XueTr查看的地址相同。说明获取到的XueTr驱动对象的地址是正确的。
  在WinDbg输入以下命令查看XueTr驱动的详细信息:



dt _DRIVER_OBJECT -b 84F79858
  WinDbg输出如下:



1 lkd> dt_DRIVER_OBJECT -b 84F79858
2 nt!_DRIVER_OBJECT
3    +0x000 Type             : 4
4    +0x002 Size             : 168
5    +0x004 DeviceObject     : 0x8617b100
6    +0x008 Flags            : 0x12
7    +0x00c DriverStart      : 0xed5ce000
8    +0x010 DriverSize       : 0x68000
9    +0x014 DriverSection    : 0x862e2220
10    +0x018 DriverExtension  : 0x84f79900
11    +0x01c DriverName       : _UNICODE_STRING "\Driver\XueTr"
12       +0x000 Length           : 0x1a
13       +0x002 MaximumLength    : 0x1a
14       +0x004 Buffer           : 0xe1605358  "\Driver\XueTr"
15    +0x024 HardwareDatabase : 0x80691b90
16    +0x028 FastIoDispatch   : (null)
17    +0x02c DriverInit       : 0xed62b03e
18    +0x030 DriverStartIo    : (null)
19    +0x034 DriverUnload     : 0xed619668
20    +0x038 MajorFunction    :
21     [00] 0xed619792
22     [01] 0x804fe101
23     [02] 0xed619792
24     [03] 0x804fe101
25     [04] 0x804fe101
26     [05] 0x804fe101
27     [06] 0x804fe101
28     [07] 0x804fe101
29     [08] 0x804fe101
30     [09] 0x804fe101
31     [10] 0x804fe101
32     [11] 0x804fe101
33     [12] 0x804fe101
34     [13] 0x804fe101
35     [14] 0xf7c37000
36     [15] 0x804fe101
37     [16] 0x804fe101
38     [17] 0x804fe101
39     [18] 0x804fe101
40     [19] 0x804fe101
41     [20] 0x804fe101
42     [21] 0x804fe101
43     [22] 0x804fe101
44     [23] 0x804fe101
45     [24] 0x804fe101
46     [25] 0x804fe101
47     [26] 0x804fe101
48     [27] 0x804fe101
  上面代码中修改的分发函数是IRP_MJ_DEVICE_CONTROL,也就是14号分发例程(0至27)
  XueTr驱动的14号分发函数地址为0xf7c37000
  由XueTr知道我们的驱动FilterDriver.sys基地址为0xF7C36000,大小为0x00006000。
  所以XueTr驱动的14号分发函数地址(0xf7c37000)在我们的驱动内(0xF7C36000~0xF7C36000+0x00006000)
DSC0004.png

  然后当我们在XueTr工具内刷新时,DbgView内输出



IRP_MJ_DEVICE_CONTROL coming.


遍历所有驱动
  遍历所有驱动需要用到一个结构_LDR_DATA_TABLE_ENTRY,具体的驱动代码如下:





1 //EnumDriver.c
2 //2016.07.17
3
4 #include <ntddk.h>
5
6 typedef struct _LDR_DATA_TABLE_ENTRY{
7     LIST_ENTRY InLoadOrderLinks;            //链表 保存了所有已经读取到内存中的驱动地址
8     LIST_ENTRY InMemoryOrderLinks;            //链表 保存了已经安装,但没启动(没执行DriverEntry)的驱动地址
9     LIST_ENTRY InInitializationOrderLinks;    //链表 保存了已经安装,同时也启动了(执行了DriverEntry)的驱动地址
10     PVOID DllBase;
11     PVOID EntryPoint;
12     ULONG SizeOfImage;
13     UNICODE_STRING FullDllName;
14     UNICODE_STRING BaseDllName;
15     ULONG Flags;
16     USHORT LoadCount;
17     USHORT TlsIndex;
18     LIST_ENTRY HashLinks;
19     PVOID SectionPointer;
20     ULONG CheckSum;
21     ULONG TimeDateStamp;
22     PVOID LoadedImports;
23     PVOID EntryPointActivationContext;
24     PVOID PatchInformation;
25 }LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
26
27 VOID MyDriverUnload(PDRIVER_OBJECT pDriverObject)
28 {
29     //
30     KdPrint(("Unload EnumDriver.sys Success."));
31 }
32
33 VOID EnumDriver(PDRIVER_OBJECT pDriverObject)
34 {
35     PLDR_DATA_TABLE_ENTRY pLdrDataTableEntry, pTempLdrDataTableEntry;
36     PLIST_ENTRY pList;
37     int i = 0;
38     
39     pLdrDataTableEntry = (PLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
40     if (!MmIsAddressValid(pLdrDataTableEntry))
41     {
42         return;
43     }
44
45     pList = &pLdrDataTableEntry->InLoadOrderLinks;
46
47     while (pList != pLdrDataTableEntry->InLoadOrderLinks.Blink)
48     {
49         //ToDo
50         pTempLdrDataTableEntry = (PLDR_DATA_TABLE_ENTRY)pList;
51         i++;
52
53         if(MmIsAddressValid(pTempLdrDataTableEntry))
54         {
55             if (MmIsAddressValid(&pTempLdrDataTableEntry->BaseDllName) && MmIsAddressValid(&pTempLdrDataTableEntry->BaseDllName))
56                 KdPrint(("%d:%wZ\t%wZ", i, &pTempLdrDataTableEntry->BaseDllName, &pTempLdrDataTableEntry->FullDllName));
57         }
58
59         pList = pList->Flink;
60     }
61 }
62
63 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
64 {
65     pDriverObject->DriverUnload = MyDriverUnload;
66     EnumDriver(pDriverObject);
67
68     return STATUS_SUCCESS;
69 }
EnumDriver.c  用Windbg在XP虚拟机下查看该结构



lkd> dt_LDR_DATA_TABLE_ENTRY
nt!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY
+0x008 InMemoryOrderLinks : _LIST_ENTRY
+0x010 InInitializationOrderLinks : _LIST_ENTRY
+0x018 DllBase          : Ptr32 Void
+0x01c EntryPoint       : Ptr32 Void
+0x020 SizeOfImage      : Uint4B
+0x024 FullDllName      : _UNICODE_STRING
+0x02c BaseDllName      : _UNICODE_STRING
+0x034 Flags            : Uint4B
+0x038 LoadCount        : Uint2B
+0x03a TlsIndex         : Uint2B
+0x03c HashLinks        : _LIST_ENTRY
+0x03c SectionPointer   : Ptr32 Void
+0x040 CheckSum         : Uint4B
+0x044 TimeDateStamp    : Uint4B
+0x044 LoadedImports    : Ptr32 Void
+0x048 EntryPointActivationContext : Ptr32 Void
+0x04c PatchInformation : Ptr32 Void
  因为结构_LDR_DATA_TABLE_ENTRY是未导出的,所以要在代码开头定义一下:



1 typedef struct _LDR_DATA_TABLE_ENTRY{
2     LIST_ENTRY InLoadOrderLinks;              //链表 保存了所有已经读取到内存中的驱动地址
3     LIST_ENTRY InMemoryOrderLinks;            //链表 保存了已经安装,但没启动(没执行DriverEntry)的驱动地址
4     LIST_ENTRY InInitializationOrderLinks;    //链表 保存了已经安装,同时也启动了(执行了DriverEntry)的驱动地址
5     PVOID DllBase;
6     PVOID EntryPoint;
7     ULONG SizeOfImage;
8     UNICODE_STRING FullDllName;
9     UNICODE_STRING BaseDllName;
10     ULONG Flags;
11     USHORT LoadCount;
12     USHORT TlsIndex;
13     LIST_ENTRY HashLinks;
14     PVOID SectionPointer;
15     ULONG CheckSum;
16     ULONG TimeDateStamp;
17     PVOID LoadedImports;
18     PVOID EntryPointActivationContext;
19     PVOID PatchInformation;
20 }LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
InLoadOrderLinks是一个双向的循环链表,保存了所有驱动的地址。我们只要遍历它,就能够找到所有的驱动了。
FullDllName是驱动的完整路径(路径+名称),BaseDllName是驱动的名称(不包含路径)

驱动加载后的输出如下:
DSC0005.png

  其中的第二个 2:(null)(null)是XueTr的驱动,应该是做了特殊处理

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-389425-1-1.html 上篇帖子: 【转载】Windows下VSCode编译调试c/c++ 下篇帖子: linux和windows双系统时间错误解决方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表