PspCaptureUserProcessParameters

NTSTATUS __stdcall PspCaptureUserProcessParameters(
        _RTL_USER_PROCESS_PARAMETERS **CapturedProcessParameters,
        _RTL_USER_PROCESS_PARAMETERS *UserProcessParameters,
        UINT64 ControlFlags){
  char v3; 
  _RTL_USER_PROCESS_PARAMETERS *v5; 
  unsigned int v6; 
  char *Environment; 
  unsigned __int64 EnvironmentSize; 
  NTSTATUS result; 
  unsigned __int64 v10; 
  UINT64 v11; 
  signed int v12; 
  _OWORD *PoolWithQuotaTag; 
  _OWORD *v14; 
  __int64 v15; 
  const VOID *v16; 
  char *v17; 
  unsigned __int64 v18; 
  _ESERVERSILO_GLOBALS *ServerSiloGlobals; 
  char v20; 
  unsigned __int64 v21; 
  WCHAR *BufferStart; 
  VOID *v23[2]; 
  unsigned int v24; 
  VOID *v25; 
  VOID *Src; 
  size_t Size[2]; 
  unsigned __int64 v28; 
  _OWORD *v29; 
  _UNICODE_STRING DestString; 
  _UNICODE_STRING v31; 
  _UNICODE_STRING SourceString; 
  _UNICODE_STRING v33; 
  _UNICODE_STRING v34; 
  _UNICODE_STRING v35; 
  _UNICODE_STRING v36; 
  _UNICODE_STRING v37; 
  VOID *v38[10]; 
  char v40; 
  _EJOB *Silo; 

  v40 = v3;
  v5 = UserProcessParameters;
  v34 = 0i64;
  DestString = 0i64;
  v36 = 0i64;
  SourceString = 0i64;
  v25 = 0i64;
  v33 = 0i64;
  v31 = 0i64;
  *(_OWORD *)v23 = 0i64;
  v37 = 0i64;
  v35 = 0i64;
  if( ((unsigned __int8)UserProcessParameters & 3) != 0 )
    ExRaiseDatatypeMisalignment();
  v6 = UserProcessParameters->Flags & 0xFFFFBFFF;
  v24 = v6;
  if( ((v6 ^ 1) & 0xF7010E11) != 0 )
    return -1073741811;
  if( ((unsigned __int8)v6 & (unsigned __int8)((v6 & 0xE0) - 1) & 0x60) != 0 )
    return -1073741811;
  Environment = (char *)UserProcessParameters->Environment;
  Src = Environment;
  v25 = Environment;
  EnvironmentSize = UserProcessParameters->EnvironmentSize;
  *(_QWORD *)Size = EnvironmentSize;
  if( !EnvironmentSize || (EnvironmentSize & 1) != 0 )
    return -1073741811;
  if( (unsigned __int64)&Environment[EnvironmentSize] > 0x7FFFFFFF0000i64
    || &Environment[EnvironmentSize] < Environment )
  {
    MEMORY[0x7FFFFFFF0000] = 0;
  }
  if( (v3 & 1) != 0 )
  {
    ServerSiloGlobals = PsGetServerSiloGlobals(Silo);
    DestString = ServerSiloGlobals->PsProtectedCurrentDirectory;
    *(_OWORD *)v23 = PspProtectedRuntimeData;
    if( (v20 & 2) == 0 )
    {
      Src = ServerSiloGlobals->PsProtectedEnvironment.Buffer;
      v25 = Src;
      *(_QWORD *)Size = ServerSiloGlobals->PsProtectedEnvironment.MaximumLength;
    }
  }
  else
  {
    result = PspCaptureAndValidateUnicodeString(&UserProcessParameters->CurrentDirectory.DosPath, &DestString);
    if( result < 0 )
      return result;
    if( DestString.Length >= 0x208u )
      return -1073741811;
    DestString.MaximumLength = 520;
    *(_UNICODE_STRING *)v23 = v5->RuntimeData;
    if( v23[1] )
    {
      WORD1(v23[0]) = v23[0];
      if( LOWORD(v23[0])
        && ((char *)v23[1] + LOWORD(v23[0]) > (VOID *)0x7FFFFFFF0000i64 || (char *)v23[1] + LOWORD(v23[0]) < v23[1]) )
      {
        MEMORY[0x7FFFFFFF0000] = 0;
      }
    }
    else
    {
      if( LOWORD(v23[0]) )
        return -1073741811;
      LODWORD(v23[0]) = 0;
    }
  }
  result = PspCaptureAndValidateUnicodeString(&v5->DllPath, &SourceString);
  if( result < 0 )
    return result;
  result = PspCaptureAndValidateUnicodeString(&v5->ImagePathName, &v33);
  if( result < 0 )
    return result;
  result = PspCaptureAndValidateUnicodeString(&v5->CommandLine, &v34);
  if( result < 0 )
    return result;
  result = PspCaptureAndValidateUnicodeString(&v5->WindowTitle, &v35);
  if( result < 0 )
    return result;
  result = PspCaptureAndValidateUnicodeString(&v5->DesktopInfo, &v36);
  if( result < 0 )
    return result;
  result = PspCaptureAndValidateUnicodeString(&v5->ShellInfo, &v37);
  if( result < 0 )
    return result;
  if( ControlFlags && (*(_DWORD *)(ControlFlags + 4) & 2) != 0 )
  {
    v31 = *(_UNICODE_STRING *)(ControlFlags + 8);
  }
  else
  {
    result = PspCaptureAndValidateUnicodeString(&v5->RedirectionDllName, &v31);
    if( result < 0 )
      return result;
  }
  if( ControlFlags && (*(_DWORD *)(ControlFlags + 4) & 4) != 0 )
    *(_OWORD *)v38 = *(_OWORD *)(ControlFlags + 24);
  else
    *(_OWORD *)v38 = 0i64;
  v10 = (WORD1(v23[0])
       + SourceString.MaximumLength
       + v33.MaximumLength
       + v34.MaximumLength
       + v35.MaximumLength
       + v36.MaximumLength
       + v37.MaximumLength
       + v31.MaximumLength
       + (unsigned __int64)WORD1(v38[0])
       + DestString.MaximumLength
       + 1089i64) & 0xFFFFFFFFFFFFFFFEui64;
  v28 = v10;
  if( ControlFlags && (*(_DWORD *)(ControlFlags + 4) & 1) != 0 )
  {
    v21 = (v10 + 3) & 0xFFFFFFFFFFFFFFFCui64;
    v10 = v21 + 8i64 * *(unsigned int *)(ControlFlags + 48);
    if( v10 >= v21 )
    {
      v28 = v21 + 8i64 * *(unsigned int *)(ControlFlags + 48);
      goto LABEL_31;
    }
    return -1073741811;
  }
LABEL_31:
  v11 = -1i64;
  if( v10 + *(_QWORD *)Size >= v10 )
    v11 = v10 + *(_QWORD *)Size;
  v12 = v10 + *(_QWORD *)Size < v10 ? 0xC0000095 : 0;
  if( v10 + *(_QWORD *)Size < v10 )
    return -1073741811;
  PoolWithQuotaTag = ExAllocatePoolWithQuotaTag((POOL_TYPE)520, v11, 0x62507350ui64);
  v14 = PoolWithQuotaTag;
  v29 = PoolWithQuotaTag;
  if( !PoolWithQuotaTag )
    return -1073741670;
  v15 = 8i64;
  do
  {
    *PoolWithQuotaTag = *(_OWORD *)&v5->MaximumLength;
    PoolWithQuotaTag[1] = *(_OWORD *)&v5->ConsoleHandle;
    PoolWithQuotaTag[2] = *(_OWORD *)&v5->StandardInput;
    PoolWithQuotaTag[3] = *(_OWORD *)&v5->StandardError;
    PoolWithQuotaTag[4] = *(_OWORD *)&v5->CurrentDirectory.DosPath.Buffer;
    PoolWithQuotaTag[5] = v5->DllPath;
    PoolWithQuotaTag[6] = v5->ImagePathName;
    PoolWithQuotaTag += 8;
    *(PoolWithQuotaTag - 1) = v5->CommandLine;
    v5 = (_RTL_USER_PROCESS_PARAMETERS *)((char *)v5 + 128);
    --v15;
  }
  while( v15 );
  *PoolWithQuotaTag = *(_OWORD *)&v5->MaximumLength;
  PoolWithQuotaTag[1] = *(_OWORD *)&v5->ConsoleHandle;
  PoolWithQuotaTag[2] = *(_OWORD *)&v5->StandardInput;
  PoolWithQuotaTag[3] = *(_OWORD *)&v5->StandardError;
  if( v12 < 0 )
    goto LABEL_84;
  *((_DWORD *)v14 + 2) = v6;
  *((_DWORD *)v14 + 1) = v10;
  *(_DWORD *)v14 = v10;
  BufferStart = (WCHAR *)(v14 + 68);
  if( ControlFlags && (*(_DWORD *)(ControlFlags + 4) & 8) != 0 )
    *((_DWORD *)v14 + 271) = *(_DWORD *)(ControlFlags + 52);
  v12 = PspCopyUnicodeString((const VOID **)&DestString, (_UNICODE_STRING *)((char *)v14 + 56), (VOID **)&BufferStart);
  if( v12 < 0 )
    goto LABEL_84;
  v12 = PspCopyUnicodeString((const VOID **)&SourceString, (_UNICODE_STRING *)v14 + 5, (VOID **)&BufferStart);
  if( v12 < 0 )
    goto LABEL_84;
  v12 = PspCopyUnicodeString((const VOID **)&v33, (_UNICODE_STRING *)v14 + 6, (VOID **)&BufferStart);
  if( v12 < 0 )
    goto LABEL_84;
  v12 = PspCopyUnicodeString((const VOID **)&v34, (_UNICODE_STRING *)v14 + 7, (VOID **)&BufferStart);
  if( v12 < 0 )
    goto LABEL_84;
  v12 = PspCopyUnicodeString((const VOID **)&v35, (_UNICODE_STRING *)v14 + 11, (VOID **)&BufferStart);
  if( v12 < 0 )
    goto LABEL_84;
  v12 = PspCopyUnicodeString((const VOID **)&v36, (_UNICODE_STRING *)v14 + 12, (VOID **)&BufferStart);
  if( v12 < 0 )
    goto LABEL_84;
  v12 = PspCopyUnicodeString((const VOID **)&v37, (_UNICODE_STRING *)v14 + 13, (VOID **)&BufferStart);
  if( v12 < 0 )
    goto LABEL_84;
  PspCopyUnicodeString((const VOID **)&v31, (_UNICODE_STRING *)v14 + 65, (VOID **)&BufferStart);
  if( ControlFlags && (*(_DWORD *)(ControlFlags + 4) & 4) != 0 )
    PspCopyUnicodeString((const VOID **)v38, (_UNICODE_STRING *)v14 + 66, (VOID **)&BufferStart);
  else
    v14[66] = 0i64;
  v14[14] = *(_OWORD *)v23;
  v16 = v23[1];
  v17 = (char *)BufferStart;
  if( v23[1] )
  {
    *((_QWORD *)v14 + 29) = BufferStart;
    memmove(v17, v16, LOWORD(v23[0]));
    if( v17 )
    {
      v17 += LOWORD(v23[0]);
      BufferStart = (WCHAR *)v17;
    }
  }
  *((_QWORD *)v14 + 134) = 0i64;
  *((_DWORD *)v14 + 270) = 0;
  if( ControlFlags )
  {
    if( (*(_DWORD *)(ControlFlags + 4) & 1) != 0 )
    {
      v17 = (char *)((unsigned __int64)(v17 + 3) & 0xFFFFFFFFFFFFFFFCui64);
      BufferStart = (WCHAR *)v17;
      *((_QWORD *)v14 + 134) = v17;
      *((_DWORD *)v14 + 270) = *(_DWORD *)(ControlFlags + 48);
      memmove(v17, *(const VOID **)(ControlFlags + 40), 8 * *(_DWORD *)(ControlFlags + 48));
      if( v17 )
      {
        v17 += 8 * *(unsigned int *)(ControlFlags + 48);
        BufferStart = (WCHAR *)v17;
      }
    }
  }
  v18 = (char *)v14 - v17 + v10;
  if( v18 )
  {
    memset(v17, 0i64, v18);
    if( v17 )
    {
      v17 += v18;
      BufferStart = (WCHAR *)v17;
    }
  }
  memmove(v17, Src, Size[0]);
  if( (v40 & 3) == 1 || (v12 = PspValidateEnvironmentBlock((WCHAR *)v17, (UINT64 *)Size), v12 >= 0) )
  {
    if( (v40 & 1) != 0 )
    {
      *((_QWORD *)v14 + 2) = 0i64;
      *((_QWORD *)v14 + 4) = 0i64;
      *((_QWORD *)v14 + 5) = 0i64;
      *((_QWORD *)v14 + 6) = 0i64;
    }
    *((_QWORD *)v14 + 16) = v17;
    *((_QWORD *)v14 + 126) = *(_QWORD *)Size;
    *((_QWORD *)v14 + 127) = 0i64;
    *CapturedProcessParameters = (_RTL_USER_PROCESS_PARAMETERS *)v14;
    return 0;
  }
  else
  {
LABEL_84:
    ExFreePoolWithTag(v14, 0);
    return v12;
  }
}

Referenced by:

PsCaptureUserProcessParameters
PspCaptureProcessParameters