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

结果图:

202301052120

对象通知

参考:windows内核编程

   内核提供这样一种机制,它能够在试图打开或者复制特定对象类型的句柄时通知感兴趣的驱动程序。正式支持的对象类型有进程和线程(上图中的文件,可能还有其它的),对Windows10来说,还有桌面对象。

相关函数和数据结构:

 NTSTATUS ObRegisterCallbacks(

  _In_ POB_CALLBACK_REGISTRATION CallbackRegistration,

  _Outptr_  PVOID *RegistrationHandle);

typedef struct _OB_CALLBACK_REGISTRATION{

_In_ USHORT                                       Version;

_In_ USHORT                                       OperationRegistrationCount;

_In_  UNICODE_STRING                     Altitude;

_In_  PVOID                                          RegistrationContext;//驱动程序定义的值,会原样传递给回调函数

_In_ OB_OPERATION_REGISTRATION *OperationRegistration;

}OB_CALLBACK_REGISTRATION,*POB_CALLBACK_REGISTRATION;

typedef struct _OB_OPERATION_REGISTRATION{

_In_  POBJECT_TYPE                     *ObjectType;

_In_  OB_OPERATION                       Operations;

_In_   POB_PRE_OPERATION_CALLBACK  PreOperation;

_In_  POB_POST_OPERATION_CALLBACK PostOperation;

}OB_OPERATION_REGISTRATION,*POB_OPERATION_REGISTRATION;

ObjectType是一个指向这个实例注册的对象类型(进程,线程或桌面)的指针。这些指针被分别输出为全局内核变量:PsProcessType,PsThreadType和ExDesktopObjectType.

Operations字段是一个位标识枚举类型,用来选择创建/打开操作(OB_OPERATION_HANDLE_CREATE)和复制操作(OB_OPERATION_HANDLE_DUPLICATE)。

OB_OPERATION_HANDLE_CREATE针对用户模式函数CreateProcess、OpenProcess、CreateThread、OpenThread、CreateDesktop、OpenDesktop和针对这些对象类型的相似函数的调用。OB_OPERATION_HANDLE_DUPLICATE指这些对象类型的句柄复制操作(用户模式DuplicateHandle API)。

操作前回调

   操作前回调是在实际的创建/打开/复制操作完成之前被调用,给驱动程序一个对操作结果进行修改的机会。操作前回调接受一个OB_PRE_OPERATION_INFORMATION结构,其定义如下:

typedef struct _OB_PRE_OPREATION_INFORMATION{

_In_   OB_OPERATION                  Operation;

union {

    _In_   ULONG      Flags;

    struct  {

            _In_   ULONG  KernelHandle:1;

           _In_    ULONG  Reserved:31;

     };

    _In_   PVOID       Object;

    _In_   POBJECT_TYPE    ObjectType;

    _Out_   PVOID               CallContext;

    _In_  POB_PRE_OPERATION_PARAMETERS  Parameters;

}OB_PRE_OPERATION_INFORMATION,*POB_PRE_OPERATION_INFORMATION;

typedef union _OB_PRE_OPERATION_PARAMETERS{

_Inout_    OB_PRE_CREATE_HANDLE_INFORMATION            CreateHandleInformation;

_Inout_     OB_PRE_DUPLICATE_HANDLE_INFORMATION     DuplicateHandleInformation;

}OB_PRE_OPERATION_PARAMETERS,*POB_PRE_OPERATION_PARAMETERS;

typedef struct _OB_PRE_CREATE_HANDLE_INFORMATION{

_Inout_   ACCESS_MASK         DesiredAccdess;//可以被驱动程序修改的掩码值,只能减,不能加

_In_        ACCESS_MASK         OriginalDesiredAccess;//原始的掩码值

}OB_PRE_CREATE_HANDLE_INFORMATION,*POB_PRE_CREATE_HANDLE_INFORMATION;

typedef struct _OB_PRE_DUPICATE_HADNLE_INFORMATION{

_Inout_   ACCESS_MASK      DesiredAccess;

_In_       ACCESS_MASK       OriginalDesiredAccess;

_In_       PVOID                       SourceProcess;

_In_       PVOID                       TargetProcess;

}OB_PRE_DUPLICATE_HANDLE_INFORMATION,*POB_PRE_DUPLICATE_HANDLE_INFORMATION;

操作后回调

   操作后回调是在操作完成之后被调用。此时驱动程序不能进行任何修改,只能查看结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值