MiConstructLoaderEntry

NTSTATUS __stdcall MiConstructLoaderEntry(
        _KLDR_DATA_TABLE_ENTRY *TempDataTableEntry,
        _UNICODE_STRING *BaseName,
        _UNICODE_STRING *PrefixedImageName,
        UINT64 LoadFlags,
        UINT64 SharePages,
        _KLDR_DATA_TABLE_ENTRY **NewDataTableEntry){
  char v9; 
  UINT64 v10; 
  _KLDR_DATA_TABLE_ENTRY *v11; 
  _WORD *Pool; 
  _WORD *v13; 
  UINT64 DllBase; 
  __int64 v15; 
  int v16; 
  __int64 v17; 
  unsigned __int64 v18; 
  size_t *v19; 
  unsigned int v20; 
  unsigned int v21; 
  __int64 v22; 
  __int64 v23; 
  unsigned __int64 v24; 
  unsigned __int64 v25; 
  UINT64 v26; 
  _KLDR_DATA_TABLE_ENTRY *v27; 
  _SECTION *SectionPointer; 
  _CONTROL_AREA *v29; 
  char *v30; 
  char *v31; 
  char *v32; 
  bool v33; 
  int v34; 
  _CONTROL_AREA *v35; 
  __int16 v36; 
  unsigned __int64 TotalNumberOfPtes; 
  VOID *SectionInfo; 
  __int64 v40; 
  unsigned __int64 v41; 
  unsigned int v42; 
  unsigned int v43; 
  UINT64 v44; 
  unsigned __int64 v45; 
  unsigned int v46; 
  int v47; 
  unsigned __int64 v48; 
  unsigned int v49; 
  __int64 v50; 
  size_t *v51; 
  __int64 v52; 
  size_t v53; 
  unsigned int v54; 
  __int64 v55; 
  unsigned __int128 v56; 
  unsigned __int64 v57; 
  NTSTATUS v58; 
  __int64 v59; 
  unsigned int v60; 
  int v61; 
  __int64 v62; 
  __int64 v63; 
  __int64 v64; 
  __int128 v65; 
  char *v66; 
  _SECTION *Section; 
  __int64 v68[27]; 
  UINT64 CoverageSectionSize; 
  int v72; 

  v72 = LoadFlags;
  v9 = LoadFlags;
  memset(&v68[1], 0i64, 0x88u);
  v10 = PrefixedImageName->Length + 2i64;
  v59 = 0i64;
  *NewDataTableEntry = 0i64;
  v11 = 0i64;
  DWORD1(v65) = 0;
  Pool = MiAllocatePool(256i64, v10, 0x54446D4Dui64);
  *((_QWORD *)&v65 + 1) = Pool;
  v13 = Pool;
  if( !Pool )
    return -1073741670;
  LOWORD(v65) = PrefixedImageName->Length;
  WORD1(v65) = PrefixedImageName->Length;
  memmove(Pool, PrefixedImageName->Buffer, PrefixedImageName->Length);
  v13[(unsigned __int64)PrefixedImageName->Length >> 1] = 0;
  DllBase = (UINT64)TempDataTableEntry->DllBase;
  LODWORD(v15) = RtlImageNtHeader(DllBase);
  v16 = v9 & 1;
  v17 = v15;
  v61 = v16;
  if( (v9 & 1) != 0 )
  {
    LODWORD(v18) = 0;
    LODWORD(CoverageSectionSize) = 0;
  }
  else
  {
    v18 = *(unsigned __int16 *)(v15 + 6);
    LODWORD(CoverageSectionSize) = *(unsigned __int16 *)(v15 + 6);
    if( 0xFFFFFFFFFFFFFFFFui64 / v18 < 4 )
    {
      v58 = -1073741520;
      goto LABEL_78;
    }
  }
  v64 = 0i64;
  v19 = 0i64;
  v20 = 0;
  if( v16 )
  {
    v20 = 32;
    if( *(_DWORD *)(v15 + 132) > 6u )
    {
      v40 = *(unsigned int *)(v15 + 184);
      v64 = v17 + 184;
      if( (_DWORD)v40 )
      {
        v41 = *(unsigned int *)(v17 + 188);
        if( (_DWORD)v41 )
        {
          if( (int)v41 + (int)v40 > (unsigned int)v40 )
          {
            v42 = *(_DWORD *)(v17 + 80);
            if( (int)v41 + (int)v40 < v42 )
            {
              v20 = v41 + 32;
              v43 = 0;
              v44 = DllBase + v40;
              v45 = v41 / 0x1C;
              if( v45 )
              {
                do
                {
                  v46 = *(_DWORD *)(v44 + 20);
                  if( v46 )
                  {
                    if( v46 < v42 )
                    {
                      v47 = *(_DWORD *)(v44 + 16);
                      if( v47 + v46 < v42 )
                        v20 += v47;
                    }
                  }
                  ++v43;
                  v44 += 28i64;
                }
                while( v43 < v45 );
              }
              v19 = (size_t *)(-28i64 * v43 + v44);
            }
          }
        }
      }
      v20 = (v20 + 7) & 0xFFFFFFF8;
    }
  }
  v21 = (*(_DWORD *)(v17 + 80) >> 12) + ((*(_DWORD *)(v17 + 80) & 0xFFF) != 0);
  v22 = 8 * ((v21 >> 6) + ((v21 & 0x3F) != 0) + 2);
  v23 = (unsigned int)v22;
  v24 = v22 + 306;
  v62 = v23;
  if( v24 <= 0x132 )
    goto LABEL_76;
  if( v20 )
  {
    if( v24 + v20 <= v24 )
      goto LABEL_76;
    v24 += v20;
  }
  v25 = (BaseName->Length + 7i64) & 0xFFFFFFFFFFFFFFF8ui64;
  v26 = v24 + v25;
  if( v24 + v25 <= v24 )
  {
LABEL_76:
    v58 = -1073741701;
    goto LABEL_78;
  }
  if( (_DWORD)v18 )
  {
    if( v26 + 4i64 * (unsigned int)v18 > v26 )
    {
      v26 += 4i64 * (unsigned int)v18;
      goto LABEL_11;
    }
    goto LABEL_76;
  }
LABEL_11:
  v66 = (char *)MiAllocatePool(64i64, v26, 0x644C6D4Dui64);
  v11 = (_KLDR_DATA_TABLE_ENTRY *)v66;
  if( !v66 )
    goto LABEL_77;
  v27 = TempDataTableEntry;
  SectionPointer = (_SECTION *)TempDataTableEntry->SectionPointer;
  Section = SectionPointer;
  if( !SectionPointer )
    goto LABEL_15;
  v29 = MiSectionControlArea(SectionPointer);
  v59 = (v29->Segment->TotalNumberOfPtes >> 12) + ((v29->Segment->TotalNumberOfPtes & 0xFFF) != 0);
  if( MiChargeResident((ULONG_PTR *)&Irp.Core.PartitionId, (unsigned int)v59, 0i64) == MiChargeFailed )
  {
LABEL_77:
    v58 = -1073741670;
LABEL_78:
    ExFreePoolWithTag(v13, 0);
    if( v11 )
      ExFreePoolWithTag(v11, 0);
    return v58;
  }
  v27 = TempDataTableEntry;
LABEL_15:
  v30 = v66 + 160;
  *((_QWORD *)v66 + 33) = 0i64;
  v31 = &v66[v62 + 304];
  v32 = &v31[v20];
  *((_QWORD *)v66 + 34) = v66 + 304;
  v33 = (_DWORD)CoverageSectionSize == 0;
  *((_QWORD *)v66 + 32) = v31;
  *((_QWORD *)v66 + 27) = v59;
  if( !v33 )
    *((_QWORD *)v66 + 28) = &v32[v25];
  *(_LIST_ENTRY *)v66 = v27->InLoadOrderLinks;
  *((_OWORD *)v66 + 1) = *(_OWORD *)&v27->ExceptionTable;
  *((_OWORD *)v66 + 2) = *(_OWORD *)&v27->GpValue;
  *((_OWORD *)v66 + 3) = *(_OWORD *)&v27->DllBase;
  *((_OWORD *)v66 + 4) = *(_OWORD *)&v27->SizeOfImage;
  *((_OWORD *)v66 + 5) = *(_OWORD *)&v27->FullDllName.Buffer;
  *((_OWORD *)v66 + 6) = *(_OWORD *)&v27->BaseDllName.Buffer;
  *((_OWORD *)v66 + 7) = *(_OWORD *)&v27->SectionPointer;
  *((_OWORD *)v66 + 8) = *(_OWORD *)&v27->CoverageSection;
  *((_OWORD *)v66 + 9) = *(_OWORD *)&v27->Spare;
  if( *(_WORD *)(v17 + 64) >= 5u && *(_WORD *)(v17 + 68) >= 5u )
    *((_DWORD *)v66 + 26) |= 0x8000000u;
  if( (*(_BYTE *)(v17 + 94) & 0x80) != 0 )
    *((_DWORD *)v66 + 26) |= 0x20u;
  *((_QWORD *)v66 + 12) = v32;
  *((_WORD *)v66 + 44) = BaseName->Length;
  *((_WORD *)v66 + 45) = BaseName->Length;
  memmove(v32, BaseName->Buffer, BaseName->Length);
  v34 = v61;
  *(_WORD *)(*((_QWORD *)v66 + 12) + 2 * ((unsigned __int64)BaseName->Length >> 1)) = 0;
  *((_QWORD *)v66 + 5) = 0i64;
  *(_OWORD *)(v66 + 72) = v65;
  if( v61 )
  {
    *((_DWORD *)v66 + 26) |= 0x20000000u;
    *((_QWORD *)v66 + 5) = v31;
    *(_DWORD *)v31 = 84302;
    *((_DWORD *)v31 + 1) = v20;
    *((_WORD *)v31 + 4) = *(_WORD *)(v17 + 4);
    *((_WORD *)v31 + 5) = *(_WORD *)(v17 + 22);
    *((_DWORD *)v31 + 3) = *(_DWORD *)(v17 + 8);
    *((_DWORD *)v31 + 4) = *(_DWORD *)(v17 + 88);
    *((_DWORD *)v31 + 5) = *(_DWORD *)(v17 + 80);
    *((_QWORD *)v31 + 3) = DllBase;
    if( v19 )
    {
      memmove(v31 + 32, v19, *(_DWORD *)(v64 + 4));
      v48 = *(unsigned int *)(v64 + 4);
      v60 = 0;
      v49 = 0;
      if( v48 / 0x1C )
      {
        v50 = 0i64;
        v63 = 0i64;
        v51 = v19 + 4;
        do
        {
          v52 = v51[1];
          v53 = *v51;
          LODWORD(CoverageSectionSize) = v48;
          if( (_DWORD)v52
            && (v54 = *(_DWORD *)(v17 + 80), (unsigned int)v52 < v54)
            && (unsigned int)v52 + v53 > (unsigned int)v52
            && (unsigned int)v52 + v53 < v54 )
          {
            memmove(&v31[(unsigned int)v48 + 32], (const VOID *)(DllBase + v52), v53);
            v50 = v63;
            LODWORD(v48) = v53 + v48;
            v49 = v60;
          }
          else
          {
            LODWORD(CoverageSectionSize) = 0;
          }
          ++v49;
          v55 = 28 * v50;
          v50 = v49;
          v51 += 7;
          v60 = v49;
          v63 = v49;
          *(_DWORD *)&v31[v55 + 52] = CoverageSectionSize;
          v56 = *(unsigned int *)(v64 + 4) * (unsigned __int128)0x2492492492492493ui64;
        }
        while( v49 < (*((_QWORD *)&v56 + 1)
                     + (((unsigned __int64)*(unsigned int *)(v64 + 4) - *((_QWORD *)&v56 + 1)) >> 1)) >> 4 );
        v11 = (_KLDR_DATA_TABLE_ENTRY *)v66;
        v34 = v61;
        v30 = v66 + 160;
      }
    }
  }
  v11->EntryPoint = (void *)(DllBase + *(unsigned int *)(v17 + 40));
  v11->CheckSum = *(_DWORD *)(v17 + 88);
  if( Section )
  {
    v35 = MiSectionControlArea(Section);
    v36 = v11->u1._bf_0 & 0xFFF0 | (v35->Segment->SegmentFlags.UChar2 >> 4);
    v11->u1._bf_0 = v36;
    v11->u1._bf_0 = v36 & 0xFF8F | (16 * ((v35->Segment->SegmentFlags.UChar2 >> 1) & 7));
  }
  else
  {
    v35 = 0i64;
  }
  v11->SizeOfImageNotRounded = *(_DWORD *)(v17 + 80);
  v11->TimeDateStamp = *(_DWORD *)(v17 + 8);
  MiCaptureImageExceptionValues(v11);
  MiLockdownSections(v11);
  if( Section )
    TotalNumberOfPtes = v35->Segment->TotalNumberOfPtes;
  else
    TotalNumberOfPtes = (unsigned __int64)v11->SizeOfImage >> 12;
  if( v34 )
    goto LABEL_30;
  *((_QWORD *)v30 + 5) = TotalNumberOfPtes;
  *((_QWORD *)v30 + 6) = TotalNumberOfPtes;
  if( DllBase == PsNtosImageBase )
    goto LABEL_70;
  if( (PVOID)DllBase == PsHalImageBase )
  {
    if( DllBase != PsNtosImageBase )
    {
      v57 = TotalNumberOfPtes - MxHalFreedGapCharges;
      goto LABEL_71;
    }
LABEL_70:
    v57 = TotalNumberOfPtes - MxKernelFreedGapCharges;
LABEL_71:
    *((_QWORD *)v30 + 5) = v57;
  }
LABEL_30:
  if( !(_DWORD)SharePages )
    *((_DWORD *)v30 + 9) |= 1u;
  if( (dword_140CFA174 & 1) != 0 || (v72 & 2) != 0 )
    *((_DWORD *)v30 + 9) |= 0x10u;
  v11->CoverageSection = 0i64;
  LODWORD(CoverageSectionSize) = 0;
  if( ExCovMaxPagedPoolToUse )
  {
    SectionInfo = ExpCovGetSectionInfo(v11->DllBase, &CoverageSectionSize);
    if( SectionInfo )
    {
      v11->CoverageSectionSize = CoverageSectionSize;
      v11->CoverageSection = SectionInfo;
      DbgPrintEx(0x7Eu, 2u, (PCSTR)&stru_1407D9AB0._R13, v11);
      ExCovReadjustUnloadedModuleEntry(v11, 1);
    }
  }
  MiProcessLoaderEntry(v11, 1ui64);
  if( !v34 )
  {
    if( Section )
    {
      *((_DWORD *)v30 + 8) = -2;
      *((_QWORD *)v30 + 2) = DllBase | 3;
      *((_QWORD *)v30 + 3) = (TotalNumberOfPtes << 12) + DllBase - 1;
      v68[0] = (__int64)v35;
      MiManageSubsectionView(v68, v30, 3i64);
    }
  }
  *NewDataTableEntry = v11;
  return 0;
}

Referenced by:

MiApplyHotPatchToLoadedDriver
MiInitializeLoadedModuleList
MmLoadSystemImageEx