RtlpWalkFrameChain

INT64 __fastcall RtlpWalkFrameChain(VOID **Callers, UINT64 Count, UINT64 Flags, UINT64 FramesToSkip){
  char v4; 
  INT64 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; 
  unsigned int v21; 
  VOID *v22; 
  __int64 v23; 
  unsigned int v24; 
  __int64 v25; 
  unsigned __int64 v26; 
  UINT64 *v27; 
  unsigned __int64 v28; 
  void *v29; 
  UINT64 *v30; 
  unsigned __int64 v31; 
  int v32; 
  _ETHREAD *v33; 
  unsigned int v34; 
  char v35; 
  unsigned __int64 StackBase; 
  char NextKernelStackSegment; 
  int v38; 
  __int64 v39; 
  INT64 v40; 
  __int64 i; 
  __int64 v42; 
  unsigned __int64 v43; 
  UINT64 v45; 
  CHAR *v46; 
  int v47; 
  unsigned int v48; 
  UINT64 *v49; 
  char *v50; 
  __int64 *v51; 
  __int64 *v52; 
  UINT64 v53; 
  VOID *CurrentThread; 
  unsigned int v55; 
  int v56; 
  unsigned __int64 v57; 
  _KERNEL_STACK_LIMITS Type; 
  UINT64 LowLimit; 
  __int64 v60; 
  UINT64 HighLimit; 
  UINT64 v62; 
  __int64 j; 
  unsigned __int64 v64; 
  __int64 v65; 
  unsigned int v66; 
  int v67; 
  INT64 v68; 
  _DWORD *a1; 
  UINT64 v70; 
  UINT64 v71; 
  int v72; 
  int v73; 
  __int64 v74; 
  INT64 v75; 
  INT64 v76; 
  UINT64 StackLimit; 
  UINT64 v78; 
  __int64 v79; 
  CHAR *ExtendedFeature2; 
  _KERNEL_STACK_SEGMENT StackSegment; 
  INT64 a2[2]; 
  unsigned __int64 v83; 
  int v84; 
  __int64 v85; 
  __int64 v86; 
  __int64 v87; 
  UINT64 *p_LowLimit; 
  UINT64 *p_HighLimit; 
  __int64 v90; 
  UINT64 *v91; 
  __int128 v92[3]; 
  char v93; 
  v93 = Flags;
  v55 = FramesToSkip;
  v4 = Flags;
  LODWORD(v62) = Count;
  v76 = (INT64)Callers;
  *(_OWORD *)a2 = 0i64;
  v83 = 0i64;
  a1 = 0i64;
  v66 = 0;
  v85 = 0i64;
  v86 = 0i64;
  HighLimit = 0i64;
  memset(&StackSegment, 0, sizeof(StackSegment));
  LowLimit = 0i64;
  v67 = 0;
  j = 0i64;
  v65 = 0i64;
  HIBYTE(v53) = 1;
  CurrentThread = KeGetCurrentThread();
  v5 = *((_QWORD *)CurrentThread + 23);
  v75 = v5;
  if( (*((_DWORD *)CurrentThread + 29) & 0x400) != 0 || *((_BYTE *)CurrentThread + 586) == 1 )
    v68 = 0i64;
  else
    v68 = *((_QWORD *)CurrentThread + 30);
  v57 = 0i64;
  v64 = 0i64;
  v6 = 0;
  LODWORD(v53) = 0;
  v56 = 0;
  if( !RtlpGetStackLimits(&LowLimit, &HighLimit) )
    return 0i64;
  v7 = 0i64;
  v79 = 0i64;
  v8 = v4 & 1;
  if( v8 && (*(_DWORD *)(v5 + 2516) & 0x4000) != 0 )
  {
    v7 = KeRaiseExceptionForReturnAddressHijack;
    v79 = KeRaiseExceptionForReturnAddressHijack;
  }
  v9 = 0;
  BYTE4(v53) = 0;
  if( v7 )
  {
    v9 = 1;
    BYTE4(v53) = 1;
  }
  v10 = 1048587;
  v11 = 0i64;
  if( v9 )
  {
    v10 = 1048651;
    v11 = 2048i64;
  }
  v12 = v11;
  v72 = 0;
  v73 = 0;
  LODWORD(v74) = 0;
  v13 = 1;
  if( (v10 & 0x100040) == 1048640 )
  {
    if( !KUSER_SHARED_DATA.XState.EnabledFeatures )
    {
      v15 = v66;
      goto LABEL_12;
    }
    v13 = 3;
  }
  v72 = v13;
  v73 = 16;
  v14 = 1256;
  if( (v13 & 2) != 0 )
  {
    if( (KUSER_SHARED_DATA.XState.ControlFlags & 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(v74) = v15;
  v66 = v15;
LABEL_12:
  v16 = v15 + 15;
  if( v15 + 15 <= v15 )
    v16 = 0xFFFFFFFFFFFFFF0i64;
  v17 = v16 & 0xFFFFFFFFFFFFFFF0ui64;
  v18 = alloca(v17);
  v19 = alloca(v17);
  HIDWORD(v74) = 0;
  v20 = 1;
  if( (v10 & 0x100040) != 1048640 )
    goto LABEL_15;
  if( KUSER_SHARED_DATA.XState.EnabledFeatures )
  {
    v20 = 3;
LABEL_15:
    HIDWORD(v74) = v20;
    LODWORD(v60) = 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.ControlFlags & 2) != 0 )
        v11 &= KUSER_SHARED_DATA.XState.EnabledUserVisibleSupervisorFeatures | KUSER_SHARED_DATA.XState.EnabledFeatures | 0x8000000000000000ui64;
      v47 = RtlpGetEntireXStateAreaLength(v11) - 512;
      memset((unsigned __int64)&STACK[0x577] & 0xFFFFFFFFFFFFFFC0ui64, 0i64);
      if( (KUSER_SHARED_DATA.XState.ControlFlags & 2) != 0 )
        *(_QWORD *)(((unsigned __int64)&STACK[0x577] & 0xFFFFFFFFFFFFFFC0ui64) + 8) = v11 | 0x8000000000000000ui64;
      v48 = (((unsigned int)&STACK[0x520] + 87) & 0xFFFFFFC0) - (unsigned int)&STACK[0x520];
      LODWORD(STACK[0x530]) = v48;
      LODWORD(STACK[0x534]) = v47;
      LODWORD(STACK[0x524]) = v47 + v48 - LODWORD(STACK[0x520]);
      v6 = v53;
    }
    else
    {
      STACK[0x530] = 25i64;
    }
    a1 = &STACK[0x520];
  }
  RtlpCaptureContext2();
  BYTE6(v53) = 0;
  v21 = 0;
  LODWORD(v53) = 0;
  BYTE5(v53) = (v93 & 2) != 0;
  if( !v8 && (dword_140CFA174 & 1) == 0 )
    v67 = 0x80000000;
  v70 = 0i64;
  v71 = 0i64;
  v22 = CurrentThread;
  if( v8 )
  {
    for( i = *((_QWORD *)CurrentThread + 5); (*(_BYTE *)(i + 8) & 1) != 0; i = *(_QWORD *)(i + 40) )
      ;
    v42 = i - 400;
    v57 = i - 400;
    v64 = i - 400;
    if( !v68 || (*(_WORD *)(v68 + 6126) & 0x100) != 0 )
      return 0i64;
    if( (unsigned __int16)PsWow64GetProcessMachine(v75) != 332 || *(_BYTE *)(v42 + 43) == 2 )
    {
      v24 = v55;
    }
    else
    {
      v24 = v55;
      if( *(_WORD *)(v42 + 368) == 35 )
      {
        LODWORD(v53) = 1;
        LODWORD(v52) = *(_DWORD *)(v42 + 384);
        LODWORD(v51) = *(_DWORD *)(v42 + 344);
        LODWORD(v50) = v55;
        LODWORD(v49) = v62;
        if( RtlpWalkWowStack(v76, (UINT64 *)(v42 + 360), v68, &v53, (UINT64)v49, (UINT64)v50, (UINT64)v51, (UINT64)v52) )
        {
          v21 = v53;
          goto LABEL_154;
        }
        v21 = v53;
      }
    }
    v70 = *(_QWORD *)(v42 + 384);
    v43 = *(_QWORD *)(v68 + 8);
    v71 = v43;
    if( v43 <= v70 )
      return 0i64;
    if( v43 > 0x7FFFFFFF0000i64 )
      MEMORY[0x7FFFFFFF0000] = 0;
    for( j = *((_QWORD *)v22 + 5); (*(_BYTE *)(j + 8) & 1) != 0; j = *(_QWORD *)(j + 40) )
      ;
    v23 = *(_QWORD *)(j + 32);
    v65 = v23;
    HIBYTE(v53) = _bittestandset((signed __int32 *)v22 + 29, 5u);
  }
  else
  {
    v23 = v65;
    v24 = v55;
  }
  v60 = v23;
  memset(&StackSegment, 0, sizeof(StackSegment));
  *(_OWORD *)a2 = *(_OWORD *)&xmmword_140E00020;
  v83 = qword_140E00030;
  while( 1 )
  {
    v25 = j;
    if( v6 != 1
      && v83 >= 0xFFFF800000000000ui64
      && *((_BYTE *)&antNameB + ((v83 >> 39) & 0x1FF) - 256) == 1
      && !(unsigned int)MmIsSessionExecutionValid(v22, v75, v83, 0xFFFF800000000000ui64, (INT64)v49) )
    {
      goto LABEL_154;
    }
    v26 = v75;
    v78 = 0i64;
    StackLimit = 0i64;
    Type = BugcheckStackLimits;
    if( (v75 & 7) != 0 )
      goto LABEL_153;
    if( v75 < LowLimit || v75 >= HighLimit )
      break;
LABEL_30:
    v27 = RtlpLookupFunctionEntryForStackWalks((PVOID)v83, (INT64)a2);
    v91 = v27;
    if( v27 )
    {
      v90 = 0i64;
      p_LowLimit = &LowLimit;
      p_HighLimit = &HighLimit;
      v52 = &v85;
      v51 = &v86;
      v50 = (char *)&v53 + 6;
      v49 = &v53;
      v84 = RtlpxVirtualUnwind(v67, a2[1], v83, v27);
      if( v84 < 0 )
      {
        v22 = CurrentThread;
        goto LABEL_154;
      }
      if( BYTE6(v53) )
        BYTE5(v53) = 0;
      v28 = v83;
    }
    else
    {
      if( !a2[1] )
      {
        v22 = CurrentThread;
        goto LABEL_154;
      }
      if( v83 <= 0x7FFFFFFEFFFFi64 )
      {
        if( (v75 & 3) != 0 )
          goto LABEL_144;
        v21 = v53;
        v60 = v65;
        v57 = v64;
        v6 = v56;
      }
      v28 = *(_QWORD *)v75;
      v83 = *(_QWORD *)v75;
      v75 += 8i64;
    }
    v29 = (void *)v28;
    if( v6 == 1 && v21 && v79 && v28 == v79 )
    {
      ExtendedFeature2 = RtlLocateExtendedFeature2(a1, 0xBui64, 0xFFFFF780000003D8ui64, 0i64);
      v29 = *(void **)(*((_QWORD *)ExtendedFeature2 + 1) - 8i64);
      v83 = (unsigned __int64)v29;
    }
    if( !v29 )
    {
      if( (v93 & 1) != 0 && (unsigned __int16)PsWow64GetProcessMachine(v75) == 332 && *(_BYTE *)(v57 + 43) == 2 )
      {
        memset(v92, 0, sizeof(v92));
        v40 = v68;
        if( (int)RtlWow64GetCpuAreaInfo(*(_QWORD *)(v68 + 5256), v39, (__int64)v92) >= 0 )
        {
          if( (v92[0] & 3) != 0 )
LABEL_144:
            ExRaiseDatatypeMisalignment();
          LODWORD(v52) = *(_DWORD *)(*(_QWORD *)&v92[0] + 196i64) - 4;
          LODWORD(v51) = *(_DWORD *)(*(_QWORD *)&v92[0] + 180i64);
          LODWORD(v50) = v24;
          LODWORD(v49) = v62;
          if( RtlpWalkWowStack(v76, 0i64, v40, &v53, (UINT64)v49, (UINT64)v50, (UINT64)v51, (UINT64)v52) )
          {
            v21 = v53;
            v22 = CurrentThread;
            goto LABEL_154;
          }
          v21 = v53;
        }
      }
      v22 = CurrentThread;
      goto LABEL_154;
    }
    if( v6 )
    {
      if( v6 == 1 )
      {
        if( (unsigned __int64)v29 > 0x7FFFFFFEFFFFi64 )
        {
          v22 = CurrentThread;
          goto LABEL_154;
        }
        if( v60 && v29 == *(void **)(v57 + 360) )
        {
          v6 = 2;
          v56 = 2;
          v83 = *(_QWORD *)(v60 + 312);
          v75 = v60 + 320;
          v76 = *(_QWORD *)(v60 + 248);
          v74 = *(_QWORD *)(v60 + 256);
          v78 = *(_QWORD *)(v60 + 264);
          StackLimit = *(_QWORD *)(v60 + 272);
          StackSegment.KernelStack = *(_QWORD *)(v60 + 280);
          StackSegment.InitialStack = *(_QWORD *)(v60 + 288);
          a2[0] = *(_QWORD *)(v60 + 296);
          a2[1] = *(_QWORD *)(v60 + 304);
          if( BYTE4(v53) )
          {
            ExtendedFeature2 = RtlLocateExtendedFeature2(a1, 0xBui64, 0xFFFFF780000003D8ui64, 0i64);
            *(_QWORD *)ExtendedFeature2 = 0i64;
          }
          v60 = *(_QWORD *)(v25 + 32);
          v65 = v60;
          v30 = *(UINT64 **)(v25 + 40);
          if( !v30 )
          {
            v22 = CurrentThread;
            goto LABEL_154;
          }
          j = *(_QWORD *)(v25 + 40);
          LowLimit = v75;
          HighLimit = *v30;
        }
      }
      else
      {
        if( v6 != 2 )
        {
          v22 = CurrentThread;
          goto LABEL_154;
        }
        if( (unsigned __int64)v29 <= 0x7FFFFFFEFFFFi64 )
        {
          if( v29 != *(void **)(v57 + 360) )
          {
            v22 = CurrentThread;
            goto LABEL_154;
          }
          v87 = *(_QWORD *)(v57 + 384);
          if( (v87 & 3) != 0 )
            goto LABEL_144;
          v6 = 1;
          v56 = 1;
          v75 = *(_QWORD *)(v87 + 72);
          LowLimit = v70;
          HighLimit = v71;
          v60 = v65;
          if( v65 )
          {
            v57 = *(_QWORD *)(v65 + 208);
            v64 = v57;
            v21 = v53;
          }
          else
          {
            v21 = v53;
            v57 = v64;
          }
        }
      }
      goto LABEL_42;
    }
    if( (v93 & 1) == 0 && (unsigned __int64)v29 < 0xFFFF800000000000ui64 )
    {
      v22 = CurrentThread;
      goto LABEL_154;
    }
    if( (v93 & 1) != 0 )
    {
      if( (unsigned __int64)v29 < 0xFFFF800000000000ui64 )
      {
        if( (unsigned __int64)v29 > 0x7FFFFFFEFFFFi64 )
        {
          v22 = CurrentThread;
          goto LABEL_154;
        }
        if( v29 != *(void **)(v57 + 360) )
        {
          v22 = CurrentThread;
          goto LABEL_154;
        }
        v6 = 1;
        v56 = 1;
        if( v60 )
        {
          v57 = *(_QWORD *)(v60 + 208);
          v64 = v57;
          if( v57 < 0xFFFF800000000000ui64 )
          {
            v22 = CurrentThread;
            goto LABEL_154;
          }
        }
        if( BYTE4(v53) )
        {
          LODWORD(v60) = v60 | 0x100040;
          v46 = RtlLocateExtendedFeature2(a1, 0xBui64, 0xFFFFF780000003D8ui64, 0i64);
          ExtendedFeature2 = v46;
          *(_QWORD *)v46 = 1i64;
          *((_QWORD *)v46 + 1) = __readmsr(0x6A7u);
        }
        LowLimit = v70;
        HighLimit = v71;
LABEL_42:
        if( v21 >= v55 )
          *(_QWORD *)(v76 + 8i64 * (v21 - v55)) = v83;
        LODWORD(v53) = ++v21;
        if( v21 >= (unsigned int)v62 )
        {
          v22 = CurrentThread;
          goto LABEL_154;
        }
        v24 = v55;
        v22 = CurrentThread;
      }
      else
      {
        if( !v21 )
          goto LABEL_42;
        v22 = CurrentThread;
      }
    }
    else
    {
      if( !BYTE5(v53) )
        goto LABEL_42;
      v22 = CurrentThread;
    }
  }
  if( LowLimit < 0xFFFF800000000000ui64 )
    goto LABEL_153;
  KeQueryCurrentStackInformation(&Type, &StackLimit, &v78);
  if( (unsigned int)Type <= MachineCheckStackLimits )
  {
    v32 = 929;
    if( _bittest(&v32, Type) )
      goto LABEL_153;
  }
  v33 = (_ETHREAD *)KeGetCurrentThread();
  v34 = Type;
  if( Type != DPCStackLimits )
  {
    if( (*((_BYTE *)KeGetPcr() + 12972) & 1) != 0 && v33 != *((_ETHREAD **)KeGetCurrentPrcb() + 3) )
    {
      v45 = *((_QWORD *)KeGetPcr() + 1618) + 80i64;
      v31 = v45 - (unsigned int)KeKernelStackSize;
      if( v31 <= v26 && v26 < v45 )
      {
        HighLimit = v45;
        LowLimit = v45 - (unsigned int)KeKernelStackSize;
        goto LABEL_87;
      }
    }
    v34 = Type;
  }
  v35 = 0;
  StackBase = StackSegment.StackBase;
  if( !StackSegment.StackBase )
  {
    LOBYTE(v31) = 1;
    KeGetNextKernelStackSegment(v33, &StackSegment, v31);
    StackBase = StackSegment.StackBase;
  }
  NextKernelStackSegment = 1;
  if( v34 > 0xA || (v38 = 1090, !_bittest(&v38, v34)) || !v35 )
  {
    NextKernelStackSegment = KeGetNextKernelStackSegment(v33, &StackSegment, 0i64);
    StackBase = StackSegment.StackBase;
  }
  if( NextKernelStackSegment )
  {
    StackLimit = StackSegment.StackLimit;
    v78 = StackBase;
    if( v26 >= StackSegment.StackLimit && v26 < StackBase )
    {
      LowLimit = StackSegment.StackLimit;
      HighLimit = StackBase;
LABEL_87:
      v60 = v65;
      v6 = v56;
      v57 = v64;
      v21 = v53;
      goto LABEL_30;
    }
  }
  v21 = v53;
LABEL_153:
  v22 = CurrentThread;
LABEL_154:
  if( (v93 & 1) != 0 && !HIBYTE(v53) )
    *((_DWORD *)v22 + 29) &= ~0x20u;
  return v21;
}

Referenced by:

RtlWalkFrameChain