Windows驱动开发学习记录-驱动中获取当前驱动文件路径

1.背景

        学习驱动期间打算做一个驱动,功能中需要在驱动启动成功后删除注册表中的服务项,关机时再自动添加到注册表启动项以便下次能自动加载驱动。一般情况注册表中项目如下,其中ImagePath为驱动的路径。

 

         这个路径是在注册服务时写进入注册表里的, 在DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)中,可以根据第二个参数pRgisterPath对应项读取注册表中的ImagePath便可获得。但我想用类似于用户层应用的GetModuleFileName直接获取应用路径,查了一些资料后发现是可行的,虽然没有直接函数,但还是可以获取到的。此次调试和开发目标环境为均为Win10 x64,其它系统环境的数据结构可能不一样,需要调试获取。

2. _DRIVER_OBJECT、_LDR_DATA_TABLE_ENTRY结构体

0: kd> dt nt!_DRIVER_OBJECT
   +0x000 Type             : Int2B
   +0x002 Size             : Int2B
   +0x008 DeviceObject     : Ptr64 _DEVICE_OBJECT
   +0x010 Flags            : Uint4B
   +0x018 DriverStart      : Ptr64 Void
   +0x020 DriverSize       : Uint4B
   +0x028 DriverSection    : Ptr64 Void
   +0x030 DriverExtension  : Ptr64 _DRIVER_EXTENSION
   +0x038 DriverName       : _UNICODE_STRING
   +0x048 HardwareDatabase : Ptr64 _UNICODE_STRING
   +0x050 FastIoDispatch   : Ptr64 _FAST_IO_DISPATCH
   +0x058 DriverInit       : Ptr64     long 
   +0x060 DriverStartIo    : Ptr64     void 
   +0x068 DriverUnload     : Ptr64     void 
   +0x070 MajorFunction    : [28] Ptr64     long 

         其中要用到的就是DriverSection字段,该字段对应的是LDR_DATA_TABLE_ENTRY结构体,该结构体未文档化,Win10 x64环境下是这样的:

0: kd> dt _LDR_DATA_TABLE_ENTRY
nt!_LDR_DATA_TABLE_ENTRY
   +0x000 InLoadOrderLinks : _LIST_ENTRY
   +0x010 InMemoryOrderLinks : _LIST_ENTRY
   +0x020 InInitializationOrderLinks : _LIST_ENTRY
   +0x030 DllBase          : Ptr64 Void
   +0x038 EntryPoint       : Ptr64 Void
   +0x040 SizeOfImage      : Uint4B
   +0x048 FullDllName      : _UNICODE_STRING
   +0x058 BaseDllName      : _UNICODE_STRING
   +0x068 FlagGroup        : [4] UChar
   +0x068 Flags            : Uint4B
   +0x068 PackagedBinary   : Pos 0, 1 Bit
   +0x068 MarkedForRemoval : Pos 1, 1 Bit
   +0x068 ImageDll         : Pos 2, 1 Bit
   +0x068 LoadNotificationsSent : Pos 3, 1 Bit
   +0x068 TelemetryEntryProcessed : Pos 4, 1 Bit
   +0x068 ProcessStaticImport : Pos 5, 1 Bit
   +0x068 InLegacyLists    : Pos 6, 1 Bit
   +0x068 InIndexes        : Pos 7, 1 Bit
   +0x068 ShimDll          : Pos 8, 1 Bit
   +0x068 InExceptionTable : Pos 9, 1 Bit
   +0x068 ReservedFlags1   : Pos 10, 2 Bits
   +0x068 LoadInProgress   : Pos 12, 1 Bit
   +0x068 LoadConfigProcessed : Pos 13, 1 Bit
   +0x068 EntryProcessed   : Pos 14, 1 Bit
   +0x068 ProtectDelayLoad : Pos 15, 1 Bit
   +0x068 ReservedFlags3   : Pos 16, 2 Bits
   +0x068 DontCallForThreads : Pos 18, 1 Bit
   +0x068 ProcessAttachCalled : Pos 19, 1 Bit
   +0x068 ProcessAttachFailed : Pos 20, 1 Bit
   +0x068 CorDeferredValidate : Pos 21, 1 Bit
   +0x068 CorImage         : Pos 22, 1 Bit
   +0x068 DontRelocate     : Pos 23, 1 Bit
   +0x068 CorILOnly        : Pos 24, 1 Bit
   +0x068 ChpeImage        : Pos 25, 1 Bit
   +0x068 ReservedFlags5   : Pos 26, 2 Bits
   +0x068 Redirected       : Pos 28, 1 Bit
   +0x068 ReservedFlags6   : Pos 29, 2 Bits
   +0x068 CompatDatabaseProcessed : Pos 31, 1 Bit
   +0x06c ObsoleteLoadCount : Uint2B
   +0x06e TlsIndex         : Uint2B
   +0x070 HashLinks        : _LIST_ENTRY
   +0x080 TimeDateStamp    : Uint4B
   +0x088 EntryPointActivationContext : Ptr64 _ACTIVATION_CONTEXT
   +0x090 Lock             : Ptr64 Void
   +0x098 DdagNode         : Ptr64 _LDR_DDAG_NODE
   +0x0a0 NodeModuleLink   : _LIST_ENTRY
   +0x0b0 LoadContext      : Ptr64 _LDRP_LOAD_CONTEXT
   +0x0b8 ParentDllBase    : Ptr64 Void
   +0x0c0 SwitchBackContext : Ptr64 Void
   +0x0c8 BaseAddressIndexNode : _RTL_BALANCED_NODE
   +0x0e0 MappingInfoIndexNode : _RTL_BALANCED_NODE
   +0x0f8 OriginalBase     : Uint8B
   +0x100 LoadTime         : _LARGE_INTEGER
   +0x108 BaseNameHashValue : Uint4B
   +0x10c LoadReason       : _LDR_DLL_LOAD_REASON
   +0x110 ImplicitPathOptions : Uint4B
   +0x114 ReferenceCount   : Uint4B
   +0x118 DependentLoadFlags : Uint4B
   +0x11c SigningLevel     : UChar

        其中FullDllName字段就是指定驱动对象对应bin文件的全路径。在本人机器上如下

