ZwReadFile STATUS_INVALID_PARAMETER

calling this in in a work item queued in a post close operation , or even from pre close , always getting STATUS_INVALID_PARAMETER on the ZwReadFile call , any idea why ?

  OBJECT_ATTRIBUTES objAttr;
    IO_STATUS_BLOCK ioStatusBlock;
    HANDLE FileHandle = nullptr;
    NTSTATUS status;
    FILE_STANDARD_INFORMATION fileInfo;

    InitializeObjectAttributes(&objAttr, &FileName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);

    // Open the file
    status = ZwCreateFile(&FileHandle, FILE_ALL_ACCESS, &objAttr, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0);

    if (!NT_SUCCESS(status) || FileHandle == nullptr)
    {
        DbgPrint("[*] failed create file with 0x%x\n", status);
        return 0;
    }
    status = ZwQueryInformationFile(FileHandle, &ioStatusBlock, &fileInfo, sizeof(fileInfo), FileStandardInformation);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("[*] failed in query file with 0x%x\n", status);
        ZwClose(FileHandle);
        return 0;
    }

    ULONG Size = (ULONG)fileInfo.EndOfFile.QuadPart;
    PVOID Buffer = ExAllocatePoolWithTag(NonPagedPool,Size,TAG);
    if (!Buffer)
    {
        ZwClose(FileHandle);
        return 0;
    }

    status = ZwReadFile(FileHandle, NULL, NULL, NULL, &ioStatusBlock, Buffer, Size, NULL, NULL);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("[*] failed in read file with 0x%x size = 0x%d buffer = 0x%p \n", status, Size, Buffer);
        ExFreePoolWithTag(Buffer, TAG);
        ZwClose(FileHandle);
        return 0;
    }

Solved , FILE_SYNCHRONOUS_IO_NONALERT , or you have to specify the ByteOffset

1 Like

Ah! Bravo for figuring this out, and even more so, for following up here in the Community to let us know how the problem was solved. Thanks for that.

(There was a little voice in the back of my head when I read your question that was saying “byte offset” but I couldn’t quite put my finger on why you’d need it in this case. Of course, it’s FILE_SYNCHRONOUS_IO_NONALERT!)