Exemple #1
0
NTSTATUS validatePePointer(PVOID pImageBase, PVOID pArbitraryPtr, ULONGLONG accessLength, BOOLEAN isNewImage){
	UNREFERENCED_PARAMETER(accessLength);
	MEMORY_BASIC_VLM_INFORMATION vlmImageInfo;
	ULONGLONG returnLen = 0;
	NTSTATUS status = 0;

	static ULONGLONG peSize = 0;
	if (!peSize || isNewImage){
		status = NtQueryVirtualMemory(INVALID_HANDLE_VALUE, pImageBase, MemoryBasicVlmInformation, &vlmImageInfo, sizeof(MEMORY_BASIC_VLM_INFORMATION), &returnLen);
		if (status)
			return status;

		peSize = vlmImageInfo.SizeOfImage;
	}

	///The viability of this pointer validation is based on three assumptions:
	///1. Each mapped section of the image is at least readable (R) without guard (+G).
	///2. There don't exist any free pages between two sections of the same image.
	if ((pImageBase < ALIGN_DOWN_POINTER(pArbitraryPtr, PVOID)) && (((PUCHAR)ALIGN_UP_POINTER(pArbitraryPtr, PVOID) + accessLength) < ((PUCHAR)pImageBase + peSize)))
		return STATUS_SUCCESS;

	return STATUS_INVALID_ADDRESS;
}
Exemple #2
0
VOID
NTAPI
IopLogWorker(IN PVOID Parameter)
{
    PELF_API_MSG Message;
    PIO_ERROR_LOG_MESSAGE ErrorMessage;
    PLIST_ENTRY ListEntry;
    PERROR_LOG_ENTRY LogEntry;
    PIO_ERROR_LOG_PACKET Packet;
    PCHAR StringBuffer;
    ULONG RemainingLength;
    PDRIVER_OBJECT DriverObject;
    ULONG DriverNameLength = 0, DeviceNameLength;
    UNICODE_STRING DriverNameString;
    NTSTATUS Status;
    UCHAR Buffer[256];
    POBJECT_NAME_INFORMATION ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
    POBJECT_NAME_INFORMATION PoolObjectNameInfo = NULL;
    ULONG ReturnedLength, MessageLength;
    PWCHAR p;
    ULONG ExtraStringLength;
    PAGED_CODE();

    /* Connect to the port */
    if (!IopConnectLogPort()) return;

    /* Allocate the message */
    Message = ExAllocatePool(PagedPool, IO_ERROR_LOG_MESSAGE_LENGTH);
    if (!Message)
    {
        /* Couldn't allocate, try again */
        IopRestartLogWorker();
        return;
    }

    /* Copy the message */
    RtlZeroMemory(Message, sizeof(ELF_API_MSG));

    /* Get the actual I/O Structure */
    ErrorMessage = &Message->IoErrorMessage;

    /* Start loop */
    while (TRUE)
    {
        /* Get an entry */
        ListEntry = IopGetErrorLogEntry();
        if (!ListEntry) break;
        LogEntry = CONTAINING_RECORD(ListEntry, ERROR_LOG_ENTRY, ListEntry);

        /* Get pointer to the log packet */
        Packet = (PIO_ERROR_LOG_PACKET)((ULONG_PTR)LogEntry +
                                        sizeof(ERROR_LOG_ENTRY));

        /* Calculate the total length of the message only */
        MessageLength = sizeof(IO_ERROR_LOG_MESSAGE) -
                        sizeof(ERROR_LOG_ENTRY) -
                        sizeof(IO_ERROR_LOG_PACKET) +
                        LogEntry->Size;

        /* Copy the packet */
        RtlCopyMemory(&ErrorMessage->EntryData,
                      Packet,
                      LogEntry->Size - sizeof(ERROR_LOG_ENTRY));

        /* Set the timestamp and time */
        ErrorMessage->TimeStamp = LogEntry->TimeStamp;
        ErrorMessage->Type = IO_TYPE_ERROR_MESSAGE;

        /* Check if this message has any strings */
        if (Packet->NumberOfStrings)
        {
            /* String buffer is after the current strings */
            StringBuffer = (PCHAR)&ErrorMessage->EntryData +
                            Packet->StringOffset;
        }
        else
        {
            /* Otherwise, string buffer is at the end */
            StringBuffer = (PCHAR)ErrorMessage + MessageLength;
        }

        /* Align the buffer */
        StringBuffer = ALIGN_UP_POINTER(StringBuffer, WCHAR);

        /* Set the offset for the driver's name to the current buffer */
        ErrorMessage->DriverNameOffset = (ULONG)(StringBuffer -
                                                (PCHAR)ErrorMessage);

        /* Check how much space we have left for the device string */
        RemainingLength = (ULONG)((ULONG_PTR)Message +
                                  IO_ERROR_LOG_MESSAGE_LENGTH -
                                  (ULONG_PTR)StringBuffer);

        /* Now check if there is a driver object */
        DriverObject = LogEntry->DriverObject;
        if (DriverObject)
        {
            /* Check if the driver has a name */
            if (DriverObject->DriverName.Buffer)
            {
                /* Use its name */
                DriverNameString.Buffer = DriverObject->DriverName.Buffer;
                DriverNameLength = DriverObject->DriverName.Length;
            }
            else
                DriverNameString.Buffer = NULL;

            /* Check if there isn't a valid name*/
            if (!DriverNameLength)
            {
                /* Query the name directly */
                Status = ObQueryNameString(DriverObject,
                                           ObjectNameInfo,
                                           sizeof(Buffer),
                                           &ReturnedLength);
                if (!(NT_SUCCESS(Status)) || !(ObjectNameInfo->Name.Length))
                {
                    /* We don't have a name */
                    DriverNameLength = 0;
                }
            }
        }
        else
        {
            /* Use default name */
            DriverNameString.Buffer = L"Application Popup";
            DriverNameLength = (ULONG)wcslen(DriverNameString.Buffer) * sizeof(WCHAR);
        }

        /* Check if we have a driver name by here */
        if (DriverNameLength)
        {
            /* Skip to the end of the driver's name */
            p = &DriverNameString.Buffer[DriverNameLength / sizeof(WCHAR)];

            /* Now we'll walk backwards and assume the minimum size */
            DriverNameLength = sizeof(WCHAR);
            p--;
            while ((*p != L'\\') && (p != DriverNameString.Buffer))
            {
                /* No backslash found, keep going */
                p--;
                DriverNameLength += sizeof(WCHAR);
            }

            /* Now we probably hit the backslash itself, skip past it */
            if (*p == L'\\')
            {
                p++;
                DriverNameLength -= sizeof(WCHAR);
            }

            /*
             * Now make sure that the driver name fits in our buffer, minus 3
             * NULL chars, and copy the name in our string buffer
             */
            DriverNameLength = min(DriverNameLength,
                                   RemainingLength - 3 * sizeof(UNICODE_NULL));
            RtlCopyMemory(StringBuffer, p, DriverNameLength);
        }

        /* Null-terminate the driver name */
        *((PWSTR)(StringBuffer + DriverNameLength)) = L'\0';
        DriverNameLength += sizeof(WCHAR);

        /* Go to the next string buffer position */
        StringBuffer += DriverNameLength;
        RemainingLength -= DriverNameLength;

        /* Update the string offset and check if we have a device object */
        ErrorMessage->EntryData.StringOffset = (USHORT)
                                               ((ULONG_PTR)StringBuffer -
                                               (ULONG_PTR)ErrorMessage);
        if (LogEntry->DeviceObject)
        {
            /* We do, query its name */
            Status = ObQueryNameString(LogEntry->DeviceObject,
                                       ObjectNameInfo,
                                       sizeof(Buffer),
                                       &ReturnedLength);
            if (!NT_SUCCESS(Status) || (ObjectNameInfo->Name.Length == 0))
            {
                /* Setup an empty name */
                ObjectNameInfo->Name.Length = 0;
                ObjectNameInfo->Name.Buffer = L"";

                /* Check if we failed because our buffer wasn't large enough */
                if (Status == STATUS_INFO_LENGTH_MISMATCH)
                {
                    /* Then we'll allocate one... we really want this name! */
                    PoolObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
                                                               ReturnedLength,
                                                               TAG_IO);
                    if (PoolObjectNameInfo)
                    {
                        /* Query it again */
                        ObjectNameInfo = PoolObjectNameInfo;
                        Status = ObQueryNameString(LogEntry->DeviceObject,
                                                   ObjectNameInfo,
                                                   ReturnedLength,
                                                   &ReturnedLength);
                        if (NT_SUCCESS(Status))
                        {
                            /* Success, update the information */
                            ObjectNameInfo->Name.Length =
                                100 - (USHORT)DriverNameLength;
                        }
                    }
                }
            }
        }
        else
        {
            /* No device object, setup an empty name */
            ObjectNameInfo->Name.Length = 0;
            ObjectNameInfo->Name.Buffer = L"";
        }

        /*
         * Now make sure that the device name fits in our buffer, minus 2
         * NULL chars, and copy the name in our string buffer
         */
        DeviceNameLength = min(ObjectNameInfo->Name.Length,
                               RemainingLength - 2 * sizeof(UNICODE_NULL));
        RtlCopyMemory(StringBuffer,
                      ObjectNameInfo->Name.Buffer,
                      DeviceNameLength);

        /* Null-terminate the device name */
        *((PWSTR)(StringBuffer + DeviceNameLength)) = L'\0';
        DeviceNameLength += sizeof(WCHAR);

        /* Free the buffer if we had one */
        if (PoolObjectNameInfo)
        {
            ExFreePool(PoolObjectNameInfo);
            PoolObjectNameInfo = NULL;
            ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
        }

        /* Go to the next string buffer position */
        ErrorMessage->EntryData.NumberOfStrings++;
        StringBuffer += DeviceNameLength;
        RemainingLength -= DeviceNameLength;

        /* Check if we have any extra strings */
        if (Packet->NumberOfStrings)
        {
            /* Find out the size of the extra strings */
            ExtraStringLength = LogEntry->Size -
                                sizeof(ERROR_LOG_ENTRY) -
                                Packet->StringOffset;

            /* Make sure that the extra strings fit in our buffer */
            if (ExtraStringLength > (RemainingLength - sizeof(UNICODE_NULL)))
            {
                /* They wouldn't, so set normalize the length */
                MessageLength -= ExtraStringLength - RemainingLength;
                ExtraStringLength = RemainingLength - sizeof(UNICODE_NULL);
            }

            /* Now copy the extra strings */
            RtlCopyMemory(StringBuffer,
                          (PCHAR)Packet + Packet->StringOffset,
                          ExtraStringLength);

            /* Null-terminate them */
            *((PWSTR)(StringBuffer + ExtraStringLength)) = L'\0';
        }

        /* Set the driver name length */
        ErrorMessage->DriverNameLength = (USHORT)DriverNameLength;

        /* Update the message length to include the device and driver names */
        MessageLength += DeviceNameLength + DriverNameLength;
        ErrorMessage->Size = (USHORT)MessageLength;

        /* Now update it again, internally, for the size of the actual LPC */
        MessageLength += (FIELD_OFFSET(ELF_API_MSG, IoErrorMessage) -
                          FIELD_OFFSET(ELF_API_MSG, Unknown[0]));

        /* Set the total and data lengths */
        Message->h.u1.s1.TotalLength = (USHORT)(sizeof(PORT_MESSAGE) +
                                                MessageLength);
        Message->h.u1.s1.DataLength = (USHORT)(MessageLength);

        /* Send the message */
        Status = NtRequestPort(IopLogPort, (PPORT_MESSAGE)Message);
        if (!NT_SUCCESS(Status))
        {
            /* Requeue log message and restart the worker */
            ExInterlockedInsertTailList(&IopErrorLogListHead,
                                        &LogEntry->ListEntry,
                                        &IopLogListLock);
            IopLogWorkerRunning = FALSE;
            IopRestartLogWorker();
            break;
        }

        /* Dereference the device object */
        if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject);
        if (DriverObject) ObDereferenceObject(LogEntry->DriverObject);

        /* Update size */
        InterlockedExchangeAdd(&IopTotalLogSize,
                               -(LONG)(LogEntry->Size -
                                       sizeof(ERROR_LOG_ENTRY)));
    }

    /* Free the LPC Message */
    ExFreePool(Message);
}
static pool_t *pool_create(int size,int num_elems) {
    pool_t *pool=calloc(1,sizeof(pool_t));
    pool->size=ALIGN_UP_POINTER(size);;
    pool_addelems(pool,num_elems);
    return pool;
}