其他分享
首页 > 其他分享> > ObCreateObjectTypeEx函数逆向分析

ObCreateObjectTypeEx函数逆向分析

作者:互联网

0x00前言

过程比较简单主要是类型的初始化和验证

0x01汇编分析

__int64 __fastcall ObCreateObjectTypeEx(
        PCUNICODE_STRING SourceString,
        __int64 a2,
        __int64 a3,
        __int16 *a4,
        __int64 *a5)
{
  __int16 *v8; // r13
  unsigned int Length; // ecx
  unsigned __int8 v10; // r12
  char v11; // al
  unsigned int v12; // ecx
  wchar_t *Buffer; // rdx
  wchar_t v14; // ax
  __int128 *v15; // r8
  UNICODE_STRING v16; // xmm6
  int Object; // esi
  size_t v18; // rax
  __int64 v19; // rbx
  bool v20; // zf
  char v21; // r13
  unsigned __int16 v22; // r15
  PVOID PoolWithTag; // rax
  PVOID v24; // r15
  _DWORD *v25; // r8
  unsigned int v26; // ecx
  int v27; // ecx
  struct _KTHREAD *CurrentThread; // rax
  _DMA_OPERATIONS *v29; // rax
  PADAPTER_OBJECT v30; // rcx
  _DMA_OPERATIONS *DmaOperations; // rdx
  unsigned int v32; // edi
  PADAPTER_OBJECT v33; // rdx
  unsigned int DmaOperations_high; // eax
  int v35; // ecx
  __int64 v36; // rdx
  unsigned int v38; // r9d
  _BYTE *v39; // rdx
  __int128 v40; // xmm0
  __int128 v41; // xmm1
  __int128 v42; // xmm0
  __int128 v43; // xmm1
  __int128 v44; // xmm0
  __int128 v45; // xmm1
  __int128 v46; // xmm0
  int v47; // [rsp+48h] [rbp-C0h]
  size_t Size[2]; // [rsp+58h] [rbp-B0h] BYREF
  _DWORD *DestinationString; // [rsp+68h] [rbp-A0h]
  __int128 DestinationString_8; // [rsp+70h] [rbp-98h] BYREF
  PVOID P; // [rsp+80h] [rbp-88h]
  __int64 v53[2]; // [rsp+88h] [rbp-80h] BYREF
  __int128 v54; // [rsp+98h] [rbp-70h]
  __int64 v55; // [rsp+A8h] [rbp-60h]
  __int64 *v56; // [rsp+B0h] [rbp-58h]
  int v57[16]; // [rsp+B8h] [rbp-50h] BYREF
  __int128 v58[14]; // [rsp+F8h] [rbp-10h] BYREF

  v56 = a5;
  v8 = a4;
  memset(v58, 0, 0xD8ui64);
  v55 = 0i64;
  *(_OWORD *)v53 = 0i64;
  Size[0] = 0i64;
  v54 = 0i64;
  memset(v57, 0, sizeof(v57));
  DestinationString_8 = 0i64;
  if ( !SourceString
    || (Length = SourceString->Length, !(_WORD)Length)
    || (Length & 1) != 0
    || !a2
    || (*(_DWORD *)(a2 + 8) & 0xFFFEE00D) != 0
    || *(_WORD *)a2 != 120
    || (v10 = 2, *(_BYTE *)(a2 + 3) >= 2u)
    || (v11 = *(_BYTE *)(a2 + 2), (v11 & 0x10) != 0) && !*(_QWORD *)(a2 + 56) && !*(_QWORD *)(a2 + 64)
    || (v11 & 4) == 0 && (*(_DWORD *)(a2 + 36) & 0xFFFFFDFF) != 0 && ((unsigned __int8)v8 & 1) == 0 )
  {
    DbgPrintEx(0, 0, "Error creating object type\n");// 参数检查
    __debugbreak();
  }
  v12 = Length >> 1;                            // 除2
  Buffer = SourceString->Buffer;
  v47 = *(_DWORD *)(a2 + 36);
  if ( !v12 )                                   // 长度大于0
  {
LABEL_13:
    LODWORD(v55) = 0xFFFF1234;
    if ( ObpTypeDirectoryObject                 // 寻找已经类型目录
      && (ObpLockDirectoryExclusive((__int64)v53, ObpTypeDirectoryObject),
          ObpLookupDirectoryEntryEx(ObpTypeDirectoryObject, &SourceString->Length, 64, 0i64, 0, (__int64)v53)) )// 不忽略大小写
    {
      v32 = 0xC0000035;                         // 类型对象冲突
    }
    else
    {
      *((_QWORD *)&DestinationString_8 + 1) = ExAllocatePoolWithTag(PagedPool, SourceString->MaximumLength, 0x6D4E624Fu);
      if ( *((_QWORD *)&DestinationString_8 + 1) )// 判断是否为空
      {
        WORD1(DestinationString_8) = SourceString->MaximumLength;
        RtlCopyUnicodeString((PUNICODE_STRING)&DestinationString_8, SourceString);// 复制
        v15 = (__int128 *)ObpTypeObjectType;
        v16 = (UNICODE_STRING)DestinationString_8;
        if ( !ObpTypeObjectType )
        {
          v40 = *(_OWORD *)a2;                  // POBJECT_TYPE_INITIALIZER 填充这个结构
          BYTE8(v58[2]) = 2;
          v15 = v58;
          v41 = *(_OWORD *)(a2 + 16);
          LODWORD(v58[12]) = 1416258127;
          v58[4] = v40;
          v42 = *(_OWORD *)(a2 + 32);
          v58[5] = v41;
          v43 = *(_OWORD *)(a2 + 48);
          v58[6] = v42;
          v44 = *(_OWORD *)(a2 + 64);
          v58[7] = v43;
          v45 = *(_OWORD *)(a2 + 80);
          v58[8] = v44;
          v46 = *(_OWORD *)(a2 + 96);
          v58[9] = v45;
          *(_QWORD *)&v45 = *(_QWORD *)(a2 + 112);
          v58[10] = v46;
          *(_QWORD *)&v58[11] = v45;
          v58[1] = DestinationString_8;
        }
        v57[0] = 16;
        v57[5] = *((_DWORD *)v15 + 26);
        v57[6] = *((_DWORD *)v15 + 27);
        v57[7] = 2048;
        Object = ObpAllocateObject(
                   (int *)(unsigned int)v57,    // POBJECT_CREATE_INFORMATION 结构体
                   0i64,
                   (unsigned int)v15,           // object 类型
                   (_WORD *)(unsigned int)&DestinationString_8,// PUNICODE_STRING
                   216,
                   Size,                        // 大小
                   0i64);
        if ( Object < 0 )
        {
          ObpReleaseLookupContext(v53);
          ExFreePoolWithTag(*((PVOID *)&DestinationString_8 + 1), 0);// 释放string 
        }
        else
        {
          v18 = Size[0];
          *(_QWORD *)(Size[0] + 32) = 0i64;
          v19 = v18 + 48;
          v20 = (_DWORD)InitializationPhase == 0;
          *(UNICODE_STRING *)(v18 + 64) = v16;
          if ( v20 || (Object = ObpInitObjectTypeSD(v18 + 48, a3), Object >= 0) )
          {
            *(_OWORD *)(v19 + 44) = 0i64;
            *(_DWORD *)(v19 + 60) = 0;
            if ( ObpTypeObjectType )            // 存在这个对象
            {
              v21 = 1;                          // 将标记转为ascii码
              v22 = ((RtlxUnicodeStringToAnsiSize(SourceString) + 2) & 0xFFFC) + 1;
              Size[1] = v22;                    // 申请结构
              PoolWithTag = ExAllocatePoolWithTag(PagedPool, v22, 0x6E54624Fu);
              P = PoolWithTag;
              if ( !PoolWithTag )
                goto LABEL_75;
              memset(PoolWithTag, 0, Size[1]);
              Size[1] = 0i64;
              WORD1(Size[1]) = v22;
              v24 = P;
              DestinationString = P;
              if ( RtlUnicodeStringToAnsiString((PANSI_STRING)&Size[1], SourceString, 0) >= 0 )
              {
                v25 = DestinationString;
                v26 = SourceString->Length >> 1;
                if ( v26 < 4 )
                {
                  v38 = WORD1(Size[1]);
                  v39 = (char *)DestinationString + v26;// 主要对转换成功字符串的缺失处理
                  do
                  {
                    if ( v26 < v38 )
                      *v39 = 32;                // 对于每个缺失的字符用空格代替
                    ++v26;
                    ++v39;
                  }
                  while ( v26 < 4 );            // 长度是否小于4
                }
                v21 = 0;
                *(_DWORD *)(v19 + 192) = *v25;
              }
              ExFreePoolWithTag(v24, 0);        // 释放申请空间
              if ( v21 )                        // 转换成功走的
              {
LABEL_75:
                v8 = a4;
                if ( SourceString->Length < 4u )// 判断大小给相应赋值
                  *(_DWORD *)(v19 + 192) = 0x3F6A624F;
                else
                  *(_DWORD *)(v19 + 192) = *(_DWORD *)SourceString->Buffer;
              }
              else
              {
                v8 = a4;
              }
            }
            else
            {
              ObpTypeObjectType = (PADAPTER_OBJECT)v19;
              *(_DWORD *)(v19 + 44) = 1;        // 已经有了第一个type类型
              *(_DWORD *)(v19 + 192) = 0x546A624F;
            }
            *(_OWORD *)(v19 + 64) = *(_OWORD *)a2;// 数据结构填充
            *(_OWORD *)(v19 + 80) = *(_OWORD *)(a2 + 16);
            *(_OWORD *)(v19 + 96) = *(_OWORD *)(a2 + 32);
            *(_OWORD *)(v19 + 112) = *(_OWORD *)(a2 + 48);
            *(_OWORD *)(v19 + 128) = *(_OWORD *)(a2 + 64);
            *(_OWORD *)(v19 + 144) = *(_OWORD *)(a2 + 80);
            *(_OWORD *)(v19 + 160) = *(_OWORD *)(a2 + 96);
            *(_QWORD *)(v19 + 176) = *(_QWORD *)(a2 + 112);
            *(_DWORD *)(v19 + 100) = v47;
            if ( (NtGlobalFlag & 0x4000) != 0 ) // 检查是要维护一个类型
              *(_BYTE *)(v19 + 66) |= 0x20u;
            v27 = (*(_BYTE *)(a2 + 2) & 0x10) != 0 ? 104 : 88;
            if ( (v47 & 1) != 0 )               // 检查pool类型
              *(_DWORD *)(v19 + 104) += v27;
            else
              *(_DWORD *)(v19 + 108) += v27;
            if ( !*(_QWORD *)(a2 + 88) )        // 是否需要安全过程
              *(_QWORD *)(v19 + 152) = &SeDefaultObjectMethod;
            *(_QWORD *)(v19 + 184) = 0i64;
            *(_QWORD *)(v19 + 8) = v19;
            *(_QWORD *)v19 = v19;
            *(_QWORD *)(v19 + 208) = v19 + 200;
            *(_QWORD *)(v19 + 200) = v19 + 200;
            if ( (*(_BYTE *)(v19 + 66) & 4) != 0 )// 选择等待对象
            {
              *(_DWORD *)(v19 + 92) |= 0x100000u;
              v8 = &ObpDefaultObject;
            }
            *(_QWORD *)(v19 + 32) = v8;
            CurrentThread = KeGetCurrentThread();
            --CurrentThread->SpecialApcDisable; // 获取是否锁占用
            ExAcquirePushLockExclusiveEx((ULONG_PTR)&ObpTypeObjectType[11].DmaOperations, 0i64);
            if ( (*(_BYTE *)(Size[0] + 26) & 1) != 0 )
              v29 = (_DMA_OPERATIONS *)(Size[0] - 32);
            else
              v29 = 0i64;
            v30 = ObpTypeObjectType;
            DmaOperations = ObpTypeObjectType->DmaOperations;
            if ( *(PADAPTER_OBJECT *)&DmaOperations->Size != ObpTypeObjectType )
              __fastfail(3u);
            *(_QWORD *)&v29->Size = ObpTypeObjectType;
            v29->PutDmaAdapter = (void (__fastcall *)(_DMA_ADAPTER *))DmaOperations;
            *(_QWORD *)&DmaOperations->Size = v29;
            v32 = -1073741670;
            v30->DmaOperations = v29;
            v33 = ObpTypeObjectType;            // 初始化头部结构
            DmaOperations_high = HIDWORD(ObpTypeObjectType[2].DmaOperations);
            if ( DmaOperations_high >= 0x100 )
              Object = -1073741670;
            else
              ObpObjectTypes[DmaOperations_high - 1] = v19;
            ExReleasePushLockEx((ULONG_PTR)&v33[11].DmaOperations, 0i64);// 释放占用锁
            KiLeaveGuardedRegionUnsafe(KeGetCurrentThread());
            if ( (PADAPTER_OBJECT)v19 != ObpTypeObjectType )// 后面就是释放和初始化操作
            {
              if ( Object < 0 )
              {
LABEL_69:
                v32 = Object;
LABEL_70:
                ObpReleaseLookupContext(v53);
                HalPutDmaAdapter((PADAPTER_OBJECT)v19);
                return v32;
              }
              v35 = 3;
              v36 = 3i64;
              while ( _InterlockedCompareExchange64(&ObTypeIndexTable[v36], 1i64, 0i64) )
              {
                v36 = ++v35;
                if ( (unsigned __int64)v35 >= 0x100 )
                {
                  Object = -1073741823;
                  goto LABEL_69;
                }
              }
              v10 = v35;
            }
            ObTypeIndexTable[v10] = v19;
            *(_BYTE *)(v19 + 40) = v10;
            if ( !ObpTypeDirectoryObject || (unsigned __int8)ObpInsertDirectoryEntry(ObpTypeDirectoryObject, (PVOID)v19) )
            {
              ObpReleaseLookupContext(v53);
              *v56 = v19;
              return 0i64;
            }
            ObTypeIndexTable[v10] = 0i64;
            goto LABEL_70;
          }
          ObpReleaseLookupContext(v53);
          HalPutDmaAdapter((PADAPTER_OBJECT)v19);
        }
        return (unsigned int)Object;
      }
      v32 = -1073741670;
    }
    ObpReleaseLookupContext(v53);
    return v32;
  }
  while ( 1 )
  {
    v14 = *Buffer;
    --v12;
    ++Buffer;
    if ( v14 == 92 )
      return 3221225523i64;
    if ( !v12 )
      goto LABEL_13;
  }
}

 

标签:__,ObCreateObjectTypeEx,v19,函数,逆向,QWORD,OWORD,a2,DWORD
来源: https://www.cnblogs.com/feizianquan/p/16030399.html