RtlApplyHotPatch

INT64 __fastcall RtlApplyHotPatch(
        INT64 a1,
        INT64 a2,
        INT64 a3,
        INT64 a4,
        INT64 a5,
        INT64 a6,
        INT64 a7,
        INT64 a8,
        INT64 a9,
        INT64 a10,
        INT64 a11,
        INT64 a12,
        INT64 a13,
        INT64 a14,
        INT64 a15,
        RTL_BITMAP *BitMapHeader,
        INT64 a17,
        INT64 a18,
        INT64 a19,
        INT64 a20,
        INT64 a21){
  __int128 *v21; 
  unsigned int *v22; 
  INT64 v23; 
  INT64 v24; 
  RTL_BITMAP *v25; 
  int HotPatchSize; 
  __int128 *v27; 
  INT64 v28; 
  INT64 v29; 
  int v30; 
  int v31; 
  INT64 v32; 
  int v33; 
  unsigned int v34; 
  int v35; 
  __int64(__fastcall *v36)(__int64, _QWORD, _QWORD, INT64 *); 
  INT64 result; 
  unsigned __int64 v38; 
  _QWORD *v39; 
  BYTE *v40; 
  _QWORD *v41; 
  _WORD *v42; 
  __int64 v43; 
  _DWORD *v44; 
  INT64 v45; 
  _QWORD *v46; 
  int v47; 
  __int64 v48; 
  int v49; 
  ULONG i; 
  unsigned int v51; 
  ULONG ClearBitsAndSet; 
  INT64 v53; 
  __int64 v54; 
  INT64 v55; 
  int v56; 
  __int128 *v57; 
  __int128 v58; 
  __int64 v59; 
  int v63; 
  v63 = a4;
  LODWORD(a20) = 0;
  LODWORD(a19) = 0;
  v54 = 0i64;
  a21 = 0i64;
  LODWORD(a7) = 0;
  v56 = 0;
  v21 = &v58;
  v55 = 0i64;
  v22 = (unsigned int *)a14;
  v23 = a1;
  v24 = a17;
  v25 = BitMapHeader;
  v59 = 0i64;
  LOBYTE(a6) = 0;
  v58 = 0i64;
  if( a18 )
    v21 = (__int128 *)a18;
  v57 = v21;
  v53 = 0i64;
  if( !a14 )
    goto LABEL_46;
  HotPatchSize = RtlGetHotPatchSize((_DWORD *)a13);
  LODWORD(a18) = HotPatchSize;
  while( 1 )
  {
    v31 = *v22;
    if( !*v22 )
      break;
    v32 = 0i64;
    LOBYTE(v33) = 0;
    if( v31 < 0 )
    {
      if( (a15 & 2) != 0 )
      {
        v28 = v23;
        v32 = a8;
        v54 = *((_QWORD *)v27 + 2);
        a21 = a10;
        LODWORD(a7) = a11;
        v56 = a9;
        v53 = v23;
        v55 = v29;
      }
    }
    else
    {
      v33 = a15 & 1;
      if( (a15 & 1) != 0 )
      {
        v28 = a8;
        v54 = *((_QWORD *)v27 + 1);
        a21 = a3;
        v55 = a9;
        LODWORD(a7) = v30;
        v56 = v29;
        v53 = a8;
      }
      HotPatchSize = a18;
      v32 = v23 & -(__int64)(v33 != 0);
    }
    ++v22;
    v34 = v31 & 0xFC000;
    v35 = v31 & 0xFFF;
    if( !v32 )
    {
      v22 += (unsigned int)(v35 * HotPatchSize);
      goto LABEL_42;
    }
    if( v35 )
    {
      while( 1 )
      {
        if( *(_QWORD *)v27 )
        {
          RtlpDetermineHotPatchExtent(v34, &a19, &a20);
          result = v36(v54, (unsigned int)a19 + *v22, (unsigned int)a20, &a6);
          if( (int)result < 0 )
            return result;
          if( !(_BYTE)a6 )
            goto LABEL_40;
          v28 = v53;
        }
        v38 = v22[1];
        v39 = (_QWORD *)(v32 + *v22);
        switch( v34 )
        {
          case 0x1C000u:
            v40 = 0i64;
            if( (_DWORD)a18 != 2 )
              v40 = (BYTE *)(v22 + 2);
            v41 = (_QWORD *)RtlpCheckFunctionPatchAppliedInOriginalImage((BYTE *)(v32 + *v22), v40);
            if( v41 == (_QWORD *)-1i64 )
              return 3221225496i64;
            if( v41 )
            {
              v45 = ((__int64)v41 - a21) >> 3;
              *v41 = v43;
            }
            else
            {
              v45 = (unsigned int)*v44;
              if( (unsigned int)v45 >= (unsigned int)a7 )
                return 3221226668i64;
              v46 = (_QWORD *)(a21 + 8 * v45);
              *v46 = v43;
              v47 = v56 + (_DWORD)v46 - v32;
              if( v24 && (_BYTE)v33 )
              {
                v48 = 3 * v45;
                *(_DWORD *)(v24 + 2 * v48) = *v22;
                *(_WORD *)(v24 + 2 * v48 + 4) = *v42;
              }
              v49 = v56 + *v22;
              *(v42 - 3) = 9727;
              *v42 = -1813;
              *((_DWORD *)v42 - 1) = v47 - v49;
              ++*v44;
            }
            if( v25 && (_BYTE)v33 )
              _bittestandset((signed __int32 *)v25->Buffer, v45);
            break;
          case 0x2C000u:
            *v39 = v38 + v55;
            break;
          case 0x5C000u:
            *v39 = *(_QWORD *)(v38 + v28);
            break;
          default:
            if( v34 == 491520 && *(_BYTE *)v38 == 0xFF )
              *v39 += *(_QWORD *)(8 * v38);
            break;
        }
LABEL_40:
        --v35;
        v27 = v57;
        v28 = v53;
        v22 += (unsigned int)a18;
        if( !v35 )
        {
          v29 = a2;
          v30 = v63;
          break;
        }
      }
    }
LABEL_42:
    v23 = a1;
    if( !v22 )
      break;
    HotPatchSize = a18;
  }
LABEL_46:
  if( v25 )
  {
    for( i = 0; ; i = ClearBitsAndSet )
    {
      ClearBitsAndSet = RtlFindClearBitsAndSet(v25, 1u, i);
      if( ClearBitsAndSet == -1 )
        break;
      v51 = *(_DWORD *)(v24 + 6i64 * ClearBitsAndSet);
      if( v51 )
      {
        *(_WORD *)(v51 + v23) = *(_WORD *)(v24 + 6i64 * ClearBitsAndSet + 4);
        *(_DWORD *)(v24 + 6i64 * ClearBitsAndSet) = 0;
      }
    }
  }
  return 0i64;
}

Referenced by:

MiApplyDriverHotPatch
MiApplyImageHotPatch
MiApplyImageHotPatchDpc
MiPerformImageHotPatch