RtlpLookupUserFunctionTable

_IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY *__fastcall RtlpLookupUserFunctionTable(
        VOID *ControlPc,
        _INVERTED_FUNCTION_TABLE_ENTRY *FunctionTableInfo,
        INT64 a3,
        INT64 a4,
        INT64 a5,
        UINT64 a6,
        UINT64 a7,
        CHAR *a8){
  _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY *v10; 
  _ETHREAD *CurrentThread; 
  _EX_PUSH_LOCK *Process; 
  _EX_PUSH_LOCK *v14; 
  _DWORD *bf_0; 
  int v16; 
  void *v17; 
  unsigned int SizeOfTable; 
  int v19; 
  unsigned __int64 v20; 
  unsigned int v21; 
  unsigned int v22; 
  unsigned int v23; 
  int v24; 
  void *v25; 
  _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY *v26; 
  __int64 v27; 
  unsigned __int64 v28; 
  _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY *FunctionTable; 
  UINT64 v30[2]; 
  unsigned __int64 v31; 
  void *v32; 
  VOID *Base; 
  __int64 v34[13]; 
  int v35; 

  Base = 0i64;
  v35 = 0;
  v34[0] = 0i64;
  v10 = RtlpLookupUserFunctionTableInverted(
          ControlPc,
          FunctionTableInfo,
          a3,
          a4,
          (INT64)FunctionTable,
          0i64,
          0i64,
          0i64);
  FunctionTable = v10;
  if( !v10 )
  {
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    Process = (_EX_PUSH_LOCK *)CurrentThread->Tcb.Process;
    if( Process[265]._bf_0 )
    {
      --CurrentThread->Tcb.SpecialApcDisable;
      v14 = Process + 266;
      ExAcquirePushLockSharedEx(Process + 266, 0i64);
      bf_0 = (_DWORD *)Process[265]._bf_0;
      if( bf_0 )
      {
        v16 = 1;
        if( *bf_0 != 1 )
        {
          if( (KiSpeculationFeatures & 0x2000000) != 0 )
          {
            v22 = dword_140C4C9F0;
            v23 = 4096;
          }
          else
          {
            v22 = 0;
            v23 = 0;
          }
          v24 = *bf_0 - 1;
          while( 1 )
          {
            while( 1 )
            {
              if( v24 < v16 )
                goto LABEL_6;
              v19 = (v16 + v24) >> 1;
              v32 = *(void **)&bf_0[6 * v19 + 6];
              v20 = (unsigned __int64)v32 + (unsigned int)bf_0[6 * v19 + 8];
              if( ControlPc >= v32 )
                break;
              if( !v19 )
                goto LABEL_6;
              v24 = v19 - 1;
            }
            if( (unsigned __int64)ControlPc > 0x7FFFFFFEFFFFi64
              && v23
              && (unsigned __int64)ControlPc >= v20 + v22
              && (unsigned __int64)ControlPc < v20 + v23 + v22
              && v32 != (void *)PsNtosImageBase
              && v32 != PsHalImageBase )
            {
              break;
            }
            if( (unsigned __int64)ControlPc < v20 )
            {
              *(_OWORD *)v30 = *(_OWORD *)&bf_0[6 * v19 + 4];
              v31 = *(_QWORD *)&bf_0[6 * v19 + 8];
              v23 = v31;
              v25 = (void *)v30[1];
              goto LABEL_40;
            }
            v16 = v19 + 1;
          }
          v30[0] = (UINT64)&RtlRetpolineStubsFunctionTable;
          v25 = (void *)(v20 + v22);
          v30[1] = (UINT64)v25;
          v31 = __PAIR64__(RtlRetpolineStubsFunctionTableSize, v23);
LABEL_40:
          FunctionTableInfo->ImageBase = v25;
          FunctionTableInfo->SizeOfImage = v23;
          if( _InterlockedCompareExchange64(&v14->_bf_0, 0i64, 17i64) != 17 )
            ExfReleasePushLockShared(v14);
          KeAbPostRelease(v14);
          KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
          v26 = *(_IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY **)(v30[0] + 16);
          FunctionTable = v26;
          FunctionTableInfo->FunctionTable = (_IMAGE_RUNTIME_FUNCTION_ENTRY *)v26;
          v27 = (unsigned int)(12 * *(_DWORD *)(v30[0] + 84));
          FunctionTableInfo->SizeOfTable = v27;
          if( (_DWORD)v27 )
          {
            if( ((unsigned __int8)v26 & 3) != 0 )
              ExRaiseDatatypeMisalignment();
            v28 = (unsigned __int64)v26 + v27;
            if( v28 > 0x7FFFFFFF0000i64 || v28 < (unsigned __int64)v26 )
              MEMORY[0x7FFFFFFF0000] = 0;
          }
          return FunctionTable;
        }
      }
LABEL_6:
      if( _InterlockedCompareExchange64(&v14->_bf_0, 0i64, 17i64) != 17 )
        ExfReleasePushLockShared(v14);
      KeAbPostRelease(v14);
      KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
    }
    if( (int)MmGetImageInformation(ControlPc, &Base, v34, &v35) < 0 )
    {
      v17 = 0i64;
      v21 = 0;
      v10 = FunctionTable;
    }
    else
    {
      v17 = Base;
      RtlCaptureImageExceptionValues(Base, &FunctionTable, (UINT64 *)&FunctionTableInfo->SizeOfTable);
      v10 = FunctionTable;
      if( FunctionTable )
      {
        SizeOfTable = FunctionTableInfo->SizeOfTable;
        if( SizeOfTable && SizeOfTable == 12 * (SizeOfTable / 0xCui64) )
        {
          if( ((unsigned __int8)FunctionTable & 3) != 0 )
            ExRaiseDatatypeMisalignment();
          if( (unsigned __int64)FunctionTable + SizeOfTable > 0x7FFFFFFF0000i64
            || (_IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY *)((char *)FunctionTable + SizeOfTable) < FunctionTable )
          {
            MEMORY[0x7FFFFFFF0000] = 0;
          }
        }
        else
        {
          v10 = 0i64;
          FunctionTable = 0i64;
        }
      }
      v21 = v34[0];
    }
    FunctionTableInfo->ImageBase = v17;
    FunctionTableInfo->SizeOfImage = v21;
    FunctionTableInfo->FunctionTable = (_IMAGE_RUNTIME_FUNCTION_ENTRY *)v10;
    if( !v10 )
      FunctionTableInfo->SizeOfTable = 0;
  }
  return v10;
}

Referenced by:

RtlpLookupFunctionEntryForStackWalks