4: kd> dt _DRIVER_OBJECT -b 0xffffa603b4a78a70
DriverEntryHook!_DRIVER_OBJECT
   +0x000 Type             : 0n4
   +0x002 Size             : 0n336
   +0x008 DeviceObject     : (null) 
   +0x010 Flags            : 2
   +0x018 DriverStart      : 0xfffff802`59c20000 
   +0x020 DriverSize       : 0x8000
   +0x028 DriverSection    : 0xffffa603`b1181120 
   +0x030 DriverExtension  : 0xffffa603`b4a78bc0 
   +0x038 DriverName       : _UNICODE_STRING "\Driver\DriverEntryHook"
      +0x000 Length           : 0x2e
      +0x002 MaximumLength    : 0x2e
      +0x008 Buffer           : 0xffffa603`af1c66d0  "\Driver\DriverEntryHook"
   +0x048 HardwareDatabase : 0xfffff802`5df2d988 
   +0x050 FastIoDispatch   : (null) 
   +0x058 DriverInit       : 0xfffff802`59c26000 
   +0x060 DriverStartIo    : (null) 
   +0x068 DriverUnload     : (null) 
   +0x070 MajorFunction    : 
   ......


4: kd> dt _LDR_DATA_TABLE_ENTRY 0xffffa603`b1181120
nt!_LDR_DATA_TABLE_ENTRY
   +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0xfffff802`5de2a1d0 - 0xffffa603`b6dbc270 ]
   +0x010 InMemoryOrderLinks : _LIST_ENTRY [ 0xfffff802`59c25000 - 0x00000000`000000b4 ]
   +0x020 InInitializationOrderLinks : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ]
   +0x030 DllBase          : 0xfffff802`59c20000 Void
   +0x038 EntryPoint       : 0xfffff802`59c26000 Void
   +0x040 SizeOfImage      : 0x8000
   +0x048 FullDllName      : _UNICODE_STRING "\??\C:\Users\Administrator\Desktop\DriverEntryHook.sys"
   +0x058 BaseDllName      : _UNICODE_STRING "DriverEntryHook.sys"
   +0x068 FlagGroup        : [4]  ""
   +0x068 Flags            : 0x49104000
   +0x068 PackagedBinary   : 0y0
   +0x068 MarkedForRemoval : 0y0
   +0x068 ImageDll         : 0y0
   +0x068 LoadNotificationsSent : 0y0
   +0x068 TelemetryEntryProcessed : 0y0 

        可以看到FullDllName就显示的是全路径。 

3. 代码实现

        通过已上可以看出代码实现就简单了。我们先定义一个结构体,只需要几个简单的字段,无需要定义全部

typedef struct _LDR_DATA_TABLE_ENTRY {
	LIST_ENTRY InLoadOrderLinks;
	LIST_ENTRY InMemoryOrderLinks;
	LIST_ENTRY InInitializationOrderLinks;
	PVOID DllBase;
	PVOID EntryPoint;
	ULONG SizeOfImage;
	UNICODE_STRING FullDllName;
	UNICODE_STRING BaseDllName;
	union {
		ULONG FlagGroup;
		ULONG Flags;
	};
}LDR_DATA_TABLE_ENTRY64, *PLDR_DATA_TABLE_ENTRY64;



VOID Function(PDRIVER_OBJECT pDriverObject)
{
    PLDR_DATA_TABLE_ENTRY64 pldt = (PLDR_DATA_TABLE_ENTRY64)pDriverObject->DriverSection;
    if (pldt)
    {
	    KDPRINT("ImagePath is :%wZ\n", pldt->FullDllName);
        //do smomething else....
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值