遍历设备栈

查找设备名
内核对象地址-0x18 为OBJECT_HEADER的地址

 kd> dt _OBJECT_HEADER
   +0x000 PointerCount     : Int4B
   +0x004 HandleCount      : Int4B
   +0x004 NextToFree       : Ptr32 Void
   +0x008 Type             : Ptr32 _OBJECT_TYPE
   +0x00c NameInfoOffset   : UChar  _OBJECT_HEADER-NameInfoOffset的值是_OBJECT_HEADER_NAME_INFO结构里面保存有对面的名字.
   +0x00d HandleInfoOffset : UChar
   +0x00e QuotaInfoOffset  : UChar
   +0x00f Flags            : UChar
   +0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
   +0x010 QuotaBlockCharged : Ptr32 Void
   +0x014 SecurityDescriptor : Ptr32 Void
   +0x018 Body             : _QUAD

typedef struct _OBJECT_HEADER_NAME_INFO
{
    POBJECT_DIRECTORY Directory;
    UNICODE_STRING Name;	//内核对象的名字在这里
    ULONG Reserved;
#if DBG
    ULONG Reserved2 ;
    LONG DbgDereferenceCount ;
#endif
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;

根据设备对象指针,获取设备名

VOID GetDeviceName(PDEVICE_OBJECT pDevObj)
{
	if (!pDevObj)
	{
		DbgPrint("设备对象指针为空,无法获取设备名\n");
		return;
	}
	
	//获取设备对象头指针
	POBJECT_HEADER pDeviceObjectHeader = (POBJECT_HEADER)((ULONG)pDevObj - 0x18);

	//获取OBJECT_HEADER_NAME_INFO结构指针 
	POBJECT_HEADER_NAME_INFO pObjectNameInfo = (POBJECT_HEADER_NAME_INFO)((ULONG)pDeviceObjectHeader - pDeviceObjectHeader->NameInfoOffset);

	//打印对象名
	DbgPrint("device name is %wZ",&pObjectNameInfo->Name);

}

根据设备对象,遍历设备栈 以传进来的设备对象为栈底,往上遍历每一个设备对象. 因为附加的时候,都是下一层的AttachedDevice记录上一层设备对象指针.

VOID
GetAttachedDeviceInfo( PDEVICE_OBJECT DevObj )
{
  PDEVICE_OBJECT DeviceObject;

  if ( DevObj == NULL )
  {
    DbgPrint( "DevObj is NULL!\n" );
    return;
  }

  DeviceObject = DevObj->AttachedDevice;

  while ( DeviceObject )
  {
    DbgPrint( "Attached Driver Name:%wZ,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
              &DeviceObject->DriverObject->DriverName,
              DeviceObject->DriverObject,
              DeviceObject );

    DeviceObject = DeviceObject->AttachedDevice;
  }
}

根据驱动名,枚举驱动所有的设备栈


PDRIVER_OBJECT
EnumDeviceStack( PWSTR pwszDeviceName )
{
  UNICODE_STRING DriverName;
  PDRIVER_OBJECT DriverObject = NULL;
  PDEVICE_OBJECT DeviceObject = NULL;


  RtlInitUnicodeString( &DriverName, pwszDeviceName );


  ObReferenceObjectByName( &DriverName,
                           OBJ_CASE_INSENSITIVE,
                           NULL,
                           0,
                           ( POBJECT_TYPE ) IoDriverObjectType,
                           KernelMode,
                           NULL,
                           (PVOID*)&DriverObject );

  if ( DriverObject == NULL )
  {
    return NULL;
  }

  DeviceObject = DriverObject->DeviceObject;

  while ( DeviceObject )
  {
    GetDeviceObjectInfo( DeviceObject );

    // 判断当前设备上是否有过滤驱动(Filter Driver)
    if ( DeviceObject->AttachedDevice )
    {
      GetAttachedDeviceInfo( DeviceObject );
    }

    // 进一步判断当前设备上 VPB 中的设备  特定的设备类型 VPB才会有值.
    if ( DeviceObject->Vpb && DeviceObject->Vpb->DeviceObject )
    {
      GetDeviceObjectInfo( DeviceObject->Vpb->DeviceObject );

      if ( DeviceObject->Vpb->DeviceObject->AttachedDevice )
      {
        GetAttachedDeviceInfo( DeviceObject->Vpb->DeviceObject );
      }
    }

    // 得到建立在此驱动上的下一个设备 DEVICE_OBJECT 
    DeviceObject = DeviceObject->NextDevice;
  }

  return DriverObject;
}

通过ObQueryNameString函数来获得对象名字.

VOID GetDeviceInfo(PDEVICE_OBJECT pDeviceObject)
{
	PDEVICE_OBJECT CurrentDevice = pDeviceObject;
	POBJECT_NAME_INFORMATION pNameInfo = (POBJECT_NAME_INFORMATION)ExAllocatePoolWithTag(PagedPool, 1024, 'dale');
	if (!pNameInfo)
	{	
		KdPrint(("对象名字信息内存分配失败\n"));
		return;
	}
	ULONG Length = 0;
	while (CurrentDevice!=NULL)
	{
		
		RtlZeroMemory(pNameInfo,1024);
		NTSTATUS status=ObQueryNameString(CurrentDevice,pNameInfo,1024,&Length);
		if (!NT_SUCCESS(status))
		{
			KdPrint(("ObQueryNameString failed,error code=%x", status));
			continue;
		}
		KdPrint(("驱动对象%p:%wZ\t设备对象%p:%wZ\n",
			CurrentDevice->DriverObject,
			&CurrentDevice->DriverObject->DriverName,
			CurrentDevice,
			&pNameInfo->Name
			));
		CurrentDevice = CurrentDevice->AttachedDevice;
	}
	ExFreePoolWithTag(pNameInfo,'dale');
}

VOID EnumDriver()
{
	UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"\\Driver\\ACPI");
	NTSTATUS status = STATUS_SUCCESS;
	PDRIVER_OBJECT DriverObject;
	status = ObReferenceObjectByName(&DriverName,
		OBJ_CASE_INSENSITIVE,//不区分大小写
		NULL,
		FILE_ALL_ACCESS,
		*IoFileObjectType,
		KernelMode,
		NULL,
		&DriverObject
		);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("ObReferenceObjectByName failed,error code=%x",status));
		return;
	}

	PDEVICE_OBJECT CurrentDevice = DriverObject->DeviceObject;
	while (CurrentDevice!=NULL)
	{
		GetDeviceInfo(CurrentDevice);
		CurrentDevice = CurrentDevice->NextDevice;
	}


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值