Windows内核对象头部结构

来源:互联网 发布:杰克伦敦广场重要数据 编辑:程序博客网 时间:2024/05/19 11:44

在Windows中,内核对象由三部分组成,其中第一部分是由数个不确定的结构组成,第二部分就是结构头OBJECT_HEADER,第三部分则是对象体。后两部分容易确定,OBJECT_HEADER后48个字节就是对象体。第一部分则是完全隐藏起来的机制,而且Win7系统中OBJECT_HEADER里也没有了前面几个结构的偏移信息,所以需要具体研究一下这个字段的生成机制。
这个结构肯定是在ObCreateObject中创建的,其中的ObpAllocateObject完成了对象的内存分配和初始化,就从这个函数着手进行分析。
下面是对ObpAllocateObject的逆向,可能有些地方和源程序流程不一样,中间许多流程进行了优化,只能尽量去还原成正确的C代码。

NTSTATUS ObpAllocateObject(POBJECT_CREATE_INFO CreateInfo,    KPROCESSOR_ACCESS OwnerMode,    POBJECT_TYPE ObjectType,    PUNICODE_STRING CapturedName,    DWORD ObjectBodySize,    POBJECT_HEADER* ObjectHeader) {    DWORD InfoMask = 0;    DWORD ObjectTotalSize = 0;    NTSTATUS Status;    PBYTE Object;    PBYTE ObjectFields;    POBJECT_HEADER_CREATOR_INFO CreatorInfo;    POBJECT_HEADER_HANDLE_INFO HandleInfo;    POBJECT_HEADER_QUOTA_INFO QuotaInfo;    POBJECT_HEADER_NAME_INFO NameInfo;    PEPROCESS CurrentProcess = PsGetCurrentProcess();    //前面不知道是干嘛的    if (CreateInfo->Attributes & 0x20) {        ObjectTotalSize += 0x10;        InfoMask |= 0x10;    }    //需要性能技术    if (CurrentProcess != PsInitialSystemProcess) {        if (CurrentProcess != PsIdleProcess)            if (PsInitialSystemProcess != NULL) {                InfoMask |= 8;                ObjectTotalSize += sizeof(OBJECT_HEADER_QUOTA_INFO);            }    }    //需要记录句柄计数信息    if (ObjectType->TypeInfo->MaintainHandleCount) {        InfoMask |= 4;        ObjectTotalSize += sizeof(OBJECT_HEADER_HANDLE_INFO);    }    //需要对象名字字段    if (CapturedName->Length != 0) {        if (ObjectType->TypeInfo->UnnamedObjectsOnly)            Status = STATUS_OBJECT_NAME_INVALID;        else {            InfoMask |= 2;            ObjectTotalSize += sizeof(OBJECT_HEADER_NAME_INFO);        }    }    //需要类型信息    if (ObjectType->TypeInfo->MaintainTypeList) {        InfoMask |= 1;        ObjectTotalSize += sizeof(OBJECT_HEADER_CREATOR_INFO);    }    if (ObjectTotalSize == 0) {        Status = STATUS_INVALID_PARAMETER;        goto EXIT;    }    Object = (PBYTE)ExAllocatePoolWithTag(ObjectType->TypeInfo->PoolType,        ObjectTotalSize,        ObjectType->Key | 0x80000000    );    if (Object == NULL) {        Status = STATUS_INSUFFICIENT_RESOURCES;        goto EXIT;    }    *(HANDLE*)Object = 0;    if (InfoMask & 0x10)        ObjectFields = Object + 0x10;    if (InfoMask & 8) {        QuotaInfo = (POBJECT_HEADER_QUOTA_INFO)(ObjectFields);        QuotaInfo->PagedPoolCharge = CreateInfo->PagedPoolCharge;        QuotaInfo->NonpagePoolCharge = CreateInfo->NonpagePoolCharge;        QuotaInfo->SecurityDescriptorCharge = CreateInfo->SecurityDescriptorCharge;        QuotaInfo->SecurityDescriptorQuotaBlock = NULL;        ObjectFields += sizeof(OBJECT_HEADER_QUOTA_INFO);    }    if (InfoMask & 4) {        HandleInfo = (POBJECT_HEADER_HANDLE_INFO)(ObjectFields);        HandleIfo->LockCount = -1;        HandleInfo->Process = NULL;        HandleInfo->HandleCount = 0;        ObjectFields += sizeof(OBJECT_HEADER_HANDLE_INFO);    }    if (InfoMask & 2) {        NameInfo = (POBJECT_HEADER_NAME_INFO)(ObjectFields);        NameInfo->Directory = NULL;        NameInfo->ReferenceCount = 0;        RtlCopyMemory(NameInfo->Name, CapturedName, sizeof(UNICODE_STRING));        ObjectFields += sizeof(OBJECT_HEADER_NAME_INFO);    }    if (InfoMask & 1) {        CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)(ObjectFields);        CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcess();        InitializeListHead(CreateInfo->TypeList);        ObjectFields += sizeof(OBJECT_HEADER_CREATOR_INFO);    }    ObjectHeader->InfoMask = InfoMask;    ObjectHeader->TraceFlags = 0;    ObjectHeader->Flags = 1;    if (InfoMask & 4)        ObjectHeader->Flags = 0x41;    ObjectHeader->PointerCount = 1;    ObjectHeader->HandleCount = 0;    ObjectHeader->Lock = 0;    ObjectHeader->TypeIndex = ObjectType->TypeIndex;    if (OwnerMode == 0) {        ObjectHeader->Flags |= 2;        if (CreateInfo->Attributes & 0x10000) {            ObjectHeader->Flags |= 4;        }    }    if (CreateInfo->Attribute & 0x10)        ObjectHeader->Flags |= 0x10;    if (CreateInfo->Attribute & 0x20)        ObjectHeader->Flags |= 0x8;    ObjectHeader->CreateInfo = CreateInfo;    ObjectHeader->SecurityDescriptor = NULL;    InterlockedIncrement(&ObjectType->TotalNumberOfObjects);    if (ObjectType->TotalNumberOfObject>ObjectType->HighWaterNumberOfObjects)        ObjectType->HighWaterNumberOfObjects = ObjectType->TotalNumberOfObject;    *ObjectHeader = (POBJECT_HEADER)ObjectFields;    Status = STATUS_SUCCESS;EXIT:    return Status;}

可以看出,对象头部具体是由那些结构组成,取决于如下几点:

  • 是不是Init进程或者Idle进程,如果不是就有OBJECT_HEADER_QUOTA_INFO结构。
  • ObjectType中是否需要记录句柄信息,如果需要就有OBJECT_HEADER_HANDLE_INFO结构。
  • 是否有参数CapturedName以及ObjectType是否允许有名字,如果都有,就有OBJECT_HEADER_NAME_INFO结构。
  • ObjectType中是否需要记录类型信息,如果需要就有OBJECT_HEADER_CREATOR_INFO结构。