freeotfehashdriver.c

来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· C语言 代码 · 共 1,396 行 · 第 1/4 页

C
1,396
字号
// Description: FreeOTFE Hash Device Driver
// By Sarah Dean
// Email: sdean12@sdean12.org
// WWW:   http://www.FreeOTFE.org/
//
// -----------------------------------------------------------------------------
//


#include <ntddk.h>
#include <stdio.h>

// Required for std disk device driver I/O control (IOCTL) codes
#include <ntdddisk.h>


#include "FreeOTFEHashDriver.h"
#include "FreeOTFEHashAPI.h"
#include "FreeOTFEDebug.h"
#include "FreeOTFEDriverlib.h"
#include "FreeOTFElib.h"
#include "FreeOTFEHashImpl.h"


// Globals.
// Not nice, but...
HANDLE DirFreeOTFERoot = NULL;
HANDLE DirFreeOTFEHash = NULL;


// =========================================================================
// This routine is the driver's entry point, called by the I/O system
// to load the driver.  The driver's entry points are initialized.
// In DBG mode, this routine also examines the registry for special
// debug parameters.
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    UNICODE_STRING devDirName;
    OBJECT_ATTRIBUTES dirObjAttribs;
    PDEVICE_OBJECT mainDevObj;
    PDEVICE_EXTENSION mainDevExt;
    int i;
    
    // The following debug handling was ripped from the MS DDK "floppy.c"
    // example
#if DBG
    // We use this to query into the registry as to whether we
    // should break at driver entry.
    RTL_QUERY_REGISTRY_TABLE paramTable[3];
    ULONG default_ShouldBreak = 0;           // Default to 0; no break
//    ULONG default_DebugLevel  = 0xFFFFFFFF;  // Default to all on
    ULONG default_DebugLevel  = 0x0000001F;  // All except verbose debug
    ULONG debugLevel = 0;
    ULONG shouldBreak = 0;
    PWCHAR path;
    ULONG pathLength;
    
    // Since the registry path parameter is a "counted" UNICODE string, it
    // might not be zero terminated.  For a very short time allocate memory
    // to hold the registry path zero terminated so that we can use it to
    // delve into the registry.
    //
    // NOTE NOTE!!!! This is not an architected way of breaking into
    // a driver.  It happens to work for this driver because the original
    // DDK example code for DriverEntry happened to be written in this manner.
    pathLength = RegistryPath->Length + sizeof(WCHAR);

    if ( path = ExAllocatePool(PagedPool, pathLength) ) {

        RtlZeroMemory( &paramTable[0], sizeof(paramTable) );
        RtlZeroMemory( path, pathLength);
        RtlMoveMemory( path, RegistryPath->Buffer, RegistryPath->Length );

        paramTable[0].Flags         = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[0].Name          = L"BreakOnEntry";
        paramTable[0].EntryContext  = &shouldBreak;
        paramTable[0].DefaultType   = REG_DWORD;
        paramTable[0].DefaultData   = &default_ShouldBreak;
        paramTable[0].DefaultLength = sizeof(ULONG);

        paramTable[1].Flags         = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[1].Name          = L"DebugLevel";
        paramTable[1].EntryContext  = &debugLevel;
        paramTable[1].DefaultType   = REG_DWORD;
        paramTable[1].DefaultData   = &default_DebugLevel;
        paramTable[1].DefaultLength = sizeof(ULONG);

        if (!NT_SUCCESS(RtlQueryRegistryValues(
                            RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
                            path,
                            &paramTable[0],
                            NULL,
                            NULL))) {

            shouldBreak = default_ShouldBreak;
            debugLevel = default_DebugLevel;
        }

        ExFreePool( path );
    }

#if DBG
    FreeOTFEDebugLevel = debugLevel;
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Debug level: %d\n", FreeOTFEDebugLevel));
#endif
    
    if (shouldBreak == 1)
        {
        DbgBreakPoint();
        }

#endif

    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("DriverEntry\n"));

    // Create main device dir
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Creating dir object (main)...\n"));
    status = CreateDeviceDir(
                DEVICE_FREEOTFE_ROOT,
                &DirFreeOTFERoot
               );
    if (!(NT_SUCCESS(status)))
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("Unable to CreateDeviceDir (main)\n"));
        return status;
        }

    // Create hash device dir
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Creating dir object (hash)...\n"));
    status = CreateDeviceDir(
                DEVICE_HASH_DIR_NAME,
                &DirFreeOTFEHash
               );
    if (!(NT_SUCCESS(status)))
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("Unable to CreateDeviceDir (hash)\n"));
        ZwClose(DirFreeOTFERoot);
        return status;
        }

    // Create main device
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Creating main device...\n"));
    status = CreateDevice(DriverObject, &mainDevObj);
    if (!(NT_SUCCESS(status)))
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("Call to CreateDevice FAILED.\n"));
        return status;
        }
    
    // Store the device dir handle for closure on unload
    mainDevExt = (PDEVICE_EXTENSION)mainDevObj->DeviceExtension;
    

    // Initialize the driver object with this driver's entry points.
    DriverObject->MajorFunction[IRP_MJ_CREATE] = 
                                            FreeOTFE_MF_DispatchCreate;
                                            
    DriverObject->MajorFunction[IRP_MJ_CLOSE] =
                                            FreeOTFE_MF_DispatchClose;
                                            
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
                                            FreeOTFE_MF_DispatchDeviceControl;
                                            

    DriverObject->DriverUnload = DriverUnload;


    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("DriverEntry\n"));    

    return status;
}


