BOOLEAN ShouldBlockVolumeRead()

in Silhouette/Filter_Read.cpp [3:82]


BOOLEAN ShouldBlockVolumeRead(
    _Inout_ PFLT_CALLBACK_DATA Data,
    _In_ PCFLT_RELATED_OBJECTS FltObjects
)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    BOOLEAN bShouldLog = FALSE;
    BOOLEAN bShouldBlock = FALSE;
    FLT_FILESYSTEM_TYPE fsType = FLT_FSTYPE_UNKNOWN;

    // Ignore KernelMode requests
    // We're only interested in FO_VOLUME_OPEN reads
    // We're only interested in reads to the system boot partition
    if (((KernelMode == Data->RequestorMode) && !FlagOn(Data->Iopb->OperationFlags, SL_FORCE_ACCESS_CHECK)) ||
        (0 == FlagOn(FltObjects->FileObject->Flags, FO_VOLUME_OPEN)) ||
        (0 == FlagOn(FltObjects->FileObject->DeviceObject->Flags, DO_SYSTEM_BOOT_PARTITION)))
    {
        goto Cleanup;
    }

    // The volume should be NTFS
    ntStatus = FltGetFileSystemType(FltObjects->Volume, &fsType);
    if (!NT_SUCCESS(ntStatus) || (FLT_FSTYPE_NTFS != fsType))
    {
        goto Cleanup;
    }

    bShouldLog = TRUE;

    // Allow small reads at offset 0
    if ((0 == Data->Iopb->Parameters.Read.ByteOffset.QuadPart) &&
        (Data->Iopb->Parameters.Read.Length <= 512))
    {
        goto Cleanup;
    }

#if 0
    {
        NTFS_VOLUME_DATA_BUFFER volumeData = { 0, };
        ULONG ulBytesReturned = 0;
        LONGLONG mftStartOffset = 0;
        LONGLONG mftEndOffset = 0;

        // Find MFT region
        ntStatus = FltFsControlFile(
            FltObjects->Instance, FltObjects->FileObject, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, &volumeData, sizeof(volumeData), &ulBytesReturned);
        if (!NT_SUCCESS(ntStatus))
        {
            goto Cleanup;
        }

        mftStartOffset = volumeData.MftZoneStart.QuadPart * volumeData.BytesPerCluster;
        mftEndOffset = volumeData.MftZoneEnd.QuadPart * volumeData.BytesPerCluster;

        // Allow reads to the MFT region
        if ((Data->Iopb->Parameters.Read.ByteOffset.QuadPart >= mftStartOffset) &&
            (Data->Iopb->Parameters.Read.ByteOffset.QuadPart < mftEndOffset))
        {
            goto Cleanup;
        }
}
#endif

    bShouldBlock = TRUE;

Cleanup:

    if (bShouldLog)
    {
        DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
            "Silhouette: %s FO_VOLUME_OPEN read at offset %llu Length %lu PID %u\n",
            bShouldBlock ? "DENY" : "ALLOW",
            Data->Iopb->Parameters.Read.ByteOffset.QuadPart,
            Data->Iopb->Parameters.Read.Length,
            FltGetRequestorProcessId(Data)
        );
    }

    return bShouldBlock;
}