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