MiRelocateImage

__int64 __fastcall MiRelocateImage(__int64 a1, __int64 a2, unsigned int a3, int a4, __int64 a5, int a6){
  unsigned int v10; 
  int v11; 
  __int64 v12; 
  unsigned int v13; 
  __int64 v14; 
  __int64 v15; 
  UINT64 v16; 
  char v17; 
  unsigned int v18; 
  unsigned __int64 v19; 
  __int16 v20; 
  unsigned int v21; 
  unsigned int v22; 
  __int64 v23; 
  size_t v24; 
  UINT64 v25; 
  CHAR *v26; 
  UINT64 v27; 
  CHAR *v28; 
  INT64 v29; 
  int Config; 
  UINT64 v31; 
  INT64 v32; 
  int v33; 
  unsigned __int64 v34; 
  _QWORD *v35; 
  __int64 v36; 
  unsigned int v37; 
  unsigned int v38; 
  unsigned __int64 v39; 
  unsigned int v40; 
  UINT64 v41; 
  unsigned int v42; 
  unsigned int v43; 
  unsigned int v44; 
  __int64 *v45; 
  __int64 v46; 
  INT64 v47; 
  __int64 v48; 
  __int64 v49; 
  unsigned int v50; 
  unsigned int v52; 
  unsigned int v53; 
  unsigned __int64 v54; 
  unsigned __int64 v55; 
  unsigned int v56; 
  unsigned __int16 v57; 
  _WORD *v58; 
  unsigned int v59; 
  __int64 v60; 
  unsigned int v61; 
  __int64 v62; 
  unsigned int v63; 
  unsigned int i; 
  unsigned __int64 v65; 
  int v66; 
  _QWORD *v67; 
  UINT64 v68; 
  _MI_PARTITION *ControlAreaPartition; 
  UINT64 v70; 
  volatile INT64 *v71; 
  INT64 v72; 
  unsigned int v73; 
  unsigned int v74; 
  unsigned int v75; 
  int v76; 
  INT64 v78; 
  _QWORD *v79; 
  unsigned int v80; 
  INT64 v82; 
  __int64 v83; 
  _ETHREAD *CurrentThread; 
  int v85; 
  unsigned int v86; 
  unsigned __int64 v87; 
  unsigned int v88; 
  CHAR *v89; 
  unsigned int v91; 
  size_t Size; 
  unsigned int Sizea; 
  UINT64 v94; 
  INT64 a2a; 
  UINT64 PteOffset[3]; 
  INT64 v97; 
  __int64 v98; 
  __int64 v99; 
  unsigned __int64 v100; 
  INT64 result[2]; 
  int v102; 
  memset((INT64)result, 0i64);
  v94 = 0i64;
  v10 = 2;
  v99 = *(_QWORD *)(a1 + 56);
  if( (unsigned int)MiLegacyImageArchitecture(*(_WORD *)(v99 + 48)) )
  {
    v10 = v11 + 34;
    if( (*(_BYTE *)(v12 + 44) & 1) != 0 )
      return 0i64;
    v13 = (*(_WORD *)(v12 + 46) & 0x1000) != 0 ? 0xC000007B : 0;
  }
  else
  {
    v13 = -1073741701;
  }
  v14 = *(unsigned int *)(a2 + 88);
  LODWORD(v94) = v14;
  v15 = *(unsigned int *)(a2 + 92);
  v75 = *(_DWORD *)(a2 + 92);
  HIDWORD(v94) = v75;
  if( (_DWORD)v14 )
  {
    if( !(_DWORD)v15 )
      return v13;
  }
  else
  {
    if( (_DWORD)v15 )
      return v13;
    v10 &= ~2u;
  }
  if( (*(_BYTE *)(a1 + 15) & 1) != 0 )
    return 0i64;
  v16 = *(_QWORD *)a1;
  PteOffset[2] = v16;
  v98 = *(_QWORD *)(v16 + 96);
  v17 = *(_BYTE *)(a1 + 14) & 0x40;
  if( (a3 & 0xFFF) > (v17 != 0 ? 4092 : 4088) || ((v17 != 0 ? 3 : 7) & a3) != 0 )
    return v13;
  v18 = a3 | 1;
  if( !v17 )
    v18 = a3;
  v73 = v18;
  v19 = *(_QWORD *)(a1 + 32);
  v87 = v19;
  if( v10 >= 0x20 && !a4 )
  {
    v20 = *(_WORD *)(v12 + 46);
    if( (v20 & 0x40) == 0 && MmRegistryState != -1 && (v20 & 0x1000) == 0 )
      return 0i64;
  }
  v21 = *(_DWORD *)(a1 + 8);
  v22 = v21;
  v80 = v21;
  if( (v10 & 2) == 0 )
  {
    v22 = (v18 >> 12) + 1;
    v80 = v22;
  }
  v91 = v21 << 12;
  if( (int)v15 + (int)v14 > v21 << 12 )
    return v13;
  if( (v10 & 2) != 0 )
  {
    if( (int)v15 + (int)v14 <= (unsigned int)v14 )
      return v13;
    v23 = v14;
    if( v14 + v19 <= v19 )
      return v13;
  }
  else
  {
    v23 = v14;
  }
  if( (v10 & 2) != 0 && v23 + v15 + v19 <= v19 )
    return v13;
  Size = 8i64 * v22;
  v24 = Size + v15 + 112;
  a2a = 0i64;
  v82 = 0i64;
  v76 = 0;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  LODWORD(v25) = MiAllocatePool((struct _SLIST_ENTRY *)0x100);
  v26 = (CHAR *)v25;
  PteOffset[1] = v25;
  if( !v25 )
    return 3221225626i64;
  v27 = v25;
  do
    v27 += 4096i64;
  while( v27 < v25 + v24 );
  *(_BYTE *)(v25 + 68) = 0;
  *(_QWORD *)(v25 + 56) = v80;
  *(_QWORD *)(v25 + 24) = 0i64;
  if( (v10 & 2) == 0 )
  {
    v29 = v25 + 72;
LABEL_28:
    Config = MiSelectImageBase(a1, (__int64)v26, a4, a6, &a2a);
    if( Config < 0 )
    {
      MiFreeImageLoadConfig(v29);
      ExFreePoolWithTag(v26, 0);
      if( !a4 )
        Config = v13;
      goto LABEL_70;
    }
    v31 = v29;
    v32 = a2a;
    v97 = a2a;
    MiUpdateCfgSystemWideBitmap(v16, a2a, v31);
    Config = v33;
    if( v33 < 0 )
      goto LABEL_155;
    *((_DWORD *)v26 + 16) = v73;
    *((_QWORD *)v26 + 5) = v32 - v87;
    v34 = a5 - v87;
    if( a5 == -1 )
      v34 = 0i64;
    *((_QWORD *)v26 + 6) = v34;
    v89 = v26 + 112;
    *(_QWORD *)v26 = v26 + 112;
    memset((INT64)(v26 + 112), 0i64);
    v35 = v26 + 112;
    v78 = (INT64)&v26[Size + 112];
    *((_QWORD *)v26 + 4) = v78;
    v10 |= 4u;
    if( (v10 & 2) == 0 )
    {
LABEL_56:
      v35[(unsigned __int64)*((unsigned int *)v26 + 16) >> 12] |= 1ui64;
      if( (*(_DWORD *)(v16 + 56) & 0x40000000) != 0 )
      {
        v60 = 0i64;
        v61 = 0;
        v79 = 0i64;
        v62 = *(_QWORD *)(a1 + 64);
        v83 = v62;
        v63 = *((_DWORD *)v26 + 14);
        if( v80 <= v63 )
          v63 = v80;
        for( i = 0; i < v63; v89 += 8 )
        {
          if( *v35 != v60 || MiDoesPageRequireRetpolineFixups((INT64)(v26 + 72), i) )
          {
            v65 = MI_READ_PTE_LOCK_FREE(v62 + 8i64 * i);
            v100 = v65;
            if( (v65 & 0x400) != 0 )
            {
              *((_QWORD *)v26 + 13) = 0i64;
              Config = -1073740023;
              goto LABEL_69;
            }
            v60 = 0i64;
            if( (v65 & 0x800) != 0 )
            {
              v66 = 1;
              if( qword_140C4DC80 )
              {
                if( (v65 & 0x10) != 0 )
                  v65 &= ~0x10ui64;
                else
                  v65 &= ~qword_140C4DC80;
              }
              v67 = (_QWORD *)((char *)MmGetPfnDb() + 48 * ((v65 >> 12) & 0xFFFFFFFFFi64));
              if( (v67[2] & 0x400i64) != 0 && (*(_BYTE *)(MiGetSubsectionFromPte(v67[2]) + 34) & 2) != 0 )
                v66 = v60;
              if( v66 )
              {
                MiSetLeafPfnBuddy(v67, 0i64);
                if( *((_QWORD *)v26 + 13) == v60 )
                  *((_QWORD *)v26 + 13) = v68;
                else
                  MiSetLeafPfnBuddy(v79, v68);
                v79 = (_QWORD *)v68;
                ++v61;
              }
            }
            v62 = v83;
          }
          ++i;
          v35 = v89 + 8;
        }
        ControlAreaPartition = MiGetControlAreaPartition((_CONTROL_AREA *)v16);
        v70 = v61;
        if( !(unsigned int)MiChargeCommit(ControlAreaPartition, v61, 0i64) )
        {
          *((_QWORD *)v26 + 13) = 0i64;
          Config = -1073741670;
          goto LABEL_69;
        }
        v46 = (__int64)CurrentThread;
        --*((_WORD *)CurrentThread + 243);
        v71 = (volatile INT64 *)(a1 + 40);
        ExAcquirePushLockExclusiveEx(a1 + 40, 0i64);
        MiUpdateControlAreaCommitCount(v16, v70);
        if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 40), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
          ExfTryToWakePushLock(v71);
        KeAbPostRelease((PVOID)v71);
        KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
        v47 = a2a;
      }
      else
      {
        v46 = (__int64)CurrentThread;
        v47 = v97;
      }
      LOBYTE(v10) = v10 | 8;
      MI_LOCK_RELOCATIONS_EXCLUSIVE(v46, (__int64)v26);
      v48 = v98;
      *(_QWORD *)(v98 + 32) = v26;
      *(_QWORD *)(a1 + 32) = v47;
      v49 = v99;
      *(_QWORD *)v99 += *((_QWORD *)v26 + 5);
      *(_DWORD *)(v16 + 92) |= 0x400000u;
      if( (*(_DWORD *)(v16 + 56) & 0x800) != 0 )
        MiSetDeleteOnClose((_CONTROL_AREA *)v16, 0i64);
      if( (MiFlags & 0x4000) == 0
        || (*(_DWORD *)(v16 + 92) & 0xC0000) == 0
        || (qword_140C1D940 ? (Config = qword_140C1D940(*(_QWORD *)(v48 + 40) & 0xFFFFFFFFFFFFFFF8ui64, v47)) : (Config = -1073741637),
            Config >= 0) )
      {
        Config = 0;
        v50 = a4 ? -1 : MmGetSessionIdEx(*((_QWORD *)KeGetCurrentThread() + 23));
        if( a6 != 1 || *((_QWORD *)v26 + 12) )
        {
          if( (*(_DWORD *)(v16 + 56) & 0x40000000) != 0 )
          {
            MiWalkEntireImage(v16, 0i64, 8, v50);
            if( (unsigned int)MiColdPageSizeSupported() )
              MiMakeUnusedImageExtentsCold(v16);
          }
          Config = MiWalkEntireImage(v16, 0i64, 2, v50);
        }
      }
      MI_UNLOCK_RELOCATIONS_EXCLUSIVE(v46, (__int64)v26);
      if( Config >= 0 && !a6 )
        *(_BYTE *)(v49 + 51) |= 4u;
LABEL_69:
      if( (v10 & 8) != 0 )
        goto LABEL_70;
LABEL_155:
      MiFreeRelocations((_DWORD *)v16, v26);
      goto LABEL_70;
    }
    memmove((UINT8 *)&v26[Size + 112], (UINT8 *)(v23 + v82), v75);
    LODWORD(v23) = 0;
    v36 = *((_QWORD *)v26 + 12);
    if( v36 )
    {
      LODWORD(v23) = v102 & 0xFFFFF;
      while( (_DWORD)v23 )
      {
        v23 = (unsigned int)(v23 - 1);
        if( *(_QWORD *)(v36 + 8 * v23 + 56) )
          goto LABEL_34;
      }
      LODWORD(v23) = 0;
    }
LABEL_34:
    v37 = v75;
    v38 = 0;
    if( v75 )
    {
      v39 = (unsigned __int64)&v26[Size + 112];
      while( v37 >= 0xA )
      {
        v40 = *(_DWORD *)(v39 + 4);
        v74 = v40;
        if( v40 > v37 || (v40 & 1) != 0 || v40 < 8 )
          goto LABEL_100;
        v41 = *(unsigned int *)v39;
        v85 = v41;
        v42 = v10 & 0xFFFFFFFB;
        if( (v41 & 0xFFF) == 0 )
          v42 = v10;
        v10 = v42;
        if( (int)v41 + 4096 <= (unsigned int)v41 || (int)v41 + 4096 > v91 || (unsigned int)v41 < v38 )
          goto LABEL_100;
        if( v40 == 8 )
        {
          v37 -= 8;
          v10 = v42 & 0xFFFFFFFB;
        }
        else
        {
          if( (MiFlags & 0x40000) != 0 && (*(_DWORD *)(v16 + 92) & 0xC0000) != 0 )
          {
            PteOffset[0] = 0i64;
            if( (*((_BYTE *)MiOffsetToProtos((_CONTROL_AREA *)v16, v41, PteOffset) + 32) & 4) != 0 )
            {
              Config = -1073741701;
              goto LABEL_69;
            }
            v40 = v74;
            LODWORD(v41) = v85;
            v39 = v78;
          }
          v86 = (unsigned int)v41 >> 12;
          *(_QWORD *)&v26[8 * ((unsigned __int64)(unsigned int)v41 >> 12) + 112] |= v39;
          v88 = (v41 & 0xFFFFF000) + 4096;
          Sizea = v37 - v40;
          Config = MiScanRelocationPage();
          if( Config < 0 )
          {
            if( Config == -1073741207 )
            {
              Config = 0;
            }
            else if( Config == -1073741701 )
            {
              Config = v13;
            }
            goto LABEL_69;
          }
          v10 |= 0x10u;
          v43 = v86;
          if( v86 <= (unsigned int)v23 )
            v43 = v23;
          LODWORD(v23) = v43;
          v37 = Sizea;
          v40 = v74;
          v38 = v88;
          v39 = v78;
        }
        v39 += v40;
        v78 = v39;
        if( !v37 )
        {
          v44 = v75;
          goto LABEL_53;
        }
      }
      if( v37 != 8 )
        goto LABEL_100;
      v44 = v75 - 8;
    }
    else
    {
      v44 = 0;
    }
LABEL_53:
    MiUnmapImageInSystemSpace((INT64)result);
    PsRevertToUserPagePriorityThread((__int64)CurrentThread, v76);
    LOBYTE(v10) = v10 & 0xFE;
    v45 = (__int64 *)*((_QWORD *)v26 + 2);
    if( !v45 )
    {
LABEL_54:
      MiLogRelocationFaults(v16, (UINT64)&v94);
      *((_QWORD *)v26 + 7) = (unsigned int)(v23 + 1);
      if( (v10 & 0x14) == 20 )
      {
        v26 = MiCompressRelocations((INT64)v26, v44);
        v35 = v26 + 112;
        v89 = v26 + 112;
      }
      else
      {
        v35 = v26 + 112;
      }
      goto LABEL_56;
    }
    while( 1 )
    {
      v52 = v23;
      v53 = *((_DWORD *)v45 + 3);
      v54 = *(_QWORD *)&v26[8 * ((unsigned __int64)v53 >> 12) + 112];
      LODWORD(v23) = v53 >> 12;
      if( v53 >> 12 <= v52 )
        LODWORD(v23) = v52;
      if( v54 > 1 )
      {
        v55 = v54 & 0xFFFFFFFFFFFFFFFEui64;
        v56 = *(_DWORD *)(v55 + 4) - 8;
        v57 = v53 & 0xFFF;
        v58 = (_WORD *)(v55 + 8);
        v59 = v56 >> 1;
        if( v59 )
          break;
      }
LABEL_92:
      v45 = (__int64 *)*v45;
      if( !v45 )
        goto LABEL_54;
    }
    while( *v58 < 0x1000u || (unsigned __int16)(*v58 & 0xFFF) >= v57 )
    {
      ++v58;
      if( !--v59 )
        goto LABEL_92;
    }
LABEL_100:
    Config = v13;
    goto LABEL_69;
  }
  if( MiMapImageInSystemSpace(v16, 3, (__int64)result) < 0 )
  {
    ExFreePoolWithTag(v26, 0);
    MiSetDeleteOnClose((_CONTROL_AREA *)v16, 0i64);
    return 0i64;
  }
  v28 = (CHAR *)result[0];
  v82 = result[0];
  v76 = PsSetSystemPagePriorityThread((__int64)CurrentThread, 1);
  v10 |= 1u;
  v29 = (INT64)(v26 + 72);
  Config = MiParseImageLoadConfig(v16, v28, (unsigned int)(v102 << 12), a2, v72, (INT64)(v26 + 72));
  if( Config >= 0 )
    goto LABEL_28;
  ExFreePoolWithTag(v26, 0);
LABEL_70:
  if( (v10 & 1) != 0 )
  {
    MiUnmapImageInSystemSpace((INT64)result);
    PsRevertToUserPagePriorityThread((__int64)CurrentThread, v76);
  }
  return(unsigned int)Config;
}

Referenced by:

MiGetSystemAddressForImage