遍历系统中加载的驱动程序以及通过设备对象指针获取设备对象名称
遍历系统中加载的驱动可以在R3层完成,通过几个未导出的函数:ZwOpenDirectoryObject、ZwQueryDirectoryObject,下面是具体的代码。
//在这定义些基本的数据结构,这些本身是在R0层用的比较多的
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef ULONG NTSTATUS;
// 对象属性定义
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
UNICODE_STRING *ObjectName;
ULONG Attributes;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
// 基本信息定义
typedef struct _DIRECTORY_BASIC_INFORMATION {
UNICODE_STRING ObjectName;
UNICODE_STRING ObjectTypeName;
} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;
// 返回值或状态类型定义
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define DIRECTORY_QUERY (0x0001)
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
#define STATUS_MORE_ENTRIES ((NTSTATUS)0x00000105L)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
// 初始化对象属性宏定义
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
// 字符串初始化
//用来存储设备驱动对象名称的链表
extern vector<CString> g_DriverNameList;
vector<DRIVER_INFO> g_DriverNameList;
typedef VOID(CALLBACK* RTLINITUNICODESTRING)(PUNICODE_STRING, PCWSTR);
RTLINITUNICODESTRING RtlInitUnicodeString;
// 打开对象
typedef NTSTATUS(WINAPI *ZWOPENDIRECTORYOBJECT)(
OUT PHANDLE DirectoryHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
ZWOPENDIRECTORYOBJECT ZwOpenDirectoryObject;
// 查询对象
typedef
NTSTATUS
(WINAPI *ZWQUERYDIRECTORYOBJECT)(
IN HANDLE DirectoryHandle,
OUT PVOID Buffer,
IN ULONG BufferLength,
IN BOOLEAN ReturnSingleEntry,
IN BOOLEAN RestartScan,
IN OUT PULONG Context,
OUT PULONG ReturnLength OPTIONAL
);
ZWQUERYDIRECTORYOBJECT ZwQueryDirectoryObject;
// 关闭已经打开的对象
typedef NTSTATUS (WINAPI *ZWCLOSE)(IN HANDLE Handle);
ZWCLOSE ZwClose;
BOOL EnumDriver()
{
HMODULE hNtdll = NULL;
UNICODE_STRING strDirName;
OBJECT_ATTRIBUTES oba;
NTSTATUS ntStatus;
HANDLE hDirectory;
hNtdll = LoadLibrary(_T("ntdll.dll"));
if (NULL == hNtdll)
{
return FALSE;
}
RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress(hNtdll, "RtlInitUnicodeString");
ZwOpenDirectoryObject = (ZWOPENDIRECTORYOBJECT)GetProcAddress(hNtdll, "ZwOpenDirectoryObject");
ZwQueryDirectoryObject = (ZWQUERYDIRECTORYOBJECT)GetProcAddress(hNtdll, "ZwQueryDirectoryObject");
ZwClose = (ZWCLOSE)GetProcAddress(hNtdll, "ZwClose");
RtlInitUnicodeString(&strDirName, _T("\\Driver"));
InitializeObjectAttributes(&oba, &strDirName, OBJ_CASE_INSENSITIVE, NULL, NULL);
ntStatus = ZwOpenDirectoryObject(&hDirectory, DIRECTORY_QUERY, &oba);
if (ntStatus != STATUS_SUCCESS)
{
return FALSE;
}
PDIRECTORY_BASIC_INFORMATION pBuffer = NULL;
PDIRECTORY_BASIC_INFORMATION pBuffer2 = NULL;
ULONG ulLength = 0x800; // 2048
ULONG ulContext = 0;
ULONG ulRet = 0;
// 查询目录对象
do
{
if (pBuffer != NULL)
{
free(pBuffer);
}
ulLength = ulLength * 2;
pBuffer = (PDIRECTORY_BASIC_INFORMATION)malloc(ulLength);
if (NULL == pBuffer)
{
if (pBuffer != NULL)
{
free(pBuffer);
}
if (hDirectory != NULL)
{
ZwClose(hDirectory);
}
return FALSE;
}
ntStatus = ZwQueryDirectoryObject(hDirectory, pBuffer, ulLength, FALSE, TRUE, &ulContext, &ulRet);
} while (ntStatus == STATUS_MORE_ENTRIES || ntStatus == STATUS_BUFFER_TOO_SMALL);
if (STATUS_SUCCESS == ntStatus)
{
pBuffer2 = pBuffer;
while ((pBuffer2->ObjectName.Length != 0) && (pBuffer2->ObjectTypeName.Length != 0))
{
CString strDriverName;
strDriverName = pBuffer2->ObjectName.Buffer;
g_DriverNameList.push_back(strDriverName);
pBuffer2++;
}
}
if (pBuffer != NULL)
{
free(pBuffer);
}
if (hDirectory != NULL)
{
ZwClose(hDirectory);
}
return TRUE;
}
通过设备对象的地址来获取设备对象的名称一般是在R0层完成,下面是具体的代码
//定义相关的结构体和宏
typedef struct _OBJECT_CREATE_INFORMATION
{
ULONG Attributes;
HANDLE RootDirectory;
PVOID ParseContext;
KPROCESSOR_MODE ProbeMode;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION;
typedef struct _OBJECT_HEADER
{
LONG PointerCount;
union
{
LONG HandleCount;
PSINGLE_LIST_ENTRY SEntry;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PSECURITY_DESCRIPTOR SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, * POBJECT_HEADER;
#define NUMBER_HASH_BUCKETS 37
typedef struct _OBJECT_DIRECTORY
{
struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
BOOLEAN LookupFound;
USHORT SymbolicLinkUsageCount;
struct _DEVICE_MAP* DeviceMap;
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
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;
#define OBJECT_TO_OBJECT_HEADER( o ) \
CONTAINING_RECORD( (o), OBJECT_HEADER, Body )
#define OBJECT_HEADER_TO_NAME_INFO( oh ) ((POBJECT_HEADER_NAME_INFO) \
((oh)->NameInfoOffset == 0 ? NULL : ((PCHAR)(oh) - (oh)->NameInfoOffset)))
void GetDeviceName(PDEVICE_OBJECT pDeviceObj)
{
POBJECT_HEADER ObjectHeader;
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
if ( pDeviceObj == NULL )
{
DbgPrint( "pDeviceObj is NULL!\n" );
return;
}
// 得到对象头
ObjectHeader = OBJECT_TO_OBJECT_HEADER( pDeviceObj );
if ( ObjectHeader )
{
// 查询设备名称并打印
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
{
DbgPrint( "Driver Name:%wZ - Device Name:%wZ - Driver Address:0x%x - Device Address:0x%x\n",
&pDeviceObj->DriverObject->DriverName,
&ObjectNameInfo->Name,
pDeviceObj->DriverObject,
pDeviceObj );
}
// 对于没有名称的设备,则打印 NULL
else if ( pDeviceObj->DriverObject )
{
DbgPrint( "Driver Name:%wZ - Device Name:%S - Driver Address:0x%x - Device Address:0x%x\n",
&pDeviceObj->DriverObject->DriverName,
L"NULL",
pDeviceObj->DriverObject,
pDeviceObj );
}
}
}