lkd> dt nt!_object_attributes
+0x000 Length : Uint4B
+0x004 RootDirectory : Ptr32 Void
+0x008 ObjectName : Ptr32 _UNICODE_STRING
+0x00c Attributes : Uint4B
+0x010 SecurityDescriptor : Ptr32 Void
+0x014 SecurityQualityOfService : Ptr32 Void
关于Attributes的取值:
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L **
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
#define OBJ_VALID_ATTRIBUTES 0x000007F2L
NTSTATUS
ExCreateCallback(OUT PCALLBACK_OBJECT *CallbackObject,//接受输出的数据
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN BOOLEAN Create,
IN BOOLEAN AllowMultipleCallbacks
)
{
NTSTATUS status;
HANDLE Handle; //esp+0x10
//esp+0x14
ULONG Length=Attrubutes->Length; //esp+0x18
PVOID RootDirectory=Attributes->RootDirectory; //esp+0x1c
PUNICODE_STRING ObjectName=Attributes->ObjectName; //esp+0x20
ULONG Attributes=Attributes->Attributes; //esp+0x24
PVOID SecurityDescriptor=Attributes->SecurityDescriptor;//esp+0x28
PVOID SecurityQualityOfService=Attributes->SecurityQualityOfService;//esp+0x2c
//Attributes esp+0x30
Attributes|=OBJ_KERNEL_HANDLE; //0X200
if(ObjectName) //提供对象名
{
status=ObOpenObjcetByName(Attributes,*ExCallbackObjectType,KERNEL_MODE/*0*/,0,0,NULL,Handle);//通过名字打开对象
}
else
{
status=STATUS_UNSUCCESSFUL; //0xc0000001
}
if(!NT_SUCCESS(status)||!Create) //没有找到目标对象也不要求创建一个
{
return status;
}
else if(!NT_SUCCESS(status)) //没找到并且要求创建一个新的callback对象
{
status=ObCreateObject(,*ExCallbackObjectType,);
if(NT_SUCCESS(status))
{
status=ObInsertObjectEx(,,);//将创建好的对象收集到一起去管理
if(!NT_SUCCESS(status))
{
return status;
}
}
else
{
return status;
}
}
status=ObReferenceObjectByHandle(,ExCallbackObjectType,Attributes,Length,);
if(NT_SUCCESS(status))
{
//保存相应的数据到第一个参数CallBackObject中
}
ZwClose(Handle);
return status;
}
上面基本上还原了这个函数的框架,里面没有真正的工作代码,任务都是调用Ob****Object这些函数去完成的。可惜的是这些函数和相关数据结构没有被内核导出来,_callback_object也只是由定义。