/*
win7 32
windows 對象管理相關部分學習小結,
可以結合winobj,windbg等工具來查看及驗證相關數據
*/
#include "ntddk.h"
//extern ObTypeIndexTable;
#define NUMBER_HASH_BUCKETS 37
#define OBJECT_TO_OBJECT_HEADER(O) CONTAINING_RECORD((O),OBJECT_HEADER,Body)
#define OBJECT_TO_OBJECT_HEADER_NAME_INFO(o) CONTAINING_RECORD((o),OBJECT_HEADER_NAME_INFO,Directory)
//#define CONTAINING_RECORD(address,type,field) ((type*)(((ULONG_PTR)address)-(ULONG_PTR)(&(((type*)0)->field))))
typedef ULONG DEVICE_MAP;
typedef ULONG EX_PUSH_LOCK;
typedef struct _OBJECT_DIRECTORY
{
struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[NUMBER_HASH_BUCKETS];
EX_PUSH_LOCK Lock;
DEVICE_MAP DeviceMap;
ULONG SessionId;
PVOID NamespaceEntry;
ULONG Flags;
}OBJECT_DIRECTORY,*POBJECT_DIRECTORY;
typedef struct _OBJECT_DIRECTORY_ENTRY{
struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
PVOID Object;
ULONG HashValue;
}OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
typedef struct _OBJECT_CREATE_INFORMATION
{
ULONG Attributes;
PVOID RootDirectory;
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
{
LONG PointerCount;
union
{
LONG HandleCount;
volatile PVOID NextToFree;
};
EX_PUSH_LOCK Lock;
UCHAR TypeIndex;
UCHAR TraceFlags;
UCHAR InfoMask;
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 ReferenceCount;
}OBJECT_HEADER_NAME_INFO,*POBJECT_HEADER_NAME_INFO;
typedef struct _OBJECT_TYPE_INITIALIZER {
USHORT Length ;
UCHAR ObjectTypeFlags ;
UCHAR CaseInsensitive ;
UCHAR UnnamedObjectsOnly ;
UCHAR UseDefaultObject ;
UCHAR SecurityRequired ;
UCHAR MaintainHandleCount ;
UCHAR MaintainTypeList ;
UCHAR SupportsObjectCallbacks ;
UCHAR CacheAligned ;
ULONG ObjectTypeCode ;
BOOLEAN InvalidAttributes ;
GENERIC_MAPPING GenericMapping ;
BOOLEAN ValidAccessMask ;
BOOLEAN RetainAccess ;
POOL_TYPE PoolType ;
BOOLEAN DefaultPagedPoolCharge ;
BOOLEAN DefaultNonPagedPoolCharge ;
PVOID DumpProcedure ;
ULONG OpenProcedure ;
PVOID CloseProcedure ;
PVOID DeleteProcedure ;
ULONG ParseProcedure ;
ULONG SecurityProcedure;
ULONG QueryNameProcedure;
UCHAR OkayToCloseProcedure ;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
typedef struct _OBJECT_TYPE
{
LIST_ENTRY TypeList;
UNICODE_STRING Name;
PVOID DefaultObject;
UCHAR Index;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
OBJECT_TYPE_INITIALIZER TypeInfo;
EX_PUSH_LOCK TypeLock;
ULONG Key;
LIST_ENTRY CallbackList;
}OBJECT_TYPE,*POBJECT_TYPE;
NTSTATUS
ZwOpenDirectoryObject(
__out PHANDLE DirectoryHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes
);
NTSTATUS
ObQueryNameString(
IN PVOID Object,
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
IN ULONG Length,
OUT PULONG ReturnLength
);
NTSTATUS ObReferenceObjectByHandle(IN HANDLE Handle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
OUT PVOID* Object,
OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL);
VOID DriverUnload(PDRIVER_OBJECT driver)
{
DbgPrint("goodbye!\n");
}
VOID ListObjectType(POBJECT_DIRECTORY Type)//列出對象類型
{
ULONG BucketIndex=0;
POBJECT_TYPE temp=NULL;
POBJECT_DIRECTORY_ENTRY CurrentEntry=NULL;
DbgPrint("Index TypeNames\n");
do
{
if((CurrentEntry=Type->HashBuckets[BucketIndex]))//not (&RootDirectoryObject->HashBuckets[]),pay attention to the use of pointer and '&'
{
do//search the whole queue
{
temp=(POBJECT_TYPE)CurrentEntry->Object;
DbgPrint("0x%2x %wZ",temp->Index,&temp->Name);
CurrentEntry=CurrentEntry->ChainLink;//鏈表中下一個
}while(CurrentEntry);
}
BucketIndex++;
}while(BucketIndex<NUMBER_HASH_BUCKETS);
}
NTSTATUS object()
{
UNICODE_STRING Name;
NTSTATUS status=STATUS_SUCCESS;
HANDLE Handle;
OBJECT_ATTRIBUTES ObjectAttributes;
POBJECT_DIRECTORY RootDirectoryObject=NULL;
POBJECT_TYPE ObjectType=NULL;
POBJECT_HEADER ObjectHeader;
POBJECT_HEADER_NAME_INFO NameInfo;
POBJECT_NAME_INFORMATION name;
POBJECT_DIRECTORY_ENTRY CurrentEntry;
ULONG uRet,BucketIndex=0;
name=(POBJECT_NAME_INFORMATION)ExAllocatePool(NonPagedPool,1024);
RtlInitUnicodeString(&Name,L"\\");//ObpRootDirectoryObject,'\\'是對象管理的根目錄
InitializeObjectAttributes(&ObjectAttributes,&Name,OBJ_CASE_INSENSITIVE|OBJ_PERMANENT,NULL,/*SePublicDefaultUnrestrictedSd*/NULL);
status=ZwOpenDirectoryObject(&Handle,DIRECTORY_ALL_ACCESS,&ObjectAttributes);//打開目錄對象
if(!NT_SUCCESS(status))
{
KdPrint(("ZwOpenDirectoryObject fail!\n"));
return STATUS_UNSUCCESSFUL;
}
//通過對象句柄得到對象指針
status=ObReferenceObjectByHandle(Handle,0,NULL,KernelMode,(PVOID*)&RootDirectoryObject,NULL);
if(!NT_SUCCESS(status))
{
KdPrint((" ObReferenceObjectByName Failure! status=0x%08x\n",status));
return STATUS_UNSUCCESSFUL;
}
do
{
if((CurrentEntry=RootDirectoryObject->HashBuckets[BucketIndex]))//not (&RootDirectoryObject->HashBuckets[]),pay attention to the use of pointer and '&'
{
//KdPrint(("ObjectHeader TypeIdex HashValue name\n"));
do//search the whole queue
{
ObjectHeader=OBJECT_TO_OBJECT_HEADER(CurrentEntry->Object);
status=ObQueryNameString(CurrentEntry->Object,name,1024,&uRet);
if(!NT_SUCCESS(status))
{
KdPrint(("ObQueryNameString fails\n"));
return STATUS_UNSUCCESSFUL;
}
//KdPrint(("0x%08x 0x%2x 0x%8x %wZ\n",ObjectHeader,ObjectHeader->TypeIndex,CurrentEntry->HashValue,&name->Name));
if(ObjectHeader->TypeIndex==0x3)
{
if(name->Name.Length==RtlCompareMemory(name->Name.Buffer,L"\\ObjectTypes",name->Name.Length))
{
DbgPrint("find ObjectTypes!\n");
ListObjectType((POBJECT_DIRECTORY)CurrentEntry->Object);
}
}
CurrentEntry=CurrentEntry->ChainLink;
if(!MmIsAddressValid(CurrentEntry))
{
break;
}
RtlZeroMemory(name,uRet);
}while(CurrentEntry);
}
BucketIndex++;
}while(BucketIndex<NUMBER_HASH_BUCKETS);
ObDereferenceObject(RootDirectoryObject);
ZwClose(Handle);
ExFreePool(name);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
DbgPrint("enter DriverEntry!\n");
object();
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
結果圖: