KeCapturePersistentThreadState

NTSTATUS __fastcall KeCapturePersistentThreadState(
        INT64 a1,
        VOID *a2,
        INT64 a3,
        INT64 a4,
        INT64 ulpBugCheckParam2,
        INT64 ulpBugCheckParam3,
        INT64 ulpBugCheckParam4,
        INT64 pvDump){
  INT64 v8; 
  int v10; 
  _ETHREAD *CurrentThread; 
  void *v13; 
  unsigned __int64 v14; 
  int ActiveProcessorCount; 
  __int64 v16; 
  unsigned int v17; 
  _OWORD *v18; 
  int v19; 
  _OWORD *v20; 
  __int128 v21; 
  __int128 v22; 
  __int64 v23; 
  size_t v24; 
  int v25; 
  __int64 v26; 
  size_t v27; 
  int v28; 
  const VOID *StackLimit; 
  void *StackBase; 
  const VOID *v31; 
  unsigned int v32; 
  int v33; 
  int v34; 
  size_t v35; 
  _ETHREAD *v36; 
  unsigned int v37; 
  int v38; 
  unsigned int v39; 
  int v40; 
  int v41; 
  UINT64 v42; 
  unsigned int v43; 
  unsigned int MaxValidSectionSizeDown; 
  const VOID *v45; 
  size_t v46; 
  __int64 v47; 
  NTSTATUS result; 
  UINT64 DriverCount; 
  INT64 v50; 
  int v51; 

  v8 = pvDump;
  v50 = 0i64;
  v51 = 0;
  v10 = a3;
  CurrentThread = (_ETHREAD *)a2;
  if( !pvDump )
    return 0;
  if( !a2 )
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  if( *(&stru_140CF2E80 + 4800) || SecureDump_GetSecureDumpSettings((INT64)&v50) < 0 || (_BYTE)v50 )
    return 0;
  memset((VOID *)(v8 + 8), 0i64, 0x3FFF8u);
  v13 = (void *)v8;
  v14 = 2048i64;
  if( (v8 & 4) != 0 )
  {
    v14 = 2047i64;
    v13 = (void *)(v8 + 4);
  }
  memset64(v13, 0x4547415045474150ui64, v14 >> 1);
  if( (v14 & 1) != 0 )
    *((_DWORD *)v13 + v14 - 1) = 1162297680;
  *(_DWORD *)v8 = 1162297680;
  *(_DWORD *)(v8 + 4) = 875976004;
  *(_DWORD *)(v8 + 12) = (unsigned __int16)NtBuildNumber;
  *(_DWORD *)(v8 + 8) = (unsigned int)NtBuildNumber >> 28;
  *(_QWORD *)(v8 + 16) = CurrentThread->Tcb.ApcState.Process->Pcb.DirectoryTableBase & 0xFFFFFFFFFFFFF000ui64;
  *(_QWORD *)(v8 + 24) = MmPfnDatabase;
  *(_QWORD *)(v8 + 32) = &PsLoadedModuleList;
  *(_QWORD *)(v8 + 40) = &PsActiveProcessHead;
  *(_DWORD *)(v8 + 48) = 34404;
  ActiveProcessorCount = KeQueryActiveProcessorCountEx(0xFFFFu);
  *(_QWORD *)(v8 + 3848) = 0i64;
  *(_DWORD *)(v8 + 3864) = 0;
  *(_DWORD *)(v8 + 52) = ActiveProcessorCount;
  *(_QWORD *)(v8 + 72) = ulpBugCheckParam2;
  *(_QWORD *)(v8 + 80) = ulpBugCheckParam3;
  *(_QWORD *)(v8 + 88) = ulpBugCheckParam4;
  *(_DWORD *)(v8 + 56) = v10;
  *(_QWORD *)(v8 + 64) = a4;
  *(_DWORD *)(v8 + 3840) = -2147483645;
  *(_DWORD *)(v8 + 3844) = 1;
  *(_QWORD *)(v8 + 3856) = *(_QWORD *)(a1 + 248);
  *(_QWORD *)(v8 + 4000) = 0x40000i64;
  *(_DWORD *)(v8 + 4008) = KUSER_SHARED_DATA.SystemTime.LowPart;
  *(_DWORD *)(v8 + 4012) = KUSER_SHARED_DATA.SystemTime.High1Time;
  *(_DWORD *)(v8 + 4144) = KUSER_SHARED_DATA.InterruptTime.LowPart;
  *(_DWORD *)(v8 + 4148) = KUSER_SHARED_DATA.InterruptTime.High1Time;
  *(_DWORD *)(v8 + 3992) = 4;
  *(_DWORD *)(v8 + 4152) = 130;
  *(_DWORD *)(v8 + 4176) = 24;
  RtlGetNtProductType((_NT_PRODUCT_TYPE *)(v8 + 4160));
  v16 = 9i64;
  *(_DWORD *)(v8 + 4164) = KUSER_SHARED_DATA.SuiteMask;
  v17 = 8320;
  v18 = (_OWORD *)a1;
  *(_DWORD *)(v8 + 4180) = KUSER_SHARED_DATA.BootId;
  *(_DWORD *)(v8 + 8260) = 0;
  v19 = CmNtCSDVersion;
  *(_DWORD *)(v8 + 8256) = 0;
  *(_DWORD *)(v8 + 0x2000) = v19;
  v20 = (_OWORD *)(v8 + 840);
  *(_DWORD *)(v8 + 8196) = 0x40000;
  *(_DWORD *)(v8 + 8208) = 3840;
  *(_DWORD *)(v8 + 4152) |= 1u;
  *(_DWORD *)(v8 + 8204) = 840;
  do
  {
    *v20 = *v18;
    v20[1] = v18[1];
    v20[2] = v18[2];
    v20[3] = v18[3];
    v20[4] = v18[4];
    v20[5] = v18[5];
    v20[6] = v18[6];
    v20 += 8;
    v21 = v18[7];
    v18 += 8;
    *(v20 - 1) = v21;
    --v16;
  }
  while( v16 );
  v22 = *v18;
  LODWORD(pvDump) = 896;
  *v20 = v22;
  v20[1] = v18[1];
  v20[2] = v18[2];
  v20[3] = v18[3];
  v20[4] = v18[4];
  if( IopValidateSectionSize(0x2080ui64, (UINT64 *)&pvDump) )
  {
    *(_DWORD *)(v8 + 4152) |= 0x400u;
    *(_QWORD *)(v8 + 128) = &KdDebuggerDataBlock;
    *(_DWORD *)(v8 + 8304) = 8320;
    *(_DWORD *)(v8 + 8308) = 896;
    KdCopyDataBlock((_KDDEBUGGER_DATA64 *)(v8 + 8320));
    v17 = 9216;
  }
  LODWORD(pvDump) = 44800;
  if( IopValidateSectionSize(v17, (UINT64 *)&pvDump) )
  {
    *(_DWORD *)(v8 + 4152) |= 4u;
    *(_DWORD *)(v8 + 8220) = v17;
    memmove((VOID *)(v8 + v17), KeGetCurrentPrcb(), pvDump);
    v17 += pvDump;
  }
  LODWORD(pvDump) = 2624;
  if( IopValidateSectionSize((v17 + 7) & 0xFFFFFFF8, (UINT64 *)&pvDump) )
  {
    *(_DWORD *)(v8 + 4152) |= 8u;
    v24 = pvDump;
    v25 = v23;
    *(_DWORD *)(v8 + 8224) = v23;
    memmove((VOID *)(v8 + v23), CurrentThread->Tcb.ApcState.Process, v24);
    v17 = pvDump + v25;
  }
  LODWORD(pvDump) = 2200;
  if( IopValidateSectionSize((v17 + 7) & 0xFFFFFFF8, (UINT64 *)&pvDump) )
  {
    *(_DWORD *)(v8 + 4152) |= 0x10u;
    v27 = pvDump;
    v28 = v26;
    *(_DWORD *)(v8 + 8228) = v26;
    memmove((VOID *)(v8 + v26), CurrentThread, v27);
    v17 = pvDump + v28;
  }
  if( (*(&CurrentThread->Tcb.MiscFlags + 1) & 0x20000) != 0 )
  {
    StackLimit = CurrentThread->Tcb.StackLimit;
    StackBase = CurrentThread->Tcb.StackBase;
    v31 = *(const VOID **)(a1 + 152);
    if( (StackLimit > v31 || v31 >= StackBase) && (v31 = StackLimit, StackBase <= StackLimit) )
      v32 = 0;
    else
      v32 = (_DWORD)StackBase - (_DWORD)v31;
    if( v32 >= 0x7FFF )
      v32 = 0x7FFF;
    IopGetMaxValidSectionSize((UINT64)v31, v32);
    LODWORD(pvDump) = v33;
    if( v33 )
    {
      if( !IopValidateSectionSize(v17, (UINT64 *)&pvDump) )
        *(_DWORD *)(v8 + 8260) |= 0x100u;
      *(_DWORD *)(v8 + 4152) |= 0x20u;
      v34 = pvDump;
      v35 = pvDump;
      *(_DWORD *)(v8 + 8232) = v17;
      *(_DWORD *)(v8 + 8236) = v34;
      *(_QWORD *)(v8 + 8264) = v31;
      memmove((VOID *)(v8 + v17), v31, v35);
      v17 += v34;
    }
  }
  if( KeGetCurrentIrql() < 2u )
  {
    v36 = (_ETHREAD *)KeGetCurrentThread();
    DriverCount = 0i64;
    v37 = (v17 + 7) & 0xFFFFFFF8;
    --v36->Tcb.KernelApcDisable;
    ExAcquireResourceSharedLite((UINT64)&PsLoadedModuleResource, 1);
    if( IoGetLoadedDriverInfo(0, &DriverCount, (UINT64 *)((char *)&DriverCount + 4)) >= 0 )
    {
      v38 = DriverCount;
      LODWORD(pvDump) = 144 * DriverCount;
      if( 144 * (_DWORD)DriverCount && IopValidateSectionSize(v37, (UINT64 *)&pvDump) )
      {
        v39 = v37 + pvDump;
        LODWORD(pvDump) = (HIDWORD(DriverCount) + 7 + 6 * v38) & 0xFFFFFFF8;
        if( (_DWORD)pvDump && IopValidateSectionSize(v39, (UINT64 *)&pvDump) )
        {
          IopWriteDriverList(v8, 0, v37, v39);
          if( v40 >= 0 )
          {
            *(_DWORD *)(v8 + 4152) |= 0x40u;
            v41 = pvDump;
            *(_DWORD *)(v8 + 8240) = v37;
            *(_DWORD *)(v8 + 8244) = v38;
            *(_DWORD *)(v8 + 8248) = v39;
            v17 = v39 + v41;
            *(_DWORD *)(v8 + 8252) = v41;
          }
        }
        else
        {
          *(_DWORD *)(v8 + 8260) |= 0x100u;
        }
      }
      else
      {
        *(_DWORD *)(v8 + 8260) |= 0x100u;
      }
    }
    ExReleaseResourceLite(&PsLoadedModuleResource);
    KeLeaveCriticalRegion();
  }
  LODWORD(pvDump) = 4112;
  v42 = (v17 + 7) & 0xFFFFFFF8;
  IopValidateSectionSize(v42, (UINT64 *)&pvDump);
  if( (unsigned int)pvDump > 0x10 )
  {
    v43 = pvDump - 16;
    MaxValidSectionSizeDown = IopGetMaxValidSectionSizeDown(*(_QWORD *)(a1 + 248), (unsigned int)(pvDump - 16) >> 1);
    if( MaxValidSectionSizeDown )
    {
      v45 = (const VOID *)(*(_QWORD *)(a1 + 248) - MaxValidSectionSizeDown + 1i64);
      IopGetMaxValidSectionSize((UINT64)v45, v43);
      if( v46 )
      {
        *(_DWORD *)(v8 + 4152) |= 0x800u;
        *(_DWORD *)(v8 + 8312) = v42;
        v47 = ((_DWORD)v42 + 23) & 0xFFFFFFF8;
        *(_DWORD *)(v8 + 8316) = 1;
        *(_DWORD *)(v42 + v8 + 8) = v47;
        *(_QWORD *)(v42 + v8) = v45;
        *(_DWORD *)(v42 + v8 + 12) = v46;
        memmove((VOID *)(v8 + v47), v45, v46);
      }
    }
  }
  *(_DWORD *)(v8 + 8200) = 262140;
  result = 0x40000;
  *(_DWORD *)(v8 + 262140) = 1145524820;
  return result;
}

Referenced by:

DbgkpWerCaptureLiveTriageDump
LkmdTelCreateReport