windows 對象管理學習小結

/*
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;  
}  

結果圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章