A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #8826  by Tigzy
 Thu Sep 29, 2011 8:13 am
Here's my code, the error remains the same...
Code: Select all
//Get devices
RtlInitUnicodeString(&name, driverName);
TypeObjectType = ObGetObjectType(*IoDriverObjectType);
status = ObReferenceObjectByName(&name, OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE, NULL, 0, TypeObjectType, KernelMode, NULL, &driverobj);
Another question, if this would work, as the ObGetObjectType isn't referenced in the winXP kernel, how could I do to make this work under every OS (without rebuilding another driver)?
 #8831  by r2nwcnydc
 Thu Sep 29, 2011 11:21 am
The way I usually get driver object's is:
Code: Select all
PDRIVER_OBJECT rc;
HANDLE handle;
OBJECT_ATTRIBUTES attributes;

RtlInitUnicodeString(&name, driverName);
InitializeObjectAttributes( &attributes, &name, 0, 0, NUL );
if (!NT_SUCCESS(ObOpenObjectByName( &attributes, IoDriverObjectType, KernelMode, NULL, 0x80000000, NULL, &handle )))
{
   return NULL;
}

ObReferenceObjectByHandle( handle, FILE_ALL_ACCESS, NULL, KernelMode, &rc, NULL );
ZwClose( handle );

return rc;
 #8935  by Tigzy
 Mon Oct 03, 2011 12:56 pm
Works well, thanks!

... But I got yet another problem

the following works on XP, but not on seven.
The ObjectNameInfo->Name.Length isn't good (thousands of bytes instead of 20-30 bytes).
Is there another way to enum devices of a driver on Win7?
Code: Select all
if (driverobj != NULL)
{			
	for (device = driverobj->DeviceObject; device != NULL; device = device->NextDevice)
	{
		//Get device Name
		ObjectHeader = OBJECT_TO_OBJECT_HEADER(device);
		ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
		if (ObjectNameInfo)
		{				
			wcscpy(deviceName, L"\\Device\\");
			buff = ExAllocatePoolWithTag(PagedPool, ObjectNameInfo->Name.Length + sizeof(WCHAR), 'mlst');
			if (ObjectNameInfo->Name.Length)
			{
				RtlStringCbCopyW(buff, ObjectNameInfo->Name.Length + sizeof(WCHAR), ObjectNameInfo->Name.Buffer);					
				wcscat(deviceName, buff);
			}
			ExFreePoolWithTag(buff, 'mlst');					
			DbgPrint("--> %ws [%d]\n", deviceName , ObjectNameInfo->Name.Length);			
		}		
	}
	ObDereferenceObject(driverobj);
}		
 #8936  by EP_X0FF
 Mon Oct 03, 2011 1:12 pm
Not a surprise with all this hardcode.

http://www.codemachine.com/article_objectheader.html

some pseudo code
Code: Select all
#define OB_INFOMASK_PROCESS_INFO  0x10
#define OB_INFOMASK_QUOTA         0x08
#define OB_INFOMASK_HANDLE        0x04 
#define OB_INFOMASK_NAME          0x02 
#define OB_INFOMASK_CREATOR_INFO  0x01

ULONG i = 0;
ULONG offset = 0;
ULONG i = 0;
ULONG offset = 0;
do {
	offset = 0;

	if ( i & OB_INFOMASK_CREATOR_INFO )
		offset = sizeof(_OBJECT_HEADER_CREATOR_INFO);

	if ( i & OB_INFOMASK_NAME )
		offset += sizeof(_OBJECT_HEADER_NAME_INFO);

	if ( i & OB_INFOMASK_HANDLE )
		offset += sizeof(_OBJECT_HEADER_HANDLE_INFO);

	if ( i & OB_INFOMASK_QUOTA )
		offset += sizeof(_OBJECT_HEADER_QUOTA_INFO);

	if ( i & OB_INFOMASK_PROCESS_INFO )
		offset += sizeof(_OBJECT_HEADER_PROCESS_INFO);

	ObpInfoMaskToOffset[i++] = offset;

}while( i < 32 );

PVOID ObQueryNameInfo(IN PVOID Object)
{
	POBJECT_HEADER ObjectHeader;
	BYTE InfoMask;
	ULONG NameInfo;

	ObjectHeader = OBJECT_TO_OBJECT_HEADER_NEW(Object);
	InfoMask = ObjectHeader->InfoMask;
	NameInfo = 0;
	
	if( InfoMask & OB_INFOMASK_NAME) {

		NameInfo = (ULONG)ObjectHeader - ObpInfoMaskToOffset[InfoMask & (OB_INFOMASK_NAME + OB_INFOMASK_CREATOR_INFO)];
	
	} else {

		NameInfo = 0;
	}
	return (PVOID)NameInfo;
}
edit:
But always better to use documented ways, see GamingMaster post
 #8938  by GamingMasteR
 Mon Oct 03, 2011 1:19 pm
Code: Select all
NTSTATUS Status;
ULONG dwRetLength = 0;

Status = ObQueryNameString(Object, NULL, 0, &dwRetLength);
if (dwRetLength > 0)
{
	ObjectName = (POBJECT_NAME_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, dwRetLength, 'mlst');
	if (ObjectName)
	{
		RtlZeroMemory(ObjectName, dwRetLength);
		Status = ObQueryNameString(Object, ObjectName, dwRetLength, &dwRetLength);
		if (Status == STATUS_SUCCESS)
			DbgPrint("device :: %wZ\n", ObjectName);
		ExFreePoolWithTag(ObjectName, 'mlst');
	}
	else
	{
		Status = STATUS_UNSUCCESSFUL;
	}
}