PopGetNextTable

INT64 __fastcall PopGetNextTable(INT64 a1, INT64 a2, INT64 a3, INT64 a4, CHAR a5, UINT64 a6){
  unsigned __int64 *v7; 
  INT64 v8; 
  INT64 v9; 
  unsigned __int16 v10; 
  unsigned int v11; 
  INT64 v12; 
  unsigned int i; 
  __int64 v14; 
  unsigned int v15; 
  unsigned int v16; 
  unsigned int v17; 
  __int64 v18; 
  _DWORD *v19; 
  _DWORD *v20; 
  __int64 v21; 
  __int64 v22; 
  unsigned int j; 
  bool v24; 
  INT64 v25; 
  _DWORD *v27; 
  unsigned int v28; 
  __int64 v29; 
  unsigned int v30; 
  __int64 v31; 
  unsigned int v32; 
  __int64 v33; 
  __int64 v34; 
  unsigned int v35; 
  PHYSICAL_ADDRESS PhysicalAddress; 
  unsigned __int16 v37; 
  _BYTE *v38; 
  BOOL v41; 
  v38 = (_BYTE *)a2;
  v7 = (unsigned __int64 *)(a4 + 48);
  v8 = a4;
  *(_DWORD *)a2 = 0;
  v9 = a3;
  v37 = 0;
  v10 = 0;
  v41 = a5 == 0;
  v11 = 0;
  while( _InterlockedCompareExchange((volatile signed __int32 *)(a1 + 8), 1, 0) )
  {
    do
      _mm_pause();
    while( *(_DWORD *)(a1 + 8) );
  }
  v12 = a1 + 64;
  if( *(_QWORD *)(a1 + 104) != a1 + 64 )
  {
    v28 = *(_DWORD *)(a1 + 284);
    if( v28 )
    {
      do
      {
        a2 = *(_QWORD *)(a1 + 104);
        if( a2 == v12 )
          break;
        v29 = *(_QWORD *)(a1 + 112);
        v30 = v28 - v11;
        v31 = v29 + *(_QWORD *)(a2 + 24);
        v32 = *(_DWORD *)(a2 + 32) - v31;
        v33 = *(_QWORD *)(a2 + 40) + (v29 << 12);
        if( v32 > v30 )
        {
          v34 = v29 + v30;
          v32 = v30;
        }
        else
        {
          *(_QWORD *)(a1 + 104) = *(_QWORD *)a2;
          v34 = 0i64;
        }
        *(_QWORD *)(a1 + 112) = v34;
        *(_QWORD *)(v9 + 8i64 * v37++) = (16 * v31) | ((_BYTE)v32 - 1) & 0xF;
        v35 = 0;
        if( v32 )
        {
          v11 += v32;
          do
          {
            PhysicalAddress = MmGetPhysicalAddress((PVOID)(v33 + ((unsigned __int64)v35++ << 12)));
            *v7++ = (unsigned __int64)PhysicalAddress.QuadPart >> 12;
            --v32;
          }
          while( v32 );
          v9 = a3;
          v12 = a1 + 64;
        }
        v28 = *(_DWORD *)(a1 + 284);
      }
      while( v11 < v28 );
      v8 = a4;
      v10 = v37;
    }
  }
  for( i = *(_DWORD *)(a1 + 284); v11 < i; i = *(_DWORD *)(a1 + 284) )
  {
    v14 = *(_QWORD *)(a1 + 96);
    v15 = i - v11;
    v16 = *(_DWORD *)(a1 + 112);
    v17 = *(_DWORD *)v14;
    if( *(_DWORD *)v14 <= v16 )
    {
LABEL_37:
      *(_QWORD *)(a1 + 112) = **(unsigned int **)(a1 + 96);
      break;
    }
    v18 = *(_QWORD *)(v14 + 8);
    v19 = (_DWORD *)(v18 + 4 * ((unsigned __int64)(v17 - 1) >> 5));
    v20 = (_DWORD *)(v18 + 4 * ((unsigned __int64)v16 >> 5));
    if( v20 != v19 )
    {
      v21 = v16 & 0x1F;
      if( (*v20 | *((_DWORD *)qword_140011CE0 + v21)) == -1 )
      {
        v16 = v16 - v21 + 32;
        for( ++v20; v20 < v19 && *v20 == -1; ++v20 )
          v16 += 32;
      }
    }
    for( ; v16 < v17; ++v16 )
    {
      if( !_bittest(*(const signed __int32 **)(v14 + 8), v16) )
        break;
    }
    a2 = 0i64;
    if( v20 != v19 )
    {
      v22 = v16 & 0x1F;
      if( (*v20 & ~*((_DWORD *)qword_140011CE0 + v22)) == 0 )
      {
        a2 = (unsigned int)(32 - v22);
        v24 = (unsigned int)a2 <= v15;
        if( (unsigned int)a2 >= v15 )
          goto LABEL_22;
        v27 = v20 + 1;
        while( v27 < v19 && !*v27 )
        {
          ++v27;
          a2 = (unsigned int)(a2 + 32);
          v24 = (unsigned int)a2 <= v15;
          if( (unsigned int)a2 >= v15 )
            goto LABEL_22;
        }
      }
    }
    for( j = a2 + v16; j < *(_DWORD *)v14; a2 = (unsigned int)(a2 + 1) )
    {
      if( _bittest(*(const signed __int32 **)(v14 + 8), j) )
        break;
      v24 = (unsigned int)a2 <= v15;
      if( (unsigned int)a2 >= v15 )
        goto LABEL_22;
      ++j;
    }
    v24 = (unsigned int)a2 <= v15;
LABEL_22:
    if( v24 )
      v15 = a2;
    if( !v15 )
      goto LABEL_37;
    *(_QWORD *)(a1 + 112) = v15 + v16;
    v11 += v15;
    a2 = v16;
    *(_QWORD *)(a3 + 8i64 * v10++) = (16i64 * v16) | ((_BYTE)v15 - 1) & 0xF;
    do
    {
      *v7++ = a2++;
      --v15;
    }
    while( v15 );
  }
  *(_DWORD *)(a1 + 8) = 0;
  if( !v11 )
    return 0i64;
  v25 = v11;
  *v38 = v10;
  *(_QWORD *)v8 = 0i64;
  *(_WORD *)(v8 + 10) = 0;
  *(_WORD *)(v8 + 8) = 8 * (v11 + 6);
  *(_QWORD *)(v8 + 32) = 0i64;
  *(_DWORD *)(v8 + 44) = 0;
  *(_DWORD *)(v8 + 40) = v11 << 12;
  MmMapMemoryDumpMdlEx2(a6, a2, v8, v41);
  return v25;
}

Referenced by:

PopCompressHiberBlocks
PopWriteHiberImage