EtwpCovSampContextGetModule

NTSTATUS __stdcall EtwpCovSampContextGetModule(
        INT64 a1,
        INT64 a2,
        INT64 a3,
        const _UNICODE_STRING *a4,
        INT64 a5,
        INT64 *a6){
  __int64 v8; 
  VOID **v9; 
  VOID **v10; 
  __int64 v12; 
  INT64 v13; 
  __int64 v14; 
  __int64 v15; 
  _ETHREAD *CurrentThread; 
  __int64 v17; 
  unsigned int v18; 
  VOID **PoolWithTag; 
  UINT64 v20; 
  _CVDD **v21; 
  char *v22; 
  NTSTATUS v23; 
  unsigned int v24; 
  unsigned int v25; 
  INT64 v26; 
  __m128i v27; 
  INT64 v28; 
  INT64 v29; 
  NTSTATUS v30; 
  int v31; 
  int v32; 
  unsigned int v33; 
  _ETHREAD *v34; 
  VOID **v35; 
  VOID **v36; 
  __int64 v37; 
  unsigned int v38; 
  char i; 
  unsigned __int64 v40; 
  unsigned int v41; 
  __int64 v42; 
  _QWORD *v43; 
  __int64 v44; 
  char k; 
  unsigned __int64 v46; 
  __int64 v47; 
  unsigned int v48; 
  INT64 v49; 
  _QWORD *v50; 
  __int64 v51; 
  VOID **v52; 
  int v53; 
  INT64 v54; 
  __int64 v55; 
  _QWORD *n; 
  _QWORD *v57; 
  INT64 v58; 
  _QWORD *ii; 
  __int64 v60; 
  __int64 v61; 
  _QWORD *v62; 
  _QWORD *v63; 
  int v64; 
  unsigned __int64 v65; 
  __int64 v66; 
  int v67; 
  __int64 v68; 
  unsigned int v69; 
  void *v70; 
  __int64 v71; 
  __int64 v72; 
  unsigned int v74; 
  int Name; 
  __int64 v76; 
  __int128 *v77; 
  __int64 j; 
  __int64 v79; 
  __int64 v80; 
  __int64 v81; 
  VOID **v82; 
  unsigned int v83; 
  int v84; 
  _QWORD *v85; 
  unsigned int v86; 
  __int64 v87; 
  INT64 v88; 
  UINT64 ImageSize; 
  __int128 v90; 
  _UNICODE_STRING ValueName; 
  __int64 v92[3]; 
  __int128 v93; 
  int v96; 
  INT64 v97; 
  int v98; 
  INT64 m; 
  __int64 v100; 
  __int64 v101; 

  v8 = 0i64;
  v9 = 0i64;
  v82 = 0i64;
  v10 = 0i64;
  v74 = 0;
  *a6 = 0i64;
  v88 = 0i64;
  v90 = 0i64;
  ImageSize = *(_QWORD *)(a5 + 32);
  LODWORD(v12) = RtlImageNtHeader(*(_QWORD *)(a5 + 16));
  v92[2] = v12;
  if( !v12 )
  {
    Name = -1073741637;
    goto LABEL_132;
  }
  LODWORD(v90) = *(_DWORD *)(v12 + 88);
  DWORD1(v90) = *(_DWORD *)(v12 + 8);
  if( (*(_DWORD *)(a5 + 8) & 0x100) != 0 )
  {
    v13 = *(_QWORD *)(a5 + 16);
  }
  else
  {
    v14 = *(_QWORD *)(a5 + 48);
    if( !v14 )
    {
      Name = -1073741637;
      goto LABEL_132;
    }
    v13 = *(_QWORD *)(v14 + 24);
  }
  v88 = v13;
  if( (*(_DWORD *)(a1 + 8) & 0x400) != 0 )
  {
    if( *(_QWORD *)(a5 + 16) == *(_QWORD *)(a2 + 1312) )
    {
      v74 = 1;
    }
    else
    {
      v74 = 0;
      v15 = *(unsigned int *)(a3 + 40);
      v88 = v15 ^ v13;
      DWORD2(v90) = v15;
    }
  }
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --CurrentThread->Tcb.KernelApcDisable;
  ExAcquirePushLockSharedEx((_EX_PUSH_LOCK *)(a1 + 664), 0i64);
  LODWORD(v17) = EtwpCovSampContextFastFindModule(a1, (INT64)&v88, a6);
  if( v17 && v17 == *a6 )
  {
    ProcessForExeModule(a1, a3, *a6, v74);
    if( _InterlockedCompareExchange64((volatile signed __int64 *)(a1 + 664), 0i64, 17i64) != 17 )
      ExfReleasePushLockShared((_EX_PUSH_LOCK *)(a1 + 664));
    KeAbPostRelease((VOID *)(a1 + 664));
    KeLeaveCriticalRegionThread(KeGetCurrentThread());
    Name = 0;
    goto LABEL_17;
  }
  v84 = *(_DWORD *)(a1 + 684) >> 5;
  v18 = *(_DWORD *)(a1 + 680);
  if( v18 <= *(_DWORD *)(a1 + 696) )
    v18 = *(_DWORD *)(a1 + 696);
  v86 = v18;
  if( _InterlockedCompareExchange64((volatile signed __int64 *)(a1 + 664), 0i64, 17i64) != 17 )
    ExfReleasePushLockShared((_EX_PUSH_LOCK *)(a1 + 664));
  KeAbPostRelease((VOID *)(a1 + 664));
  KeLeaveCriticalRegionThread(KeGetCurrentThread());
  PoolWithTag = ExAllocatePoolWithTag(1ui64, 0xB0ui64, 1450669125i64);
  v10 = PoolWithTag;
  if( !PoolWithTag )
  {
    Name = -1073741670;
LABEL_17:
    v9 = 0i64;
    goto LABEL_132;
  }
  memset(PoolWithTag, 0i64, 0xB0u);
  v10[10] = v10 + 9;
  v10[9] = v10 + 9;
  v10[12] = v10 + 11;
  v10[11] = v10 + 11;
  *v10 = 0i64;
  v10[2] = 0i64;
  v10[8] = (VOID *)1;
  v10[1] = (VOID *)v88;
  v20 = ImageSize;
  v10[5] = (VOID *)ImageSize;
  v10[4] = (VOID *)v90;
  *((_DWORD *)v10 + 30) ^= (*((_DWORD *)v10 + 30) ^ (*(_DWORD *)(a5 + 8) << 9)) & 0x20000;
  v92[0] = 0i64;
  v92[1] = 0i64;
  v83 = 0;
  v77 = (__int128 *)v92;
  v96 = 1;
  LOBYTE(v21) = 1;
  if( EtwpFindDebugId(*(VOID **)(a5 + 16), v20, v21, (UINT64 *)v10 + 6) >= 0 )
  {
    v22 = (char *)v10[6];
    if( *((_DWORD *)v10 + 14) <= 0x400u )
    {
      v83 = *((_DWORD *)v22 + 5);
      v77 = (__int128 *)(v22 + 4);
      goto LABEL_28;
    }
    ExFreePoolWithTag(v10[6], 0);
    v10[6] = 0i64;
    *((_DWORD *)v10 + 14) = 0;
  }
  v23 = 0;
  v96 = 0;
  v24 = v74;
  if( !v74 )
  {
LABEL_39:
    if( !v23 && !v24 )
      goto LABEL_46;
    goto LABEL_41;
  }
LABEL_28:
  Name = EtwpCovSampModuleGetName((INT64)v10, a5, a4);
  if( Name < 0 )
    goto LABEL_17;
  *(_QWORD *)&ValueName.Length = v10[14];
  ValueName.Buffer = (wchar_t *)(unsigned __int16)*((_DWORD *)v10 + 30);
  if( *(_DWORD *)(a1 + 1112) )
    v23 = EtwpCovSampCheckForSegments(&ValueName, (_UNICODE_STRING *)(a1 + 792));
  else
    v23 = v96;
  if( !v23 || !*(_DWORD *)(a1 + 1116) )
    goto LABEL_38;
  if( EtwpCovSampCheckForSegments(&ValueName, (_UNICODE_STRING *)(a1 + 952)) )
  {
    v23 = 0;
LABEL_38:
    v24 = v74;
    goto LABEL_39;
  }
  v23 = 1;
LABEL_41:
  *((_DWORD *)v10 + 30) ^= (*((_DWORD *)v10 + 30) ^ (v23 << 16)) & 0x10000;
  v25 = *((_DWORD *)v10 + 10);
  LODWORD(v97) = *((_DWORD *)v10 + 9);
  HIDWORD(v97) = *((_DWORD *)v10 + 8);
  LODWORD(v26) = EtwCovSampHash(v97, *(unsigned int *)(a1 + 12));
  v93 = *v77;
  v27 = (__m128i)v93;
  LODWORD(v28) = EtwCovSampHash(__PAIR64__(v83, v25), v26);
  LODWORD(v29) = EtwCovSampHash(v27.m128i_u64[0], v28);
  v30 = EtwCovSampHash(_mm_srli_si128(v27, 8).m128i_u64[0], v29);
  v32 = v30 ^ v31;
  if( v30 == v31 )
    v32 = 1;
  if( !v74 )
    v32 ^= *(_DWORD *)(a3 + 40);
  *((_DWORD *)v10 + 31) = v32;
LABEL_46:
  v33 = 2 * v84;
  if( v86 + 1 > 2 * v84 )
  {
    v8 = v33;
    if( !v33 )
      v8 = 128i64;
    v82 = ExAllocatePoolWithTag(1ui64, 8i64 * (unsigned int)(2 * v8), 1450669125i64);
  }
  v34 = (_ETHREAD *)KeGetCurrentThread();
  --v34->Tcb.KernelApcDisable;
  ExAcquirePushLockExclusiveEx((_EX_PUSH_LOCK *)(a1 + 664), 0i64);
  *(_QWORD *)(a1 + 672) = KeGetCurrentThread();
  v35 = v82;
  if( v82 && (unsigned int)v8 > *(_DWORD *)(a1 + 684) >> 5 )
  {
    v36 = &v82[(unsigned int)v8];
    v37 = (unsigned int)v8;
    v98 = v8 & (v8 - 1);
    if( v98 )
    {
      v38 = v8;
      for( i = -1; v38; v38 >>= 1 )
        ++i;
      v37 = (unsigned int)(1 << i);
    }
    if( (unsigned int)v37 > 0x4000000 )
      v37 = 0x4000000i64;
    v40 = (unsigned __int64)(8 * v37 + 7) >> 3;
    if( v36 > &v36[v37] )
      v40 = 0i64;
    if( v40 )
      memset64(v36, (a1 + 696) | 1, v40);
    v87 = -1i64 << (*(_BYTE *)(a1 + 700) & 0x1F);
    v41 = 0;
    if( (*(_DWORD *)(a1 + 700) & 0xFFFFFFE0) != 0 )
    {
      do
      {
        v42 = *(_QWORD *)(a1 + 704);
        for( j = v42; ; v42 = j )
        {
          v43 = *(_QWORD **)(v42 + 8i64 * v41);
          v85 = v43;
          if( ((unsigned __int8)v43 & 1) != 0 )
            break;
          *(_QWORD *)(j + 8i64 * v41) = *v43;
          v79 = v87 & v43[1];
          v44 = (37
               * (BYTE6(v79)
                + 37
                * (BYTE5(v79)
                 + 37
                 * (BYTE4(v79)
                  + 37 * (BYTE3(v79) + 37 * (BYTE2(v79) + 37 * (BYTE1(v79) + 37 * ((unsigned __int8)v79 + 11623883)))))))
               + HIBYTE(v79)) & (unsigned int)(v37 - 1);
          *v85 = v36[v44];
          v36[v44] = v85;
          v35 = v82;
        }
        ++v41;
      }
      while( v41 < *(_DWORD *)(a1 + 700) >> 5 );
    }
    *(_QWORD *)(a1 + 704) = v36;
    *(_DWORD *)(a1 + 700) = (32 * v37) | *(_DWORD *)(a1 + 700) & 0x1F;
    if( v98 )
    {
      for( k = -1; (_DWORD)v8; LODWORD(v8) = (unsigned int)v8 >> 1 )
        ++k;
      v8 = (unsigned int)(1 << k);
    }
    if( (unsigned int)v8 > 0x4000000 )
      v8 = 0x4000000i64;
    v46 = (unsigned __int64)(8 * v8 + 7) >> 3;
    if( v35 > &v35[v8] )
      v46 = 0i64;
    if( v46 )
      memset64(v35, (a1 + 680) | 1, v46);
    v47 = -1i64 << (*(_BYTE *)(a1 + 684) & 0x1F);
    v48 = 0;
    if( (*(_DWORD *)(a1 + 684) & 0xFFFFFFE0) != 0 )
    {
      do
      {
        v49 = *(_QWORD *)(a1 + 688);
        for( m = v49; ; v49 = m )
        {
          v50 = *(_QWORD **)(v49 + 8i64 * v48);
          if( ((unsigned __int8)v50 & 1) != 0 )
            break;
          *(_QWORD *)(v49 + 8i64 * v48) = *v50;
          v80 = v47 & v50[1];
          v51 = (37
               * (BYTE6(v80)
                + 37
                * (BYTE5(v80)
                 + 37
                 * (BYTE4(v80)
                  + 37 * (BYTE3(v80) + 37 * (BYTE2(v80) + 37 * (BYTE1(v80) + 37 * ((unsigned __int8)v80 + 11623883)))))))
               + HIBYTE(v80)) & (unsigned int)(v8 - 1);
          *v50 = v35[v51];
          v35[v51] = v50;
        }
        ++v48;
      }
      while( v48 < *(_DWORD *)(a1 + 684) >> 5 );
    }
    v52 = *(VOID ***)(a1 + 688);
    *(_QWORD *)(a1 + 688) = v35;
    v53 = (32 * v8) | *(_DWORD *)(a1 + 684) & 0x1F;
    v54 = a1 + 680;
    *(_DWORD *)(a1 + 684) = v53;
    v82 = v52;
  }
  else
  {
    v54 = a1 + 680;
  }
  if( *(_DWORD *)(a1 + 684) >= 0x20u )
  {
    LODWORD(v55) = EtwpCovSampContextFastFindModule(a1, (INT64)&v88, a6);
    if( v55 )
    {
      if( v55 == *a6 )
      {
        ProcessForExeModule(a1, a3, *a6, v74);
LABEL_90:
        Name = 0;
        goto LABEL_86;
      }
      *(_DWORD *)(v55 + 120) |= 0x40000u;
      v100 = *(_QWORD *)(v55 + 8) & (-1i64 << (*(_DWORD *)(v54 + 4) & 0x1F));
      for( n = (_QWORD *)(*(_QWORD *)(v54 + 8)
                         + 8i64
                         * ((37
                           * (BYTE6(v100)
                            + 37
                            * (BYTE5(v100)
                             + 37
                             * (BYTE4(v100)
                              + 37
                              * (BYTE3(v100)
                               + 37 * (BYTE2(v100) + 37 * (BYTE1(v100) + 37 * ((unsigned __int8)v100 + 11623883)))))))
                           + HIBYTE(v100)) & (unsigned int)((*(_DWORD *)(v54 + 4) >> 5) - 1)));
            (*n & 1) == 0;
            n = (_QWORD *)*n )
      {
        if( *n == v55 )
        {
          *n = *(_QWORD *)v55;
          --*(_DWORD *)v54;
          break;
        }
      }
      *(_QWORD *)v55 = 0i64;
      v57 = (_QWORD *)(v55 + 16);
      v58 = a1 + 696;
      if( *(_QWORD *)(v55 + 16) )
      {
        v101 = *(_QWORD *)(v55 + 24) & (-1i64 << (*(_DWORD *)(a1 + 700) & 0x1F));
        for( ii = (_QWORD *)(*(_QWORD *)(a1 + 704)
                            + 8i64
                            * ((37
                              * (BYTE6(v101)
                               + 37
                               * (BYTE5(v101)
                                + 37
                                * (BYTE4(v101)
                                 + 37
                                 * (BYTE3(v101)
                                  + 37 * (BYTE2(v101) + 37 * (BYTE1(v101) + 37 * ((unsigned __int8)v101 + 11623883)))))))
                              + HIBYTE(v101)) & (unsigned int)((*(_DWORD *)(a1 + 700) >> 5) - 1)));
              (*ii & 1) == 0;
              ii = (_QWORD *)*ii )
        {
          if( (_QWORD *)*ii == v57 )
          {
            *ii = *v57;
            --*(_DWORD *)v58;
            break;
          }
        }
        *v57 = 0i64;
      }
    }
    else
    {
      v58 = a1 + 696;
    }
    *((_DWORD *)v10 + 30) = (_DWORD)v10[15] & 0xFFEFFFFF | (v74 << 20);
    *((_DWORD *)v10 + 32) = (*(_DWORD *)(a1 + 1120))++;
    v81 = (unsigned __int64)v10[1] & (-1i64 << (*(_DWORD *)(v54 + 4) & 0x1F));
    v60 = (37
         * (BYTE6(v81)
          + 37
          * (BYTE5(v81)
           + 37
           * (BYTE4(v81)
            + 37 * (BYTE3(v81) + 37 * (BYTE2(v81) + 37 * (BYTE1(v81) + 37 * ((unsigned __int8)v81 + 11623883)))))))
         + HIBYTE(v81)) & (unsigned int)((*(_DWORD *)(v54 + 4) >> 5) - 1);
    v61 = *(_QWORD *)(v54 + 8);
    *v10 = *(VOID **)(v61 + 8 * v60);
    *(_QWORD *)(v61 + 8 * v60) = v10;
    ++*(_DWORD *)v54;
    v62 = (_QWORD *)(a1 + 712);
    v63 = *(_QWORD **)(a1 + 712);
    if( v63[1] != a1 + 712 )
      __fastfail(3u);
    v10[9] = v63;
    v10[10] = v62;
    v63[1] = v10 + 9;
    *v62 = v10 + 9;
    *((_DWORD *)v10 + 34) = KUSER_SHARED_DATA.TickCount.LowPart;
    ++*(_DWORD *)(a1 + 728);
    ++*(_DWORD *)(a1 + 732);
    v64 = *((_DWORD *)v10 + 30);
    if( (v64 & 0x10000) != 0 || v74 )
    {
      v65 = *((unsigned int *)v10 + 31);
      v10[3] = (VOID *)v65;
      v66 = v65 & (-1i64 << (*(_BYTE *)(a1 + 700) & 0x1F));
      v67 = *(_DWORD *)(a1 + 700) >> 5;
      if( !v67 )
        goto LABEL_124;
      v68 = *(_QWORD *)(a1 + 704)
          + 8i64
          * ((37
            * (BYTE6(v66)
             + 37
             * (BYTE5(v66)
              + 37
              * (BYTE4(v66)
               + 37 * (BYTE3(v66) + 37 * (BYTE2(v66) + 37 * (BYTE1(v66) + 37 * ((unsigned __int8)v66 + 11623883)))))))
            + HIBYTE(v66)) & (unsigned int)(v67 - 1));
      while( 1 )
      {
        v68 = *(_QWORD *)v68;
        if( (v68 & 1) != 0 )
          break;
        if( v66 == ((-1i64 << (*(_BYTE *)(a1 + 700) & 0x1F)) & *(_QWORD *)(v68 + 8)) )
          goto LABEL_114;
      }
      v68 = 0i64;
LABEL_114:
      if( v68 )
      {
        if( *(_DWORD *)(v68 + 16) == *((_DWORD *)v10 + 8)
          && *(_DWORD *)(v68 + 20) == *((_DWORD *)v10 + 9)
          && *(VOID **)(v68 + 24) == v10[5]
          && EtwpCheckDebugInfoEqual(*(_QWORD *)(v68 + 32), (INT64)v10[6]) )
        {
          v69 = *((_DWORD *)v10 + 30);
        }
        else
        {
          *((_DWORD *)v10 + 31) = 0;
          v69 = v64 & 0xFFFEFFFF;
        }
        *((_DWORD *)v10 + 30) = v69 | 0x80000;
        EtwpCovSampModuleNameInfoCleanup((INT64 *)v10 + 13);
        v10[14] = 0i64;
        *((_WORD *)v10 + 60) = 0;
        v70 = v10[6];
        if( v70 )
          ExFreePoolWithTag(v70, 0);
        v10[6] = 0i64;
        *((_DWORD *)v10 + 14) = 0;
      }
      else
      {
LABEL_124:
        v76 = (unsigned __int64)v10[3] & (-1i64 << (*(_DWORD *)(v58 + 4) & 0x1F));
        v71 = (37
             * (BYTE6(v76)
              + 37
              * (BYTE5(v76)
               + 37
               * (BYTE4(v76)
                + 37 * (BYTE3(v76) + 37 * (BYTE2(v76) + 37 * (BYTE1(v76) + 37 * ((unsigned __int8)v76 + 11623883)))))))
             + HIBYTE(v76)) & (unsigned int)((*(_DWORD *)(v58 + 4) >> 5) - 1);
        v72 = *(_QWORD *)(v58 + 8);
        v10[2] = *(VOID **)(v72 + 8 * v71);
        *(_QWORD *)(v72 + 8 * v71) = v10 + 2;
        ++*(_DWORD *)v58;
      }
      if( (*(_DWORD *)(a1 + 8) & 0x400) != 0 )
      {
        ProcessForExeModule(a1, a3, (INT64)v10, v74);
        *((_DWORD *)v10 + 40) = *(_DWORD *)(a3 + 40);
        *((_DWORD *)v10 + 41) = *(_DWORD *)(a3 + 44);
      }
    }
    if( _InterlockedIncrement64((volatile signed __int64 *)v10 + 8) <= 1 )
      __fastfail(0xEu);
    *a6 = (INT64)v10;
    v10 = 0i64;
    *(_QWORD *)(a1 + 672) = 0i64;
    if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 664), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((_EX_PUSH_LOCK *)(a1 + 664));
    KeAbPostRelease((VOID *)(a1 + 664));
    KeLeaveCriticalRegionThread(KeGetCurrentThread());
    EtwpCovSampContextPruneModules(a1);
    goto LABEL_90;
  }
  Name = -1073741670;
LABEL_86:
  v9 = v82;
LABEL_132:
  if( *(struct _KTHREAD **)(a1 + 672) == KeGetCurrentThread() )
  {
    *(_QWORD *)(a1 + 672) = 0i64;
    if( (_InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 664), 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock((_EX_PUSH_LOCK *)(a1 + 664));
    KeAbPostRelease((VOID *)(a1 + 664));
    KeLeaveCriticalRegionThread(KeGetCurrentThread());
  }
  if( v10 )
  {
    v10[8] = 0i64;
    EtwpCovSampModuleCleanup((INT64)v10);
    ExFreePoolWithTag(v10, 0x56777445u);
  }
  if( v9 )
    ExFreePoolWithTag(v9, 0x56777445u);
  return Name;
}

Referenced by:

EtwpCovSampImageNotify