RtlpWalkFrameChain

NTSTATUS __stdcall RtlpWalkFrameChain(VOID **Callers, UINT64 Count, UINT64 Flags, UINT64 FramesToSkip){
  char v4; 
  _EPROCESS *v5; 
  int v6; 
  __int64 v7; 
  int v8; 
  char v9; 
  int v10; 
  INT64 v11; 
  unsigned __int64 v12; 
  int v13; 
  int v14; 
  unsigned __int64 v15; 
  __int64 v16; 
  signed __int64 v17; 
  void *v18; 
  void *v19; 
  int v20; 
  char *v21; 
  unsigned int v22; 
  VOID *v23; 
  __int64 v24; 
  unsigned int v25; 
  INT64 v26; 
  __int64 v27; 
  _EPROCESS *v28; 
  _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY *v29; 
  unsigned __int64 v30; 
  unsigned __int64 v31; 
  UINT64 *v32; 
  int v33; 
  _ETHREAD *v34; 
  unsigned __int64 StackBase; 
  UINT8 NextKernelStackSegment; 
  int v37; 
  UINT16 v38; 
  INT64 v39; 
  __int64 i; 
  __int64 v41; 
  unsigned __int64 v42; 
  _EPROCESS *v44; 
  size_t v45; 
  unsigned int v46; 
  UINT64 *v47; 
  char *v48; 
  __int64 *v49; 
  CHAR *v50; 
  UINT64 v51; 
  VOID *CurrentThread; 
  unsigned int v53; 
  int v54; 
  unsigned __int64 v55; 
  _KERNEL_STACK_LIMITS Type; 
  UINT64 LowLimit; 
  __int64 v58; 
  UINT64 HighLimit; 
  UINT64 v60; 
  __int64 j; 
  unsigned __int64 v62; 
  __int64 v63; 
  unsigned int v64; 
  int v65; 
  INT64 v66; 
  unsigned __int64 *v67; 
  UINT64 v68; 
  UINT64 v69; 
  int v70; 
  int v71; 
  __int64 v72; 
  _EPROCESS *Process; 
  INT64 v74; 
  UINT64 StackLimit; 
  UINT64 v76; 
  __int64 v77; 
  char *ExtendedFeature2; 
  _KERNEL_STACK_SEGMENT StackSegment; 
  _INVERTED_FUNCTION_TABLE_ENTRY FunctionTableInfo; 
  int v81; 
  __int64 v82; 
  __int64 v83; 
  __int64 v84; 
  UINT64 *p_LowLimit; 
  UINT64 *p_HighLimit; 
  __int64 v87; 
  _IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY *v88; 
  _WOW64_CPUAREA_INFO CpuAreaInfo[4]; 
  __int128 v90; 
  __int128 v91; 
  char v92; 

  v92 = Flags;
  v53 = FramesToSkip;
  v4 = Flags;
  LODWORD(v60) = Count;
  v74 = (INT64)Callers;
  memset(&FunctionTableInfo, 0, sizeof(FunctionTableInfo));
  v67 = 0i64;
  v64 = 0;
  v82 = 0i64;
  v83 = 0i64;
  HighLimit = 0i64;
  memset(&StackSegment, 0, sizeof(StackSegment));
  LowLimit = 0i64;
  v65 = 0;
  j = 0i64;
  v63 = 0i64;
  HIBYTE(v51) = 1;
  CurrentThread = KeGetCurrentThread();
  v5 = (_EPROCESS *)*((_QWORD *)CurrentThread + 23);
  Process = v5;
  if( (*((_DWORD *)CurrentThread + 29) & 0x400) != 0 || *((_BYTE *)CurrentThread + 586) == 1 )
    v66 = 0i64;
  else
    v66 = *((_QWORD *)CurrentThread + 30);
  v55 = 0i64;
  v62 = 0i64;
  v6 = 0;
  LODWORD(v51) = 0;
  v54 = 0;
  if( !RtlpGetStackLimits(&LowLimit, &HighLimit) )
    return 0;
  v7 = 0i64;
  v77 = 0i64;
  v8 = v4 & 1;
  if( v8 && (v5->MitigationFlags2 & 0x4000) != 0 )
  {
    v7 = KeRaiseExceptionForReturnAddressHijack;
    v77 = KeRaiseExceptionForReturnAddressHijack;
  }
  v9 = 0;
  BYTE4(v51) = 0;
  if( v7 )
  {
    v9 = 1;
    BYTE4(v51) = 1;
  }
  v10 = 1048587;
  v11 = 0i64;
  if( v9 )
  {
    v10 = 1048651;
    v11 = 2048i64;
  }
  v12 = v11;
  v70 = 0;
  v71 = 0;
  LODWORD(v72) = 0;
  v13 = 1;
  if( (v10 & 0x100040) == 1048640 )
  {
    if( !KUSER_SHARED_DATA.XState.EnabledFeatures )
    {
      v15 = v64;
      goto LABEL_12;
    }
    v13 = 3;
  }
  v70 = v13;
  v71 = 16;
  v14 = 1256;
  if( (v13 & 2) != 0 )
  {
    if( (KUSER_SHARED_DATA.XState._bf_0 & 2) != 0 )
      v12 = v11 & (KUSER_SHARED_DATA.XState.EnabledUserVisibleSupervisorFeatures | KUSER_SHARED_DATA.XState.EnabledFeatures | 0x8000000000000000ui64);
    v14 = RtlpGetEntireXStateAreaLength(v12) + 800;
  }
  v15 = (unsigned int)(v14 - 1 + 16);
  LODWORD(v72) = v15;
  v64 = v15;
LABEL_12:
  v16 = v15 + 15;
  if( v15 + 15 <= v15 )
    v16 = 0xFFFFFFFFFFFFFF0i64;
  v17 = v16 & 0xFFFFFFFFFFFFFFF0ui64;
  v18 = alloca(v17);
  v19 = alloca(v17);
  HIDWORD(v72) = 0;
  v20 = 1;
  if( (v10 & 0x100040) != 1048640 )
    goto LABEL_15;
  if( KUSER_SHARED_DATA.XState.EnabledFeatures )
  {
    v20 = 3;
LABEL_15:
    HIDWORD(v72) = v20;
    LODWORD(v58) = v10;
    LODWORD(STACK[0x52C]) = 1232;
    LODWORD(STACK[0x528]) = -1232;
    LODWORD(STACK[0x520]) = -1232;
    LODWORD(STACK[0x524]) = 1256;
    if( (v20 & 2) != 0 )
    {
      if( (KUSER_SHARED_DATA.XState._bf_0 & 2) != 0 )
        v11 &= KUSER_SHARED_DATA.XState.EnabledUserVisibleSupervisorFeatures | KUSER_SHARED_DATA.XState.EnabledFeatures | 0x8000000000000000ui64;
      v45 = RtlpGetEntireXStateAreaLength(v11) - 512;
      memset((VOID *)((unsigned __int64)&STACK[0x577] & 0xFFFFFFFFFFFFFFC0ui64), 0i64, v45);
      if( (KUSER_SHARED_DATA.XState._bf_0 & 2) != 0 )
        *(_QWORD *)(((unsigned __int64)&STACK[0x577] & 0xFFFFFFFFFFFFFFC0ui64) + 8) = v11 | 0x8000000000000000ui64;
      v46 = (((unsigned int)&STACK[0x520] + 87) & 0xFFFFFFC0) - (unsigned int)&STACK[0x520];
      LODWORD(STACK[0x530]) = v46;
      LODWORD(STACK[0x534]) = v45;
      LODWORD(STACK[0x524]) = v45 + v46 - LODWORD(STACK[0x520]);
      v6 = v51;
    }
    else
    {
      STACK[0x530] = 25i64;
    }
    v67 = &STACK[0x520];
  }
  RtlpCaptureContext2();
  BYTE6(v51) = 0;
  v22 = 0;
  LODWORD(v51) = 0;
  BYTE5(v51) = (v92 & 2) != 0;
  if( !v8 && (dword_140CFA174 & 1) == 0 )
    v65 = 0x80000000;
  v68 = 0i64;
  v69 = 0i64;
  v23 = CurrentThread;
  if( v8 )
  {
    for( i = *((_QWORD *)CurrentThread + 5); (*(_BYTE *)(i + 8) & 1) != 0; i = *(_QWORD *)(i + 40) )
      ;
    v41 = i - 400;
    v55 = i - 400;
    v62 = i - 400;
    if( !v66 || (*(_WORD *)(v66 + 6126) & 0x100) != 0 )
      return 0;
    if( (unsigned __int16)PsWow64GetProcessMachine((INT64)Process) != 332 || *(_BYTE *)(v41 + 43) == 2 )
    {
      v25 = v53;
    }
    else
    {
      v25 = v53;
      if( *(_WORD *)(v41 + 368) == 35 )
      {
        LODWORD(v51) = 1;
        LODWORD(v50) = *(_DWORD *)(v41 + 384);
        LODWORD(v49) = *(_DWORD *)(v41 + 344);
        LODWORD(v48) = v53;
        LODWORD(v47) = v60;
        if( RtlpWalkWowStack(v74, (UINT64 *)(v41 + 360), v66, &v51, (UINT64)v47, (UINT64)v48, (UINT64)v49, (UINT64)v50) )
        {
          v22 = v51;
          goto LABEL_155;
        }
        v22 = v51;
      }
    }
    v68 = *(_QWORD *)(v41 + 384);
    v42 = *(_QWORD *)(v66 + 8);
    v69 = v42;
    if( v42 <= v68 )
      return 0;
    if( v42 > 0x7FFFFFFF0000i64 )
      MEMORY[0x7FFFFFFF0000] = 0;
    for( j = *((_QWORD *)v23 + 5); (*(_BYTE *)(j + 8) & 1) != 0; j = *(_QWORD *)(j + 40) )
      ;
    v24 = *(_QWORD *)(j + 32);
    v63 = v24;
    HIBYTE(v51) = _bittestandset((signed __int32 *)v23 + 29, 5u);
  }
  else
  {
    v24 = v63;
    v25 = v53;
  }
  v58 = v24;
  memset(&StackSegment, 0, sizeof(StackSegment));
  FunctionTableInfo = *(_INVERTED_FUNCTION_TABLE_ENTRY *)&byte_140E00020;
LABEL_24:
  v26 = 0xFFFF800000000000ui64;
  while( 1 )
  {
    v27 = j;
    if( v6 != 1 )
    {
      v21 = *(char **)&FunctionTableInfo.SizeOfImage;
      if( *(_QWORD *)&FunctionTableInfo.SizeOfImage >= 0xFFFF800000000000ui64
        && *((_BYTE *)&stru_140C4DB30 + ((unsigned int)(*(_QWORD *)&FunctionTableInfo.SizeOfImage >> 39) & 0x1FF) + 6872) == 1 )
      {
        if( !MmIsSessionExecutionValid(
                v23,
                (INT64)Process,
                *(INT64 *)&FunctionTableInfo.SizeOfImage,
                0xFFFF800000000000ui64,
                (INT64)v47) )
          goto LABEL_155;
        v26 = 0xFFFF800000000000ui64;
      }
    }
    v28 = Process;
    v76 = 0i64;
    StackLimit = 0i64;
    Type = BugcheckStackLimits;
    if( ((unsigned __int8)Process & 7) != 0 )
      goto LABEL_154;
    if( (unsigned __int64)Process < LowLimit || (unsigned __int64)Process >= HighLimit )
      break;
LABEL_31:
    v29 = RtlpLookupFunctionEntryForStackWalks(
            *(UINT64 *)&FunctionTableInfo.SizeOfImage,
            &FunctionTableInfo,
            (INT64)v21,
            v26,
            (INT64)v47,
            (UINT64)v48,
            (UINT64)v49,
            v50);
    v88 = v29;
    if( v29 )
    {
      v87 = 0i64;
      p_LowLimit = &LowLimit;
      p_HighLimit = &HighLimit;
      v50 = (CHAR *)&v82;
      v49 = &v83;
      v48 = (char *)&v51 + 6;
      v47 = &v51;
      v81 = RtlpxVirtualUnwind(v65, (INT64)FunctionTableInfo.ImageBase, *(UINT64 *)&FunctionTableInfo.SizeOfImage, v29);
      if( v81 < 0 )
      {
        v23 = CurrentThread;
        goto LABEL_155;
      }
      if( BYTE6(v51) )
        BYTE5(v51) = 0;
      v30 = *(_QWORD *)&FunctionTableInfo.SizeOfImage;
    }
    else
    {
      if( !FunctionTableInfo.ImageBase )
      {
        v23 = CurrentThread;
        goto LABEL_155;
      }
      if( *(_QWORD *)&FunctionTableInfo.SizeOfImage <= 0x7FFFFFFEFFFFui64 )
      {
        if( ((unsigned __int8)Process & 3) != 0 )
          goto LABEL_145;
        v22 = v51;
        v58 = v63;
        v55 = v62;
        v6 = v54;
      }
      v30 = *(_QWORD *)Process->Pcb.gap0;
      *(_QWORD *)&FunctionTableInfo.SizeOfImage = *(_QWORD *)Process->Pcb.gap0;
      Process = (_EPROCESS *)((char *)Process + 8);
    }
    v31 = v30;
    if( v6 == 1 && v22 && v77 && v30 == v77 )
    {
      ExtendedFeature2 = RtlLocateExtendedFeature2(v67, 0xBu, 0xFFFFF780000003D8ui64, 0i64);
      v31 = *(_QWORD *)(*((_QWORD *)ExtendedFeature2 + 1) - 8i64);
      *(_QWORD *)&FunctionTableInfo.SizeOfImage = v31;
    }
    if( !v31 )
    {
      if( (v92 & 1) == 0 )
        goto LABEL_91;
      if( (unsigned __int16)PsWow64GetProcessMachine((INT64)Process) != 332 )
        goto LABEL_91;
      if( *(_BYTE *)(v55 + 43) != 2 )
        goto LABEL_91;
      *(_OWORD *)CpuAreaInfo = 0i64;
      v90 = 0i64;
      v91 = 0i64;
      v39 = v66;
      if( RtlWow64GetCpuAreaInfo(*(VOID **)(v66 + 5256), v38, CpuAreaInfo) < 0 )
        goto LABEL_91;
      if( (CpuAreaInfo[0] & 3) == 0 )
      {
        LODWORD(v50) = *(_DWORD *)(*(_QWORD *)CpuAreaInfo + 196i64) - 4;
        LODWORD(v49) = *(_DWORD *)(*(_QWORD *)CpuAreaInfo + 180i64);
        LODWORD(v48) = v25;
        LODWORD(v47) = v60;
        if( RtlpWalkWowStack(v74, 0i64, v39, &v51, (UINT64)v47, (UINT64)v48, (UINT64)v49, (UINT64)v50) )
        {
          v22 = v51;
          v23 = CurrentThread;
          goto LABEL_155;
        }
        v22 = v51;
LABEL_91:
        v23 = CurrentThread;
        goto LABEL_155;
      }
LABEL_145:
      ExRaiseDatatypeMisalignment();
    }
    if( v6 )
    {
      if( v6 == 1 )
      {
        if( v31 > 0x7FFFFFFEFFFFi64 )
        {
          v23 = CurrentThread;
          goto LABEL_155;
        }
        if( v58 && v31 == *(_QWORD *)(v55 + 360) )
        {
          v6 = 2;
          v54 = 2;
          *(_QWORD *)&FunctionTableInfo.SizeOfImage = *(_QWORD *)(v58 + 312);
          Process = (_EPROCESS *)(v58 + 320);
          v74 = *(_QWORD *)(v58 + 248);
          v72 = *(_QWORD *)(v58 + 256);
          v76 = *(_QWORD *)(v58 + 264);
          StackLimit = *(_QWORD *)(v58 + 272);
          StackSegment.KernelStack = *(_QWORD *)(v58 + 280);
          StackSegment.InitialStack = *(_QWORD *)(v58 + 288);
          FunctionTableInfo.FunctionTable = *(_IMAGE_RUNTIME_FUNCTION_ENTRY **)(v58 + 296);
          FunctionTableInfo.ImageBase = *(void **)(v58 + 304);
          if( BYTE4(v51) )
          {
            ExtendedFeature2 = RtlLocateExtendedFeature2(v67, 0xBu, 0xFFFFF780000003D8ui64, 0i64);
            *(_QWORD *)ExtendedFeature2 = 0i64;
          }
          v58 = *(_QWORD *)(v27 + 32);
          v63 = v58;
          v32 = *(UINT64 **)(v27 + 40);
          if( !v32 )
          {
            v23 = CurrentThread;
            goto LABEL_155;
          }
          j = *(_QWORD *)(v27 + 40);
          LowLimit = (UINT64)Process;
          HighLimit = *v32;
        }
      }
      else
      {
        if( v6 != 2 )
        {
          v23 = CurrentThread;
          goto LABEL_155;
        }
        if( v31 <= 0x7FFFFFFEFFFFi64 )
        {
          if( v31 != *(_QWORD *)(v55 + 360) )
          {
            v23 = CurrentThread;
            goto LABEL_155;
          }
          v84 = *(_QWORD *)(v55 + 384);
          if( (v84 & 3) != 0 )
            goto LABEL_145;
          v6 = 1;
          v54 = 1;
          Process = *(_EPROCESS **)(v84 + 72);
          LowLimit = v68;
          HighLimit = v69;
          v58 = v63;
          if( v63 )
          {
            v55 = *(_QWORD *)(v63 + 208);
            v62 = v55;
            v22 = v51;
          }
          else
          {
            v22 = v51;
            v55 = v62;
          }
        }
      }
      goto LABEL_43;
    }
    v26 = 0xFFFF800000000000ui64;
    if( (v92 & 1) == 0 && v31 < 0xFFFF800000000000ui64 )
    {
      v23 = CurrentThread;
      goto LABEL_155;
    }
    if( (v92 & 1) != 0 )
    {
      if( v31 < 0xFFFF800000000000ui64 )
      {
        if( v31 > 0x7FFFFFFEFFFFi64 )
        {
          v23 = CurrentThread;
          goto LABEL_155;
        }
        if( v31 != *(_QWORD *)(v55 + 360) )
        {
          v23 = CurrentThread;
          goto LABEL_155;
        }
        v6 = 1;
        v54 = 1;
        if( v58 )
        {
          v55 = *(_QWORD *)(v58 + 208);
          v62 = v55;
          if( v55 < 0xFFFF800000000000ui64 )
          {
            v23 = CurrentThread;
            goto LABEL_155;
          }
        }
        if( BYTE4(v51) )
        {
          LODWORD(v58) = v58 | 0x100040;
          v21 = RtlLocateExtendedFeature2(v67, 0xBu, 0xFFFFF780000003D8ui64, 0i64);
          ExtendedFeature2 = v21;
          *(_QWORD *)v21 = 1i64;
          *((_QWORD *)v21 + 1) = __readmsr(0x6A7u);
        }
        LowLimit = v68;
        HighLimit = v69;
LABEL_43:
        if( v22 >= v53 )
          *(_QWORD *)(v74 + 8i64 * (v22 - v53)) = *(_QWORD *)&FunctionTableInfo.SizeOfImage;
        LODWORD(v51) = ++v22;
        if( v22 >= (unsigned int)v60 )
        {
          v23 = CurrentThread;
          goto LABEL_155;
        }
        v25 = v53;
        v23 = CurrentThread;
        goto LABEL_24;
      }
      if( !v22 )
        goto LABEL_43;
      v23 = CurrentThread;
    }
    else
    {
      if( !BYTE5(v51) )
        goto LABEL_43;
      v23 = CurrentThread;
    }
  }
  if( LowLimit < 0xFFFF800000000000ui64 )
    goto LABEL_154;
  KeQueryCurrentStackInformation(&Type, &StackLimit, &v76);
  if( (unsigned int)Type <= MachineCheckStackLimits )
  {
    v33 = 929;
    if( _bittest(&v33, Type) )
      goto LABEL_154;
  }
  v34 = (_ETHREAD *)KeGetCurrentThread();
  v26 = (unsigned int)Type;
  if( Type != DPCStackLimits )
  {
    if( (KeGetPcr()->Prcb.DpcRequestSummary & 1) != 0 && v34 != KeGetCurrentPrcb()->IdleThread )
    {
      v44 = (_EPROCESS *)((char *)KeGetPcr()->Prcb.DpcStack + 80);
      v21 = &v44->Pcb.gap0[-(unsigned int)KeKernelStackSize];
      if( v21 <= (char *)v28 && v28 < v44 )
      {
        HighLimit = (UINT64)v44;
        LowLimit = (UINT64)v44 - (unsigned int)KeKernelStackSize;
        goto LABEL_88;
      }
    }
    v26 = (unsigned int)Type;
  }
  LOBYTE(v21) = 0;
  StackBase = StackSegment.StackBase;
  if( !StackSegment.StackBase )
  {
    KeGetNextKernelStackSegment(&v34->Tcb, &StackSegment, 1u);
    StackBase = StackSegment.StackBase;
  }
  NextKernelStackSegment = 1;
  if( (unsigned int)v26 > 0xA || (v37 = 1090, !_bittest(&v37, v26)) || !(_BYTE)v21 )
  {
    NextKernelStackSegment = KeGetNextKernelStackSegment(&v34->Tcb, &StackSegment, 0);
    StackBase = StackSegment.StackBase;
  }
  if( NextKernelStackSegment )
  {
    StackLimit = StackSegment.StackLimit;
    v76 = StackBase;
    if( (unsigned __int64)v28 >= StackSegment.StackLimit && (unsigned __int64)v28 < StackBase )
    {
      LowLimit = StackSegment.StackLimit;
      HighLimit = StackBase;
LABEL_88:
      v58 = v63;
      v6 = v54;
      v55 = v62;
      v22 = v51;
      goto LABEL_31;
    }
  }
  v22 = v51;
LABEL_154:
  v23 = CurrentThread;
LABEL_155:
  if( (v92 & 1) != 0 && !HIBYTE(v51) )
    *((_DWORD *)v23 + 29) &= ~0x20u;
  return v22;
}

Referenced by:

RtlWalkFrameChain