Menu

#129 IoPageRead and IO_STATUS_BLOCK::Information

v1.0_(example)
closed-fixed
nobody
None
7
2015-08-06
2014-11-07
EreTIk
No

Test:

NTSTATUS DriverEntry(
    __in PDRIVER_OBJECT pDriverObject,
    __in PUNICODE_STRING pusRegistryPath
)
{
    HANDLE hFile;
    UNICODE_STRING usFileName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatus;
    FILE_STANDARD_INFORMATION FileInfo;
    LARGE_INTEGER liFileOffset;
    PFILE_OBJECT pFileObject;
    PMDL pMdl;
    void *pReadBuffer;

    NTSTATUS Status;

    static const ULONG nBufferLength = 0x10000;

    UNREFERENCED_PARAMETER(pDriverObject);
    UNREFERENCED_PARAMETER(pusRegistryPath);

    RtlInitUnicodeString(&usFileName, L"\\??\\c:\\test.exe");
    InitializeObjectAttributes(
        &ObjectAttributes,
        &usFileName,
        OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);

    Status = 
        ZwOpenFile(
            &hFile,
            GENERIC_READ,
            &ObjectAttributes,
            &IoStatus,
            FILE_SHARE_READ | FILE_SHARE_DELETE,
            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
    if (!NT_SUCCESS(Status))
    {
        DbgPrint("ZwOpenFile(...)=0x%08x\n", Status);
        return Status;
    }

    Status = 
        ZwQueryInformationFile(
            hFile,
            &IoStatus,
            &FileInfo,
            sizeof(FileInfo),
            FileStandardInformation);
    if (!NT_SUCCESS(Status))
    {
        DbgPrint("ZwQueryInformationFile(...)=0x%08x\n", Status);
        ZwClose(hFile);
        return Status;
    }

    DbgPrint("AllocationSize=0x%I64x\n", FileInfo.AllocationSize.QuadPart);
    DbgPrint("EndOfFile=0x%I64x\n", FileInfo.EndOfFile.QuadPart);

    Status = 
        ObReferenceObjectByHandle(
            hFile,
            GENERIC_READ,
            IoFileObjectType,
            KernelMode,
            &pFileObject,
            NULL);
    if (!NT_SUCCESS(Status))
    {
        DbgPrint("ObReferenceObjectByHandle(...)=0x%08x\n", Status);
        ZwClose(hFile);
        return Status;
    }

    pReadBuffer = ExAllocatePoolWithTag(NonPagedPool, nBufferLength, 'tset');
    if (!pReadBuffer)
    {
        DbgPrint("ExAllocatePoolWithTag(...)=NULL\n");
        ObDereferenceObject(pFileObject);
        ZwClose(hFile);
        return Status;
    }

    pMdl = IoAllocateMdl(pReadBuffer, nBufferLength, FALSE, FALSE, NULL);
    if (!pMdl)
    {
        DbgPrint("IoAllocateMdl(...)=NULL\n");
        ExFreePool(pReadBuffer);
        ObDereferenceObject(pFileObject);
        ZwClose(hFile);
        return Status;
    }
    MmBuildMdlForNonPagedPool(pMdl);

    liFileOffset.QuadPart = 0;

    for (; ; )
    {
        KEVENT Event;
        KeInitializeEvent(&Event, NotificationEvent, FALSE);

        Status = IoPageRead(pFileObject, pMdl, &liFileOffset, &Event, &IoStatus);
        if (STATUS_SUCCESS != Status)
            break;

        DbgPrint("IoStatus.Information=0x%x\n", IoStatus.Information);

        if (IoStatus.Information < nBufferLength)
            break;
        liFileOffset.QuadPart += nBufferLength;
    }

    IoFreeMdl(pMdl);
    ExFreePool(pReadBuffer);
    ObDereferenceObject(pFileObject);
    ZwClose(hFile);

    return STATUS_NOT_IMPLEMENTED;
}

Output for file on ntfs:

AllocationSize=0x65000
EndOfFile=0x64a00
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x4a00

Output for file on ext3:

AllocationSize=0x64c00
EndOfFile=0x64a00
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x10000
IoStatus.Information=0x4c00

0x10000+0x10000+0x10000+0x10000+0x10000+0x10000+0x4c00 != 0x64a00 (!= EndOfFile)

Ext2Fsd v. 0.53

kd> lm vm Ext2Fsd
start    end        module name
99d1a000 99dc0080   Ext2Fsd    (deferred)             
    Image path: Ext2Fsd.sys
    Image name: Ext2Fsd.sys
    Timestamp:        Tue Aug 26 07:45:21 2014 (53FC02D1)
    CheckSum:         000AA014
    ImageSize:        000A6080
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4

Discussion

  • Matt Wu

    Matt Wu - 2015-08-06

    Fixed in 0.60. Prevoius versions of Ext2Fsd uses file allocation size for paging i/o. This way of file reading is rarely used.

     
  • Matt Wu

    Matt Wu - 2015-08-06
    • status: open --> closed-fixed
     

Log in to post a comment.