📄 drivefilter.c
字号:
status = TCWriteDevice (Extension->LowerDeviceObject, header, offset, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
if (!NT_SUCCESS (status))
{
Dump ("TCWriteDevice error %x", status);
goto ret;
}
ret:
TCfree (header);
return status;
}
static NTSTATUS PassIrp (PDEVICE_OBJECT deviceObject, PIRP irp)
{
IoSkipCurrentIrpStackLocation (irp);
return IoCallDriver (deviceObject, irp);
}
static NTSTATUS PassFilteredIrp (PDEVICE_OBJECT deviceObject, PIRP irp, PIO_COMPLETION_ROUTINE completionRoutine, PVOID completionRoutineArg)
{
IoCopyCurrentIrpStackLocationToNext (irp);
if (completionRoutine)
IoSetCompletionRoutine (irp, completionRoutine, completionRoutineArg, TRUE, TRUE, TRUE);
return IoCallDriver (deviceObject, irp);
}
static NTSTATUS OnDeviceUsageNotificationCompleted (PDEVICE_OBJECT filterDeviceObject, PIRP Irp, DriveFilterExtension *Extension)
{
if (Irp->PendingReturned)
IoMarkIrpPending (Irp);
if (!(Extension->LowerDeviceObject->Flags & DO_POWER_PAGABLE))
filterDeviceObject->Flags &= ~DO_POWER_PAGABLE;
IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp);
return STATUS_CONTINUE_COMPLETION;
}
static VOID MountDriveWorkItemRoutine (PDEVICE_OBJECT deviceObject, DriveFilterExtension *filterExtension)
{
MountDrive (filterExtension, &BootArgs.BootPassword, &BootArgs.HeaderSaltCrc32);
KeSetEvent (&filterExtension->MountWorkItemCompletedEvent, IO_NO_INCREMENT, FALSE);
}
static NTSTATUS OnStartDeviceCompleted (PDEVICE_OBJECT filterDeviceObject, PIRP Irp, DriveFilterExtension *Extension)
{
if (Irp->PendingReturned)
IoMarkIrpPending (Irp);
if (Extension->LowerDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
filterDeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
if (BootArgsValid && !BootDriveFound)
{
if (KeGetCurrentIrql() == PASSIVE_LEVEL)
{
MountDrive (Extension, &BootArgs.BootPassword, &BootArgs.HeaderSaltCrc32);
}
else
{
PIO_WORKITEM workItem = IoAllocateWorkItem (filterDeviceObject);
if (!workItem)
return STATUS_INSUFFICIENT_RESOURCES;
KeInitializeEvent (&Extension->MountWorkItemCompletedEvent, SynchronizationEvent, FALSE);
IoQueueWorkItem (workItem, MountDriveWorkItemRoutine, DelayedWorkQueue, Extension);
KeWaitForSingleObject (&Extension->MountWorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL);
IoFreeWorkItem (workItem);
}
}
IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp);
return STATUS_CONTINUE_COMPLETION;
}
static NTSTATUS DispatchPnp (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilterExtension *Extension, PIO_STACK_LOCATION irpSp)
{
NTSTATUS status;
status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp);
if (!NT_SUCCESS (status))
return TCCompleteIrp (Irp, status, Irp->IoStatus.Information);
switch (irpSp->MinorFunction)
{
case IRP_MN_START_DEVICE:
Dump ("IRP_MN_START_DEVICE pdo=%p\n", Extension->Pdo);
return PassFilteredIrp (Extension->LowerDeviceObject, Irp, OnStartDeviceCompleted, Extension);
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
Dump ("IRP_MN_DEVICE_USAGE_NOTIFICATION type=%d\n", (int) irpSp->Parameters.UsageNotification.Type);
{
PDEVICE_OBJECT attachedDevice = IoGetAttachedDeviceReference (DeviceObject);
if (attachedDevice == DeviceObject || (attachedDevice->Flags & DO_POWER_PAGABLE))
DeviceObject->Flags |= DO_POWER_PAGABLE;
if (attachedDevice != DeviceObject)
ObDereferenceObject (attachedDevice);
}
// Prevent creation of hibernation and crash dump files
if (irpSp->Parameters.UsageNotification.InPath
&& (irpSp->Parameters.UsageNotification.Type == DeviceUsageTypeDumpFile
|| (irpSp->Parameters.UsageNotification.Type == DeviceUsageTypeHibernation && !HibernationDriverFilterActive)))
{
IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp);
if (irpSp->Parameters.UsageNotification.Type == DeviceUsageTypeHibernation)
++HibernationPreventionCount;
return TCCompleteIrp (Irp, STATUS_UNSUCCESSFUL, Irp->IoStatus.Information);
}
return PassFilteredIrp (Extension->LowerDeviceObject, Irp, OnDeviceUsageNotificationCompleted, Extension);
case IRP_MN_REMOVE_DEVICE:
Dump ("IRP_MN_REMOVE_DEVICE pdo=%p\n", Extension->Pdo);
IoReleaseRemoveLockAndWait (&Extension->Queue.RemoveLock, Irp);
status = PassIrp (Extension->LowerDeviceObject, Irp);
IoDetachDevice (Extension->LowerDeviceObject);
if (Extension->QueueStarted && EncryptedIoQueueIsRunning (&Extension->Queue))
EncryptedIoQueueStop (&Extension->Queue);
if (Extension->DriveMounted)
DismountDrive (Extension);
if (Extension->BootDrive)
{
BootDriveFound = FALSE;
BootDriveFilterExtension = NULL;
}
DriverMutexWait();
IoDeleteDevice (DeviceObject);
DriverMutexRelease();
return status;
default:
status = PassIrp (Extension->LowerDeviceObject, Irp);
IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp);
}
return status;
}
static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilterExtension *Extension, PIO_STACK_LOCATION irpSp)
{
NTSTATUS status;
Dump ("IRP_MJ_POWER minor=%d type=%d shutdown=%d\n", (int) irpSp->MinorFunction, (int) irpSp->Parameters.Power.Type, (int) irpSp->Parameters.Power.ShutdownType);
if (SetupInProgress
&& irpSp->MinorFunction == IRP_MN_SET_POWER
&& irpSp->Parameters.Power.Type == DevicePowerState
&& irpSp->Parameters.Power.ShutdownType == PowerActionHibernate)
{
EncryptionSetupThreadAbortRequested = TRUE;
ObDereferenceObject (EncryptionSetupThread);
while (SetupInProgress)
TCSleep (200);
}
if (DriverShuttingDown
&& Extension->DriveMounted
&& irpSp->MinorFunction == IRP_MN_SET_POWER
&& irpSp->Parameters.Power.Type == DevicePowerState)
{
Dump ("IRP_MN_SET_POWER\n");
if (Extension->QueueStarted && EncryptedIoQueueIsRunning (&Extension->Queue))
EncryptedIoQueueStop (&Extension->Queue);
if (Extension->DriveMounted)
DismountDrive (Extension);
}
PoStartNextPowerIrp (Irp);
status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp);
if (!NT_SUCCESS (status))
return TCCompleteIrp (Irp, status, Irp->IoStatus.Information);
IoSkipCurrentIrpStackLocation (Irp);
status = PoCallDriver (Extension->LowerDeviceObject, Irp);
IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp);
return status;
}
NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DriveFilterExtension *Extension = (DriveFilterExtension *) DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
ASSERT (!Extension->bRootDevice && Extension->IsDriveFilterDevice);
switch (irpSp->MajorFunction)
{
case IRP_MJ_READ:
case IRP_MJ_WRITE:
if (BootDriveFound && !Extension->BootDrive)
{
return PassIrp (Extension->LowerDeviceObject, Irp);
}
else
{
NTSTATUS status = EncryptedIoQueueAddIrp (&Extension->Queue, Irp);
if (status != STATUS_PENDING)
TCCompleteDiskIrp (Irp, status, 0);
return status;
}
case IRP_MJ_PNP:
return DispatchPnp (DeviceObject, Irp, Extension, irpSp);
case IRP_MJ_POWER:
return DispatchPower (DeviceObject, Irp, Extension, irpSp);
default:
return PassIrp (Extension->LowerDeviceObject, Irp);
}
}
void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp)
{
LARGE_INTEGER offset;
char *header;
ReopenBootVolumeHeaderRequest *request = (ReopenBootVolumeHeaderRequest *) irp->AssociatedIrp.SystemBuffer;
irp->IoStatus.Information = 0;
if (!IoIsSystemThread (PsGetCurrentThread()) && !UserCanAccessDriveDevice())
{
irp->IoStatus.Status = STATUS_ACCESS_DENIED;
return;
}
if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof (ReopenBootVolumeHeaderRequest))
{
irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
return;
}
if (!BootDriveFound || !BootDriveFilterExtension || !BootDriveFilterExtension->DriveMounted || !BootDriveFilterExtension->HeaderCryptoInfo
|| request->VolumePassword.Length > MAX_PASSWORD)
{
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
goto wipe;
}
header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
if (!header)
{
irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
goto wipe;
}
if (BootDriveFilterExtension->HiddenSystem)
offset.QuadPart = BootArgs.HiddenSystemPartitionStart + TC_HIDDEN_VOLUME_HEADER_OFFSET;
else
offset.QuadPart = TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET;
irp->IoStatus.Status = TCReadDevice (BootDriveFilterExtension->LowerDeviceObject, header, offset, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
if (!NT_SUCCESS (irp->IoStatus.Status))
{
Dump ("TCReadDevice error %x\n", irp->IoStatus.Status);
goto ret;
}
if (VolumeReadHeader (!BootDriveFilterExtension->HiddenSystem, header, &request->VolumePassword, NULL, BootDriveFilterExtension->HeaderCryptoInfo) == 0)
{
Dump ("Header reopened\n");
BootDriveFilterExtension->Queue.CryptoInfo->header_creation_time = BootDriveFilterExtension->HeaderCryptoInfo->header_creation_time;
BootDriveFilterExtension->Queue.CryptoInfo->pkcs5 = BootDriveFilterExtension->HeaderCryptoInfo->pkcs5;
BootDriveFilterExtension->Queue.CryptoInfo->noIterations = BootDriveFilterExtension->HeaderCryptoInfo->noIterations;
irp->IoStatus.Status = STATUS_SUCCESS;
}
else
{
crypto_close (BootDriveFilterExtension->HeaderCryptoInfo);
BootDriveFilterExtension->HeaderCryptoInfo = NULL;
Dump ("Header not reopened\n");
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}
ret:
TCfree (header);
wipe:
burn (request, sizeof (*request));
}
typedef NTSTATUS (*HiberDriverWriteFunctionA) (ULONG arg0, PLARGE_INTEGER writeOffset, PMDL dataMdl, PVOID arg3);
typedef NTSTATUS (*HiberDriverWriteFunctionB) (PLARGE_INTEGER writeOffset, PMDL dataMdl);
typedef struct
{
// Until MS releases an API for filtering hibernation drivers, we have to resort to this.
#ifdef _WIN64
byte FieldPad1[64];
HiberDriverWriteFunctionB WriteFunctionB;
byte FieldPad2[56];
#else
byte FieldPad1[48];
HiberDriverWriteFunctionB WriteFunctionB;
byte FieldPad2[32];
#endif
HiberDriverWriteFunctionA WriteFunctionA;
byte FieldPad3[24];
LARGE_INTEGER PartitionStartOffset;
} HiberDriverContext;
typedef NTSTATUS (*HiberDriverEntry) (PVOID arg0, HiberDriverContext *hiberDriverContext);
typedef struct
{
LIST_ENTRY ModuleList;
#ifdef _WIN64
byte FieldPad1[32];
#else
byte FieldPad1[16];
#endif
PVOID ModuleBaseAddress;
HiberDriverEntry ModuleEntryAddress;
#ifdef _WIN64
byte FieldPad2[24];
#else
byte FieldPad2[12];
#endif
UNICODE_STRING ModuleName;
} ModuleTableItem;
#define TC_MAX_HIBER_FILTER_COUNT 3
static int LastHiberFilterNumber = 0;
static HiberDriverEntry OriginalHiberDriverEntries[TC_MAX_HIBER_FILTER_COUNT];
static HiberDriverWriteFunctionA OriginalHiberDriverWriteFunctionsA[TC_MAX_HIBER_FILTER_COUNT];
static HiberDriverWriteFunctionB OriginalHiberDriverWriteFunctionsB[TC_MAX_HIBER_FILTER_COUNT];
static LARGE_INTEGER HiberPartitionOffset;
static NTSTATUS HiberDriverWriteFunctionFilter (int filterNumber, PLARGE_INTEGER writeOffset, PMDL dataMdl, BOOL writeB, ULONG arg0WriteA, PVOID arg3WriteA)
{
MDL *encryptedDataMdl = dataMdl;
if (writeOffset && dataMdl && BootDriveFilterExtension && BootDriveFilterExtension->DriveMounted)
{
ULONG dataLength = MmGetMdlByteCount (dataMdl);
if (dataMdl->MappedSystemVa && dataLength > 0)
{
uint64 offset = HiberPartitionOffset.QuadPart + writeOffset->QuadPart;
uint64 intersectStart;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -