1. 程式人生 > 其它 >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; } }