ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ObCreateObjectTypeEx函数逆向分析

2022-03-20 16:34:24  阅读:199  来源: 互联网

标签:__ ObCreateObjectTypeEx v19 函数 逆向 QWORD OWORD a2 DWORD


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有