MiBuildImageControlArea

INT64 __fastcall MiBuildImageControlArea(INT64 a1, INT64 a2, INT64 a3, INT64 a4, INT64 CreateSectionFlags){
  int v5; 
  INT64 v7; 
  unsigned int v8; 
  __int64 v9; 
  INT64 *v10; 
  INT64 *v11; 
  INT64 v12; 
  __int64 v13; 
  INT64 v14; 
  _QWORD *v15; 
  INT64 v16; 
  INT64 v17; 
  INT64 v18; 
  bool v19; 
  __int64 v20; 
  __int64 v21; 
  unsigned int v22; 
  unsigned int v23; 
  __int16 v24; 
  INT64 SubsectionPte; 
  unsigned int v26; 
  int v27; 
  unsigned int v28; 
  unsigned int v29; 
  BOOL v30; 
  unsigned __int64 v31; 
  __int64 v32; 
  void *v33; 
  int v34; 
  unsigned __int64 v36; 
  INT64 v37; 
  INT64 DemandZeroPte; 
  __int64 v39; 
  unsigned int *v40; 
  unsigned int v41; 
  __int64 v42; 
  unsigned int *v43; 
  BOOL v44; 
  INT64 v45; 
  bool v46; 
  UINT64 v47; 
  unsigned int v48; 
  INT64 v49; 
  INT64 *v50; 
  RTL_BALANCED_NODE *Node; 
  unsigned int v54; 
  unsigned int v55; 
  _DWORD *v56; 
  INT64 **v57; 
  v5 = a1;
  v48 = *(unsigned __int16 *)(a4 + 2);
  v7 = a3;
  v54 = (*(_DWORD *)(a3 + 16) >> 12) + ((*(_DWORD *)(a3 + 16) & 0xFFF) != 0);
  if( !v54 )
    return 3221225595i64;
  v8 = CreateSectionFlags;
  v9 = 1i64;
  if( (CreateSectionFlags & 0x200000) == 0 )
    v9 = (unsigned int)*(unsigned __int16 *)(a4 + 2) + 1;
  LODWORD(v10) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
  v50 = v10;
  v11 = v10;
  if( !v10 )
  {
    dword_140C4C958 = 26;
    return 3221225626i64;
  }
  v12 = (INT64)(v10 + 16);
  v13 = (__int64)&v10[7 * v9 + 16];
  v10[12] = v13;
  Node = (RTL_BALANCED_NODE *)v13;
  *(_QWORD *)(v13 + 24) = *(_QWORD *)(v13 + 24) & 0xFFFFFFFFFFFFFFF8ui64 | 2;
  LODWORD(v14) = MiAllocatePool((struct _SLIST_ENTRY *)0x112);
  v15 = (_QWORD *)v14;
  if( !v14 )
  {
    dword_140C4C958 = 27;
    v34 = -1073741670;
    goto LABEL_37;
  }
  memset(v14, 0i64);
  LODWORD(v16) = MiAllocatePool((struct _SLIST_ENTRY *)0x100);
  v49 = v16;
  v17 = v16;
  if( !v16 )
  {
    dword_140C4C958 = 28;
    v34 = -1073741670;
    v33 = 0i64;
    goto LABEL_33;
  }
  *(_QWORD *)(v16 + 40) = 0i64;
  v18 = v16 + 72;
  *(_QWORD *)(v16 + 64) = v15;
  *(_QWORD *)v16 = v11;
  *(_DWORD *)(v16 + 8) = v54;
  *(_QWORD *)(v16 + 56) = v16 + 72;
  *(_QWORD *)(v16 + 24) = (unsigned __int64)v54 << 12;
  *(_DWORD *)(v16 + 136) = *(_DWORD *)(v7 + 24);
  *(_DWORD *)(v16 + 140) = *(_DWORD *)(v7 + 16);
  *(_DWORD *)(v16 + 144) = *(_DWORD *)(a4 + 4);
  *(_DWORD *)(v16 + 128) = *v56;
  *(_QWORD *)(v16 + 72) = *(_QWORD *)v7 + *(unsigned int *)(v7 + 28);
  *(_QWORD *)(v16 + 88) = *(_QWORD *)(v7 + 32);
  *(_QWORD *)(v16 + 96) = *(_QWORD *)(v7 + 40);
  *(_DWORD *)(v16 + 104) = *(unsigned __int16 *)(v7 + 50);
  *(_WORD *)(v16 + 110) = *(_WORD *)(v7 + 52);
  *(_WORD *)(v16 + 108) = *(_WORD *)(v7 + 54);
  *(_WORD *)(v16 + 112) = *(_WORD *)(v7 + 56);
  *(_WORD *)(v16 + 114) = *(_WORD *)(v7 + 58);
  *(_WORD *)(v16 + 118) = *(_WORD *)(v7 + 60);
  *(_DWORD *)(v16 + 132) = *(_DWORD *)(v7 + 64);
  v19 = *(_DWORD *)(v7 + 68) || *(_DWORD *)(v7 + 28);
  *(_BYTE *)(v17 + 122) = v19;
  *(_WORD *)(v17 + 116) = *(_WORD *)(a4 + 18);
  *(_WORD *)(v17 + 120) = *(_WORD *)a4;
  *(_DWORD *)(v17 + 124) = *(_DWORD *)(v7 + 20);
  v11[2] = (INT64)(v11 + 1);
  v11[1] = (INT64)(v11 + 1);
  *v11 = v17;
  v11[14] = 1i64;
  v11[3] = 1i64;
  if( (CreateSectionFlags & 1) == 0 )
    v11[6] = 1i64;
  *((_DWORD *)v11 + 22) = -1;
  v11[13] = 0i64;
  *((_DWORD *)v11 + 14) = *((_DWORD *)v11 + 14) ^ (*((_DWORD *)v11 + 14) ^ (v5 << 20)) & 0x3F00000 | 0xA2;
  *(_BYTE *)(v17 + 14) = *(_BYTE *)(v17 + 14) & 0x7F | (*(_DWORD *)(v7 + 104) != 0 ? 0x80 : 0);
  *(_QWORD *)v12 = v11;
  *(_QWORD *)(v17 + 32) = *(_QWORD *)v7;
  *(_QWORD *)(v12 + 8) = v15;
  if( (CreateSectionFlags & 0x200000) == 0 )
  {
    v20 = *(unsigned int *)(v7 + 24);
    if( (_DWORD)v20 )
    {
      v21 = *(unsigned int *)(v7 + 12);
      v22 = v20 + v21 - 1;
      if( v22 <= (unsigned int)v20 )
      {
        dword_140C4C958 = 30;
      }
      else
      {
        v23 = (((v22 & -(int)v21 & 0xFFF) + 4095) >> 12)
            + (((unsigned __int64)~(v21 - 1) >> 12) & ((unsigned __int64)(v21 + v20 - 1) >> 12));
        *(_DWORD *)(v12 + 44) = v23;
        if( v23 <= v54 )
        {
          *(_DWORD *)(v12 + 40) = *(_DWORD *)(v7 + 24) >> 9;
          v55 = v54 - v23;
          v24 = *(_WORD *)(v12 + 32);
          *(_WORD *)(v12 + 34) = *(_WORD *)(v12 + 34) & 0xF | (16 * (*(_WORD *)(v7 + 24) & 0x1FF));
          *(_WORD *)(v12 + 32) = v24 & 0xFFC1 | 2;
          SubsectionPte = MiMakeSubsectionPte(v12);
          if( v27 )
          {
            v28 = 0;
            v29 = 0;
            do
            {
              v30 = MiPteInShadowRange((UINT64)v15);
              if( v29 >= *(_DWORD *)(v7 + 24) )
              {
                v36 = ZeroPte;
                if( v30
                  && (*(_DWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 2172i64) & 0x1000) != 0
                  && (ZeroPte & 1) != 0 )
                {
                  v36 = ZeroPte | 0x8000000000000000ui64;
                }
                *v15 = v36;
                *(_DWORD *)(v12 + 52) ^= (*(_DWORD *)(v12 + 52) ^ (*(_DWORD *)(v12 + 52) + 1)) & 0x3FFFFFFF;
              }
              else
              {
                v31 = SubsectionPte;
                if( v30
                  && (*(_DWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 2172i64) & 0x1000) != 0
                  && (SubsectionPte & 1) != 0 )
                {
                  v31 = SubsectionPte | 0x8000000000000000ui64;
                }
                *v15 = v31;
              }
              v32 = *(unsigned int *)(v12 + 44);
              v29 += 4096;
              ++v15;
              ++v28;
            }
            while( v28 < (unsigned int)v32 );
            v8 = CreateSectionFlags;
            v11 = v50;
            v26 = v55;
          }
          else
          {
            v32 = *(unsigned int *)(v12 + 44);
          }
          v33 = (void *)v49;
          v15 -= v32;
          goto LABEL_23;
        }
        dword_140C4C958 = 31;
      }
      v33 = (void *)v49;
      v34 = -1073741701;
    }
    else
    {
      dword_140C4C958 = 29;
      v34 = -1073741701;
      v33 = (void *)v17;
    }
    goto LABEL_33;
  }
  *(_DWORD *)(v12 + 44) = v54;
  *(_DWORD *)(v12 + 40) = *(__int64 *)v56 >> 9;
  *(_WORD *)(v12 + 34) = *(_WORD *)(v12 + 34) & 0xF | (16 * (*(_WORD *)v56 & 0x1FF));
  *(_BYTE *)(v18 + 51) |= 8u;
  *(_BYTE *)(v18 + 50) = 1;
  *(_WORD *)(v12 + 32) = *(_WORD *)(v12 + 32) & 0xFFC1 | 0xE;
  v37 = MiMakeSubsectionPte(v12);
  DemandZeroPte = MiMakeDemandZeroPte(7);
  if( !v26 )
    goto LABEL_51;
  v41 = 0;
  v42 = v39;
  v43 = v40;
  do
  {
    v44 = MiPteInShadowRange((UINT64)v15);
    if( v41 >= *v43 )
    {
      v45 = DemandZeroPte;
      if( !v44 || (*(_DWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 2172i64) & 0x1000) == 0 )
        goto LABEL_49;
      v46 = (DemandZeroPte & 1) == 0;
    }
    else
    {
      v45 = v37;
      if( !v44 || (*(_DWORD *)(*((_QWORD *)KeGetCurrentThread() + 23) + 2172i64) & 0x1000) == 0 )
        goto LABEL_49;
      v46 = (v37 & 1) == 0;
    }
    if( !v46 )
      v45 |= 0x8000000000000000ui64;
LABEL_49:
    *v15 = v45;
    v41 += 4096;
    ++v15;
    --v42;
  }
  while( v42 );
  v26 = v54;
  v8 = CreateSectionFlags;
  v11 = v50;
  v7 = a3;
  v39 = v54;
LABEL_51:
  v33 = (void *)v49;
  v15 -= v39;
  *(_QWORD *)(v49 + 48) = v39;
LABEL_23:
  LODWORD(v47) = v26;
  v34 = MiParseImageSectionHeaders(v8, v11, a2, v48, v7, v47);
  if( v34 >= 0 )
  {
    MiUpdateSystemProtoPtesTree(Node, 1i64);
    *v57 = v11;
    return 0i64;
  }
LABEL_33:
  if( v15 )
    ExFreePoolWithTag(v15, 0);
  if( v33 )
    ExFreePoolWithTag(v33, 0);
LABEL_37:
  ExFreePoolWithTag(v11, 0);
  return(unsigned int)v34;
}

Referenced by:

MiCreateImageFileMap