LpcpCopyRequestData

NTSTATUS __fastcall LpcpCopyRequestData(
        char a1,
        VOID *a2,
        __int64 a3,
        UINT64 *a4,
        char *Address,
        UINT64 Length,
        UINT64 *a7){
  unsigned __int64 v7; 
  _OBJECT_HANDLE_INFORMATION *HandleInformation; 
  char PreviousMode; 
  unsigned __int64 v13; 
  UINT64 *v14; 
  UINT64 *v15; 
  NTSTATUS result; 
  _KALPC_MESSAGE **v17; 
  NTSTATUS v18; 
  __int64 v19; 
  unsigned __int64 v20; 
  __int64 v21; 
  __int64 v22; 
  unsigned __int64 v23; 
  unsigned __int64 v24; 
  _ETHREAD *CurrentThread; 
  _EPROCESS *Process; 
  char *v27; 
  _EPROCESS *v28; 
  char *v29; 
  int v30; 
  PVOID PrimaryToken; 
  UINT64 NumberOfBytesRead; 
  VOID *FromAddress[2]; 
  PORT_MESSAGE CapturedMessage[4]; 
  UINT64 MessageId[2]; 
  UINT64 CallbackId; 

  v7 = (unsigned int)a4;
  HandleInformation = 0i64;
  *(_OWORD *)CapturedMessage = 0i64;
  *(_OWORD *)MessageId = 0i64;
  CallbackId = 0i64;
  *(_OWORD *)FromAddress = 0i64;
  NumberOfBytesRead = 0i64;
  PreviousMode = KeGetCurrentThread()->PreviousMode;
  if( PreviousMode )
  {
    v13 = Length;
    if( a1 )
    {
      if( Length && ((unsigned __int64)&Address[Length] > 0x7FFFFFFF0000i64 || &Address[Length] < Address) )
        MEMORY[0x7FFFFFFF0000] = 0;
    }
    else
    {
      ProbeForWrite((UINT64)Address, Length, 1i64);
    }
    AlpcpProbeAndCaptureMessageHeader((PORT_MESSAGE *)a3, CapturedMessage, 0i64);
    v15 = a7;
    if( a7 )
    {
      if( a7 < v14 )
        v14 = a7;
      *v14 = *v14;
    }
  }
  else
  {
    *(_OWORD *)CapturedMessage = *(_OWORD *)a3;
    *(_OWORD *)MessageId = *(_OWORD *)(a3 + 16);
    CallbackId = *(_QWORD *)(a3 + 32);
    v15 = a7;
    v13 = Length;
  }
  if( !HIWORD(CapturedMessage[1]) )
    return -1073741811;
  PrimaryToken = HandleInformation;
  result = ObReferenceObjectByHandle(a2, 1ui64, AlpcPortObjectType, PreviousMode, &PrimaryToken, HandleInformation);
  if( result >= 0 )
  {
    v18 = AlpcpLookupMessage((_ALPC_PORT *)PrimaryToken, LODWORD(MessageId[1]), (unsigned int)CallbackId, v17);
    if( v18 < 0 )
    {
LABEL_35:
      PsDereferencePrimaryToken(PrimaryToken);
      return v18;
    }
    v19 = MEMORY[0x20];
    if( MEMORY[0x20] )
    {
      v18 = -1073741811;
      if( MEMORY[0xF6] )
      {
        LODWORD(v20) = AlpcpAvailableBufferSize(0i64);
        v24 = *(unsigned __int16 *)(v21 + 242);
        if( v20 <= v24 )
          v24 = v20;
        if( v23 >= v24 || v7 >= (v24 - v23) >> 4 )
          goto LABEL_34;
        if( *(_DWORD *)(v21 + v22 + 240) > (unsigned int)v7 )
        {
          *(_OWORD *)FromAddress = *(_OWORD *)(v21 + v22 + 16 * v7 + 248);
          v18 = (unsigned int)_mm_cvtsi128_si32(_mm_srli_si128(*(__m128i *)FromAddress, 8)) < v13 ? 0xC000000D : 0;
        }
      }
      if( v18 >= 0 )
      {
        CurrentThread = (_ETHREAD *)KeGetCurrentThread();
        if( a1 )
        {
          Process = CurrentThread->Tcb.ApcState.Process;
          v27 = (char *)FromAddress[0];
          v28 = *(_EPROCESS **)(v19 + 544);
          v29 = Address;
        }
        else
        {
          v28 = CurrentThread->Tcb.ApcState.Process;
          v27 = Address;
          v29 = (char *)FromAddress[0];
          Process = *(_EPROCESS **)(v19 + 544);
        }
        MmCopyVirtualMemory(Process, v29, v28, v27, v13, PreviousMode, &NumberOfBytesRead);
        v18 = v30;
        if( v30 >= 0 )
        {
          if( v15 )
            *v15 = NumberOfBytesRead;
        }
      }
    }
    else
    {
      v18 = -1073741790;
    }
LABEL_34:
    AlpcpUnlockMessage(0i64);
    goto LABEL_35;
  }
  return result;
}

Referenced by:

NtReadRequestData
NtWriteRequestData