freeotfecypherdriver.c
来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· C语言 代码 · 共 1,734 行 · 第 1/5 页
C
1,734 行
// Description: FreeOTFE Cypher 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 "FreeOTFECypherDriver.h"
#include "FreeOTFECypherAPI.h"
#include "FreeOTFEDebug.h"
#include "FreeOTFEDriverlib.h"
#include "FreeOTFElib.h"
#include "FreeOTFECypherImpl.h"
// Globals.
// Not nice, but...
HANDLE DirFreeOTFERoot = NULL;
HANDLE DirFreeOTFECypher = 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( ¶mTable[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,
¶mTable[0],
NULL,
NULL))) {
shouldBreak = default_ShouldBreak;
debugLevel = default_DebugLevel;
}
ExFreePool( path );
}
#if DBG
FreeOTFEDebugLevel = debugLevel;
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Debug level: %d\n", FreeOTFEDebugLevel));
#endif
if (shouldBreak == 1)
{
DbgBreakPoint();
}
#endif
DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, ("DriverEntry\n"));
// Create main device dir
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Creating dir object (main)...\n"));
status = CreateDeviceDir(
DEVICE_FREEOTFE_ROOT,
&DirFreeOTFERoot
);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("Unable to CreateDeviceDir (main)\n"));
return status;
}
// Create cypher device dir
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Creating dir object (cypher)...\n"));
status = CreateDeviceDir(
DEVICE_CYPHER_DIR_NAME,
&DirFreeOTFECypher
);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("Unable to CreateDeviceDir (cypher)\n"));
ZwClose(DirFreeOTFERoot);
return status;
}
// Create main device
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Creating main device...\n"));
status = CreateDevice(DriverObject, &mainDevObj);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTCYPHERDRV(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;
DEBUGOUTCYPHERDRV(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;
DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, ("DriverUnload\n"));
// Walk through all the device objects, shutting them down and deleting
// them
devObj = DriverObject->DeviceObject;
while (devObj != NULL)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Found a device to destroy; destroying it...\n"));
devObj = DestroyDevice(devObj);
}
status = ZwClose(DirFreeOTFERoot);
status = ZwClose(DirFreeOTFECypher);
DEBUGOUTCYPHERDRV(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;
DEBUGOUTCYPHERDRV(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 );
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Wait completed; thread terminated.\n"));
// Release the thread object ref
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Dereferencing ThreadObject...\n"));
ObDereferenceObject(devExt->ThreadObject);
devExt->ThreadObject = NULL;
}
// Tear down any symbolic device name link
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Tearing down main device specific...\n"));
if (devExt->zzSymbolicLinkName.Buffer != NULL)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Tearing down symbolic device link...\n"));
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("About to delete symlink: %ls\n", devExt->zzSymbolicLinkName.Buffer));
status = IoDeleteSymbolicLink(&devExt->zzSymbolicLinkName);
if (!NT_SUCCESS(status))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, ("Status NOT OK\n"));
}
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Freeing off symlink unicode buffer...\n"));
SecZeroMemory(
devExt->zzSymbolicLinkName.Buffer,
sizeof(devExt->zzSymbolicLinkName.MaximumLength)
);
ExFreePool(devExt->zzSymbolicLinkName.Buffer);
devExt->zzSymbolicLinkName.Buffer = NULL;
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("OK.\n"));
}
// Tear down any device name
if (devExt->zzDeviceName.Buffer != NULL)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Freeing off devname unicode buffer...\n"));
SecZeroMemory(
devExt->zzDeviceName.Buffer,
sizeof(devExt->zzDeviceName.MaximumLength)
);
ExFreePool(devExt->zzDeviceName.Buffer);
devExt->zzDeviceName.Buffer = NULL;
}
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("OK.\n"));
// Cleardown details of cyphers supported
ImpCypherDriverExtDetailsCleardown(&(devExt->DriverInfo));
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("OK.\n"));
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Overwriting device extension memory...\n"));
SecZeroMemory(devExt, sizeof(DEVICE_EXTENSION));
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("OK.\n"));
// Get rid of the device object...
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("Deleting device...\n"));
IoDeleteDevice(devObj);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, ("OK.\n"));
DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, ("DestroyDevice\n"));
return nextDevObj;
}
// =========================================================================
// Handle create IRPs
NTSTATUS
FreeOTFE_MF_DispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, ("FreeOTFE_MF_DispatchCreate\n"));
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, ("FreeOTFE_MF_DispatchCreate\n"));
return STATUS_SUCCESS;
}
// =========================================================================
// Handle close IRPs
NTSTATUS
FreeOTFE_MF_DispatchClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, ("FreeOTFE_MF_DispatchClose\n"));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?