IoIsValidNameGraftingBuffer

BOOLEAN __stdcall IoIsValidNameGraftingBuffer(PIRP Irp, PREPARSE_DATA_BUFFER ReparseBuffer){
  WCHAR v2; 
  __int64 v3; 
  unsigned int v5; 
  USHORT SubstituteNameLength; 
  WCHAR v7; 
  wchar_t *PoolWithTag; 
  wchar_t *v9; 
  NTSTATUS v11; 
  USHORT v12; 
  WCHAR v13; 
  __int16 v14; 
  void *LinkHandle; 
  struct _UNICODE_STRING LinkTarget; 
  struct _UNICODE_STRING DestinationString; 
  struct _OBJECT_ATTRIBUTES ObjectAttributes; 
  WCHAR SourceString[8]; 
  v3 = *((_QWORD *)Irp + 23);
  DestinationString = 0i64;
  v5 = *(_DWORD *)(v3 + 8);
  if( v5
    && v5 < ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength
          + (unsigned int)ReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength
          + 20 )
  {
    return 0;
  }
  SubstituteNameLength = ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
  if( SubstituteNameLength > 6u
    && ReparseBuffer->MountPointReparseBuffer.PathBuffer[0] == 92
    && *((_WORD *)&ReparseBuffer->GenericReparseBuffer + 5) == 92 )
  {
    v7 = ReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer[0];
    if( v7 != 46 && v7 != 63 )
      return 0;
  }
  if( SubstituteNameLength > 0x10u
    && ReparseBuffer->MountPointReparseBuffer.PathBuffer[0] == 92
    && *((_WORD *)&ReparseBuffer->GenericReparseBuffer + 5) == 63
    && ReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer[0] == 63
    && *((_WORD *)&ReparseBuffer->GenericReparseBuffer + 7) == 92
    && LOWORD(ReparseBuffer[1].ReparseTag) == 85
    && HIWORD(ReparseBuffer[1].ReparseTag) == 78
    && ReparseBuffer[1].ReparseDataLength == 67
    && ReparseBuffer[1].Reserved == 92 )
  {
    return 0;
  }
  if( SubstituteNameLength > 0xCu
    && ReparseBuffer->MountPointReparseBuffer.PathBuffer[0] == 92
    && *((_WORD *)&ReparseBuffer->GenericReparseBuffer + 5) == 63
    && ReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer[0] == 63
    && *((_WORD *)&ReparseBuffer->GenericReparseBuffer + 7) == 92
    && HIWORD(ReparseBuffer[1].ReparseTag) == 58 )
  {
    *(_DWORD *)(&LinkTarget.MaximumLength + 1) = 0;
    *(&ObjectAttributes.Length + 1) = 0;
    *(_OWORD *)SourceString = *(_OWORD *)L"\\??\\C:";
    *(&ObjectAttributes.Attributes + 1) = 0;
    LinkHandle = 0i64;
    RtlInitUnicodeString(&DestinationString, SourceString, v2);
    DestinationString.Buffer[4] = ReparseBuffer[1].ReparseTag;
    ObjectAttributes.ObjectName = &DestinationString;
    ObjectAttributes.Length = 48;
    ObjectAttributes.RootDirectory = 0i64;
    ObjectAttributes.Attributes = 576;
    *(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
    if( ZwOpenSymbolicLinkObject(&LinkHandle, 1ui64, &ObjectAttributes) >= 0 )
    {
      PoolWithTag = (wchar_t *)ExAllocatePoolWithTag(NonPagedPoolNx, 0x208ui64, 0x20206F49ui64);
      v9 = PoolWithTag;
      if( !PoolWithTag )
      {
        ZwClose(LinkHandle);
        return 0;
      }
      LinkTarget.Buffer = PoolWithTag;
      *(_DWORD *)&LinkTarget.Length = 34078720;
      v11 = ZwQuerySymbolicLinkObject(LinkHandle, &LinkTarget, 0i64);
      ZwClose(LinkHandle);
      if( v11 >= 0
        && *LinkTarget.Buffer == 92
        && LinkTarget.Buffer[1] == 68
        && LinkTarget.Buffer[2] == 101
        && LinkTarget.Buffer[3] == 118
        && LinkTarget.Buffer[4] == 105
        && LinkTarget.Buffer[5] == 99
        && LinkTarget.Buffer[6] == 101
        && LinkTarget.Buffer[7] == 92
        && LinkTarget.Buffer[8] == 76
        && LinkTarget.Buffer[9] == 97
        && LinkTarget.Buffer[10] == 110
        && LinkTarget.Buffer[14] == 82
        && LinkTarget.Buffer[15] == 101
        && LinkTarget.Buffer[16] == 100
        && LinkTarget.Buffer[17] == 105
        && LinkTarget.Buffer[18] == 114
        && LinkTarget.Buffer[23] == 114
        && LinkTarget.Buffer[24] == 92 )
      {
        ExFreePoolWithTag(v9, 0);
        return 0;
      }
      ExFreePoolWithTag(v9, 0);
    }
  }
  v12 = ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
  if( v12 < 0xCu )
    return 0;
  v13 = ReparseBuffer->MountPointReparseBuffer.PathBuffer[0];
  if( v13 != 92
    || *((_WORD *)&ReparseBuffer->GenericReparseBuffer + 5) != 63
    || ReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer[0] != 63
    || *((_WORD *)&ReparseBuffer->GenericReparseBuffer + 7) != 92
    || HIWORD(ReparseBuffer[1].ReparseTag) != 58 )
  {
    if( v12 != 96 && (v12 != 98 || ReparseBuffer[4].MountPointReparseBuffer.PathBuffer[0] != 92) )
      return 0;
    if( v13 != 92 )
      return 0;
    v14 = *((_WORD *)&ReparseBuffer->GenericReparseBuffer + 5);
    if( v14 != 63 && v14 != 92 )
      return 0;
    if( ReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer[0] != 63
      || *((_WORD *)&ReparseBuffer->GenericReparseBuffer + 7) != 92
      || LOWORD(ReparseBuffer[1].ReparseTag) != 86
      || HIWORD(ReparseBuffer[1].ReparseTag) != 111
      || ReparseBuffer[1].ReparseDataLength != 108
      || ReparseBuffer[1].Reserved != 117
      || ReparseBuffer[1].SymbolicLinkReparseBuffer.SubstituteNameOffset != 109
      || ReparseBuffer[1].SymbolicLinkReparseBuffer.SubstituteNameLength != 101
      || ReparseBuffer[1].SymbolicLinkReparseBuffer.PrintNameOffset != 123
      || ReparseBuffer[2].Reserved != 45
      || ReparseBuffer[2].MountPointReparseBuffer.PathBuffer[0] != 45
      || HIWORD(ReparseBuffer[3].ReparseTag) != 45
      || ReparseBuffer[3].SymbolicLinkReparseBuffer.PrintNameOffset != 45
      || ReparseBuffer[4].SymbolicLinkReparseBuffer.PrintNameLength != 125 )
    {
      return 0;
    }
  }
  return 1;
}

Referenced by:

No references.