freeotfe.c
来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· C语言 代码 · 共 1,966 行 · 第 1/5 页
C
1,966 行
// Description: FreeOTFE Device Driver
// By Sarah Dean
// Email: sdean12@sdean12.org
// WWW: http://www.FreeOTFE.org/
//
// -----------------------------------------------------------------------------
//
// #defines for debug purposes:
//
// #define DBG_CREATEINITDISKS 4
// - If defined, then when the driver starts, it will automatically create the specified
// number of disk devices
// - Should all be COMMENTED OUT for release
#include <ntddk.h>
#include <stdio.h>
// Required for std disk device driver I/O control (IOCTL) codes
#include <ntdddisk.h>
// Required for std CDROM IOCTLs and structs (e.g. IOCTL_CDROM_READ_TOC)
#include <ntddcdrm.h>
#include <ntverp.h> // Needed for VER_PRODUCTBUILD
#include "IFSRelated.h"
#include "FreeOTFEDebug.h"
#include "FreeOTFENULLGUID.h"
#include "FreeOTFEDriverlib.h"
#include "FreeOTFEDriverConstsCommon.h"
#include "FreeOTFElib.h"
#include "FreeOTFEGenerateBlockIV.h"
#include "FreeOTFECallModuleFn.h"
#include "FreeOTFEPlatform.h"
#include "FreeOTFE.h"
#include "FreeOTFEAPI.h"
#include "FreeOTFEHashAPI.h"
#include "FreeOTFECypherAPI.h"
// MAC implementations
#include "FreeOTFEMACHash.h"
#include "FreeOTFEMACHMAC.h"
// KDF implementations
#include "FreeOTFEKDFHashSaltedPassword.h"
#include "FreeOTFEKDFPBKDF2.h"
// Globals.
// Not nice, but...
HANDLE DirFreeOTFERoot = NULL;
HANDLE DirFreeOTFEDisks = 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;
#ifdef DBG_CREATEINITDISKS
int i;
PDEVICE_OBJECT dbgTmpDevObj;
#endif
// 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)) {
SecZeroMemory(¶mTable[0], sizeof(paramTable));
SecZeroMemory(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,
¶mTable[0],
NULL,
NULL)))) {
shouldBreak = default_ShouldBreak;
debugLevel = default_DebugLevel;
}
ExFreePool(path);
}
#if DBG
FreeOTFEDebugLevel = debugLevel;
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Debug level : %d\n", FreeOTFEDebugLevel));
#endif
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Driver version: 0x%08x (v%02d.%02d.%04d)\n",
DRIVER_VERSION,
(DRIVER_VERSION & 0xFF000000) / 0x00FF0000,
(DRIVER_VERSION & 0x00FF0000) / 0x0000FF00,
(DRIVER_VERSION & 0x0000FFFF)
));
if (shouldBreak == 1)
{
DbgBreakPoint();
}
#endif
DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("DriverEntry\n"));
// Create main device dir
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Creating dir object (main)...\n"));
status = CreateDeviceDir(
DEVICE_FREEOTFE_ROOT,
&DirFreeOTFERoot
);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("Unable to CreateDeviceDir (main)\n"));
return status;
}
// Create disk device dir
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Creating dir object (disks)...\n"));
status = CreateDeviceDir(
DEVICE_DISK_DIR_NAME,
&DirFreeOTFEDisks
);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("Unable to CreateDeviceDir (disks)\n"));
ZwClose(DirFreeOTFERoot);
return status;
}
// Create main device
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Creating main device...\n"));
status = CreateMainDevice(DriverObject, &mainDevObj);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("Call to CreateMainDevice FAILED.\n"));
return status;
}
// Store the device dir handle for closure on unload
mainDevExt = (PDEVICE_EXTENSION)mainDevObj->DeviceExtension;
#ifdef DBG_CREATEINITDISKS
// Create initial disk devices
for (i=1; i<=DBG_CREATEINITDISKS; i++)
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Creating disk #%d device...\n", i));
status = CreateDiskDevice(DriverObject, &dbgTmpDevObj);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("Call to CreateDiskDevice FAILED.\n"));
return status;
}
}
#endif
// 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->MajorFunction[IRP_MJ_READ] =
FreeOTFE_MF_DispatchRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] =
FreeOTFE_MF_DispatchWrite;
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] =
FreeOTFE_MF_DispatchFlushBuffers;
// xxxop - prevent hibernate, standby, etc if drives are mounted
// xxxop - will finish implementing this once my testbox is configured to handle
// hibernate & standby
// DriverObject->MajorFunction[IRP_MJ_POWER] =
// FreeOTFE_MF_DispatchPower;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
FreeOTFE_MF_DispatchSystemControl;
DriverObject->DriverUnload = DriverUnload;
DEBUGOUTMAINDRV(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;
DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("DriverUnload\n"));
// TODOzzz: Dismount all first!!!???
// Walk through all the device objects, shutting them down and deleting
// them
devObj = DriverObject->DeviceObject;
while (devObj != NULL)
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Found a device to destroy; destroying it...\n"));
devObj = DestroyDevice(devObj);
}
status = ZwClose(DirFreeOTFERoot);
status = ZwClose(DirFreeOTFEDisks);
DEBUGOUTMAINDRV(DEBUGLEV_EXIT, ("DriverUnload\n"));
return;
}
// =========================================================================
// Overwrite sensitive parts of the specified device's extension
// Given a device object, cleardown, free off and overwrite all sensitive
// parts of it's device extension which relate to DISK DEVICES
// (e.g. encryption/decryption keys, etc)
// !!! WARNING !!!
// This must only ever be called on a disk device which has been UNMOUNTED,
// with nothing remaining to be processed on it's thread's IRP queue
// Returns: Status
NTSTATUS
OverwriteDeviceSensitive(
IN PDEVICE_OBJECT devObj
)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION devExt;
NTSTATUS tmpStatus;
IO_STATUS_BLOCK ioStatusBlock;
DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("OverwriteDeviceSensitive\n"));
devExt = (PDEVICE_EXTENSION)devObj->DeviceExtension;
devExt->Mounted = FALSE;
devExt->DismountPending = FALSE;
// Tear down any filename...
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("(Filename)...\n"));
if (devExt->zzFilename.Buffer != NULL)
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Freeing off filename unicode buffer...\n"));
SecZeroMemory(
devExt->zzFilename.Buffer,
sizeof(devExt->zzFilename.MaximumLength)
);
ExFreePool(devExt->zzFilename.Buffer);
devExt->zzFilename.Buffer = NULL;
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("OK.\n"));
}
// File object pointer
if (devExt->FileObject != NULL)
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Dereferencing file object...\n"));
ObDereferenceObject(devExt->FileObject);
devExt->FileObject = NULL;
DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("OK.\n"));
}
// Closedown any open
// Return value ignored
FileClose(
&devExt->FileHandle,
devExt->FileAttributesStored,
&devExt->FileAttributes,
&ioStatusBlock
);
// Timestamps/file attributes
devExt->FileAttributesStored = FALSE;
SecZeroMemory(
&devExt->FileAttributes,
sizeof(devExt->FileAttributes)
);
// Information required for impersonation
// Return value ignored
ClientSecurityDestroy(&devExt->ClientContext);
// Offset
devExt->DataOffset.QuadPart = 0;
// Encrypted block size
devExt->EncryptionBlockSize = 0;
// Simulated disk geometry
devExt->HiddenSectors = 0;
SecZeroMemory(
&devExt->DiskGeometry,
sizeof(devExt->DiskGeometry)
);
SecZeroMemory(
&devExt->DiskSize,
sizeof(devExt->DiskSize)
);
SecZeroMemory(
&devExt->PartitionSize,
sizeof(devExt->PartitionSize)
);
// Readonly flag
devExt->ReadOnly = TRUE;
// Mount source (e.g. the volume file is a partition or file)
devExt->MountSource = MNTSRC_UNKNOWN;
// Storage media type (i.e. the type of device emulated)
devExt->StorageMediaType = Unknown;
// Prevent media removal; for removable disks only
devExt->PreventMediaRemoval = FALSE;
// Tear down any IV hash related...
FreeDeviceDetailsHash(&devExt->IVHash);
// Tear down any IV cypher related...
FreeDeviceDetailsCypher(&devExt->IVCypher);
// Tear down any main cypher related...
FreeDeviceDetailsCypher(&devExt->MainCypher);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?