// =========================================================================
// Unload the driver from the system
VOID
DriverUnload(
    IN PDRIVER_OBJECT DriverObject
    )
{
    PDEVICE_EXTENSION devExt;
    PDEVICE_OBJECT devObj;
    NTSTATUS status;
    
    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("DriverUnload\n"));
    
    
    // Walk through all the device objects, shutting them down and deleting
    // them
    devObj = DriverObject->DeviceObject;
    while (devObj != NULL)
        {
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Found a device to destroy; destroying it...\n"));
        devObj = DestroyDevice(devObj);          
        }

    status = ZwClose(DirFreeOTFERoot);
    status = ZwClose(DirFreeOTFEHash);

    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("DriverUnload\n"));

    return;
}


// =========================================================================
// Destroy the specified device object, regardless of it's state
// Note: This can be called to destroy *either* the main device, *or* a
//       disk device
// Returns: The next device object
PDEVICE_OBJECT
DestroyDevice(
    IN PDEVICE_OBJECT devObj    
)
{
    NTSTATUS status;
    PDEVICE_EXTENSION devExt;
    PDEVICE_OBJECT nextDevObj;

    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("DestroyDevice\n"));
        
    nextDevObj = devObj->NextDevice;
    
    devExt = (PDEVICE_EXTENSION)devObj->DeviceExtension;    

    // Signal the device's thread to terminate, and wait until it does.
    devExt->TerminateThread = TRUE;
    CancelAllQueuedIRPs(devObj);
    if (devExt->ThreadObject != NULL) 
        {    
        // Make sure the thread wakes up, so it can see that it should terminate
        KeReleaseSemaphore(&devExt->IRPQueueSemaphore,
                            0,  // No priority boost
                            1,  // Increment semaphore by 1
                            TRUE );// WaitForXxx after this call

        // Wait for the thread to terminate
        KeWaitForSingleObject(devExt->ThreadObject,
                            Executive,
                            KernelMode,
                            FALSE,
                            NULL );

        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Wait completed; thread terminated.\n"));
        
        // Release the thread object ref
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Dereferencing ThreadObject...\n"));
        ObDereferenceObject(devExt->ThreadObject);
        devExt->ThreadObject = NULL;
        }
    

    // Tear down any symbolic device name link
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Tearing down main device specific...\n"));
    if (devExt->zzSymbolicLinkName.Buffer != NULL)
        {
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Tearing down symbolic device link...\n"));
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("About to delete symlink: %ls\n", devExt->zzSymbolicLinkName.Buffer));
        status = IoDeleteSymbolicLink(&devExt->zzSymbolicLinkName);
        if (!NT_SUCCESS(status))
            {
            DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("Status NOT OK\n"));
            }
        
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Freeing off symlink unicode buffer...\n")); 
        SecZeroMemory(
                        devExt->zzSymbolicLinkName.Buffer,
                        sizeof(devExt->zzSymbolicLinkName.MaximumLength)
                        );
        ExFreePool(devExt->zzSymbolicLinkName.Buffer);
        devExt->zzSymbolicLinkName.Buffer = NULL;
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("OK.\n"));   
        }
        
    
    // Tear down any device name
    if (devExt->zzDeviceName.Buffer != NULL)
        {
        DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Freeing off devname unicode buffer...\n"));
        SecZeroMemory(
                      devExt->zzDeviceName.Buffer,
                      sizeof(devExt->zzDeviceName.MaximumLength)
                     );
        ExFreePool(devExt->zzDeviceName.Buffer);
        devExt->zzDeviceName.Buffer = NULL;
        }
    

    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("OK.\n"));   
    
    // Cleardown details of hashes supported
    ImpHashDriverExtDetailsCleardown(&(devExt->DriverInfo));

    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("OK.\n"));   

    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Overwriting device extension memory...\n"));   
    SecZeroMemory(devExt, sizeof(DEVICE_EXTENSION));
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("OK.\n"));   

    // Get rid of the device object...
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Deleting device...\n"));   
    IoDeleteDevice(devObj);
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("OK.\n"));   
    

    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("DestroyDevice\n"));
    
    return nextDevObj;
}
    

// =========================================================================
// Handle create IRPs
NTSTATUS
FreeOTFE_MF_DispatchCreate(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("FreeOTFE_MF_DispatchCreate\n"));
    
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = FILE_OPENED;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("FreeOTFE_MF_DispatchCreate\n"));
    
    return STATUS_SUCCESS;
}


// =========================================================================
// Handle close IRPs
NTSTATUS
FreeOTFE_MF_DispatchClose(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("FreeOTFE_MF_DispatchClose\n"));
    
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = FILE_OPENED;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?