typedef struct _OBJECT_TYPE_INITIALIZER
{
ERESOURCE Mutex ;
LIST_ENTRY TypeList ;
UNICODE_STRING Name ;
PVOID DefaultObject ;
ULONG Index ;
ULONG TotalNumberOfObjects ;
ULONG TotalNumberOfHandles ;
ULONG HighWaterNumberOfObjects ;
ULONG HighWaterNumberOfHandles ;
struct _OBJECT_TYPE_INITIALIZER *TypeInfo ;
ULONG Key ;
ERESOURCE ObjectLocks[4];
USHORT Length ;
UCHAR UseDefaultObject ;
UCHAR CaseInsensitive ;
ULONG InvalidAttributes ;
GENERIC_MAPPING GenericMapping ;
ULONG ValidAccessMask ;
UCHAR SecurityRequired ;
UCHAR MaintainHandleCount ;
UCHAR MaintainTypeList ;
POOL_TYPE PoolType ;
ULONG DefaultPagedPoolCharge ;
ULONG DefaultNonPagedPoolCharge ;
PVOID DumpProcedure ;
PLONG OpenProcedure ;
PVOID CloseProcedure ;
PVOID DeleteProcedure ;
PLONG ParseProcedure ;
PLONG SecurityProcedure ;
PLONG QueryNameProcedure ;
PUCHAR OkayToCloseProcedure ;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
typedef struct _OBJECT_TYPE
{
ERESOURCE Mutex ;
LIST_ENTRY TypeList ;
UNICODE_STRING Name ;
PVOID DefaultObject ;
ULONG Index ;
ULONG TotalNumberOfObjects ;
ULONG TotalNumberOfHandles ;
ULONG HighWaterNumberOfObjects ;
ULONG HighWaterNumberOfHandles ;
OBJECT_TYPE_INITIALIZER TypeInfo ;
ULONG Key ;
ERESOURCE ObjectLocks[4] ;
} OBJECT_TYPE, *POBJECT_TYPE;
请注意,查看这个对象头,它很有用,因为它里面的
NameInfoOffset 偏移指向的地址 指向了标志了对象的名字,
Type中 的Name标志了对象的类型。
///////////////////////////////////////////////////
//作者:wo最爱吃大白兔
//时间:2018/3/28
////////////////////////////////////////////////////
#include <ntifs.h>
#define NUMBER_HASH_BUCKETS 37
//提前声明结构体别名
typedef struct _OBJECT_DIRECTORY *POBJECT_DIRECTORY;
typedef struct _OBJECT_DIRECTORY_ENTRY *POBJECT_DIRECTORY_ENTRY;
typedef struct _DEVICE_MAP
{
POBJECT_DIRECTORY DosDevicesDirectory;
POBJECT_DIRECTORY GlobalDosDevicesDirectory;
ULONG ReferenceCount;
ULONG DriveMap;
UCHAR DriveType[32];
} DEVICE_MAP, * PDEVICE_MAP;
typedef struct _OBJECT_DIRECTORY_ENTRY
{
POBJECT_DIRECTORY_ENTRY ChainLink;
PVOID Object;
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
typedef struct _OBJECT_DIRECTORY
{
POBJECT_DIRECTORY_ENTRY HashBuckets[NUMBER_HASH_BUCKETS];
EX_PUSH_LOCK Lock;
PDEVICE_MAP DeviceMap;
ULONG SessionId;
USHORT Reserved;
USHORT SymbolicLinkUsageCount;
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
typedef struct _OBJECT_CREATE_INFORMATION
{
ULONG Attributes;
PVOID RootDirectory;
PVOID ParseContext;
CHAR ProbeMode;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PVOID SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
}OBJECT_CREATE_INFORMATION,* POBJECT_CREATE_INFORMATION;
typedef struct _OBJECT_HEADER
{
ULONG PointerCount;
union
{
ULONG HandleCount;
PVOID NextToFree;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PVOID SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, * POBJECT_HEADER;
typedef struct _OBJECT_HEADER_NAME_INFO
{
POBJECT_DIRECTORY Directory;
UNICODE_STRING Name;
ULONG QueryReferences;
} OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
typedef struct _OBJECT_TYPE_INITIALIZER
{
ERESOURCE Mutex ;
LIST_ENTRY TypeList ;
UNICODE_STRING Name ;
PVOID DefaultObject ;
ULONG Index ;
ULONG TotalNumberOfObjects ;
ULONG TotalNumberOfHandles ;
ULONG HighWaterNumberOfObjects ;
ULONG HighWaterNumberOfHandles ;
struct _OBJECT_TYPE_INITIALIZER *TypeInfo ;
ULONG Key ;
ERESOURCE ObjectLocks[4];
USHORT Length ;
UCHAR UseDefaultObject ;
UCHAR CaseInsensitive ;
ULONG InvalidAttributes ;
GENERIC_MAPPING GenericMapping ;
ULONG ValidAccessMask ;
UCHAR SecurityRequired ;
UCHAR MaintainHandleCount ;
UCHAR MaintainTypeList ;
POOL_TYPE PoolType ;
ULONG DefaultPagedPoolCharge ;
ULONG DefaultNonPagedPoolCharge ;
PVOID DumpProcedure ;
PLONG OpenProcedure ;
PVOID CloseProcedure ;
PVOID DeleteProcedure ;
PLONG ParseProcedure ;
PLONG SecurityProcedure ;
PLONG QueryNameProcedure ;
PUCHAR OkayToCloseProcedure ;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
typedef struct _OBJECT_TYPE
{
ERESOURCE Mutex ;
LIST_ENTRY TypeList ;
UNICODE_STRING Name ;
PVOID DefaultObject ;
ULONG Index ;
ULONG TotalNumberOfObjects ;
ULONG TotalNumberOfHandles ;
ULONG HighWaterNumberOfObjects ;
ULONG HighWaterNumberOfHandles ;
OBJECT_TYPE_INITIALIZER TypeInfo ;
ULONG Key ;
ERESOURCE ObjectLocks[4] ;
} OBJECT_TYPE, *POBJECT_TYPE;
//获取到对象的结构体部分
#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 EnumDirectory(POBJECT_DIRECTORY pObejctDirectory)
{
POBJECT_DIRECTORY_ENTRY pObjectDirectoryEntry;
POBJECT_HEADER pObjectHeader;
POBJECT_HEADER_NAME_INFO pObjectHeaderNameInfo;
int i;
POBJECT_TYPE pObjectType;
UNICODE_STRING ustrName;
RtlInitUnicodeString(&ustrName,L"Directory");
KdPrint(("------------------------------------正在遍历目录对象:[0x%08x]----------------------.\n",pObejctDirectory));
for(i = 0; i < NUMBER_HASH_BUCKETS; i ++)
{
pObjectDirectoryEntry = pObejctDirectory->HashBuckets[i];
if (!MmIsAddressValid(pObjectDirectoryEntry))
{
//KdPrint(("-->此节点遍历目录连接对象POBJECT_DIRECTORY_ENTRY无效.\n"));
continue;
}
do
{
if (!MmIsAddressValid(pObjectDirectoryEntry->Object))
{
//KdPrint(("-->此节点遍历到的对象pObjectDirectoryEntry->Object无效.\n"));
break;
}
pObjectHeader = OBJECT_TO_OBJECT_HEADER(pObjectDirectoryEntry->Object);//根据对象来获取到对象
KdPrint(("[节点 = %02d] 此对象地址为:[0x%08x] , 对象类型为:[%wZ] ,",i,pObjectDirectoryEntry->Object,&(pObjectHeader->Type->Name)));
if (pObjectHeader->NameInfoOffset > 0)
{
pObjectHeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(pObjectHeader);//获取到对象名结构体
KdPrint(("此对象名称为:[%wZ].\n",&(pObjectHeaderNameInfo->Name)));
}
else
{
KdPrint(("此对象没有名称.\n"));
}
//如果还是目录对象应该将其展开再次遍历
if (RtlCompareUnicodeString(&(pObjectHeader->Type->Name),&ustrName,TRUE) == 0)
{
EnumDirectory((POBJECT_DIRECTORY)pObjectDirectoryEntry->Object);
}
pObjectDirectoryEntry = pObjectDirectoryEntry->ChainLink;
}while(pObjectDirectoryEntry != NULL);
}
}
void DriverUnload(PDRIVER_OBJECT drv)
{
}
NTSTATUS myDispatchFunction(PDEVICE_OBJECT device,PIRP irp)
{
// 如果根本就不在被绑定的设备中,那是有问题的,直接返回参数错误。
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
size_t i;
NTSTATUS status;
OBJECT_ATTRIBUTES oaDirectory;
UNICODE_STRING ustrDirectory;
PVOID DirectoryObject = NULL;
HANDLE hDirectory;
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
driver->MajorFunction[i] = myDispatchFunction;
}
driver->DriverUnload = DriverUnload;
//获取目录对象
RtlInitUnicodeString(&ustrDirectory, L"\\");
InitializeObjectAttributes(&oaDirectory, &ustrDirectory, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwOpenDirectoryObject(&hDirectory, 0, &oaDirectory);
if (NT_SUCCESS(status) )
{
//提供对象句柄访问许可,获取到对应目录对象
status = ObReferenceObjectByHandle(hDirectory, 0x10000000, 0, 0, &DirectoryObject, 0);
if ( NT_SUCCESS(status) )
{
//从根目录对对象进行遍利,迭代算法
EnumDirectory((POBJECT_DIRECTORY)DirectoryObject);
//解除对象引用
ObfDereferenceObject(DirectoryObject);
}
status = ZwClose(hDirectory);
}
return STATUS_SUCCESS;
}