📄 ntdriver.c
字号:
break;
case TC_IOCTL_OPEN_TEST:
{
OPEN_TEST_STRUCT *opentest = (OPEN_TEST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE NtFileHandle;
UNICODE_STRING FullFileName;
IO_STATUS_BLOCK IoStatus;
LARGE_INTEGER offset;
unsigned char readBuffer [SECTOR_SIZE];
NTSTATUS TCBootLoaderDetected = STATUS_NO_SUCH_DEVICE; // STATUS_NO_SUCH_DEVICE is sent when the boot loader is not found (even if the device is found)
if (!ValidateIOBufferSize (Irp, sizeof (OPEN_TEST_STRUCT), ValidateInput))
break;
EnsureNullTerminatedString (opentest->wszFileName, sizeof (opentest->wszFileName));
RtlInitUnicodeString (&FullFileName, opentest->wszFileName);
InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE,
NULL, NULL);
ntStatus = ZwCreateFile (&NtFileHandle,
SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL /* alloc size = none */ ,
FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_RANDOM_ACCESS, NULL, 0);
if (NT_SUCCESS (ntStatus))
{
if (opentest->bDetectTCBootLoader)
{
// Determine if the first sector contains a portion of the TrueCrypt Boot Loader
offset.QuadPart = 0; // MBR
ntStatus = ZwReadFile (NtFileHandle,
NULL,
NULL,
NULL,
&IoStatus,
readBuffer,
sizeof(readBuffer),
&offset,
NULL);
if (NT_SUCCESS (ntStatus))
{
size_t i;
// Search for the string "TrueCrypt"
for (i = 0; i < sizeof (readBuffer) - strlen (TC_APP_NAME); ++i)
{
if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0)
{
TCBootLoaderDetected = STATUS_SUCCESS;
break;
}
}
}
}
ZwClose (NtFileHandle);
Dump ("Open test on file %ls success.\n", opentest->wszFileName);
}
else
{
#if 0
Dump ("Open test on file %ls failed NTSTATUS 0x%08x\n", opentest->wszFileName, ntStatus);
#endif
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = opentest->bDetectTCBootLoader ? TCBootLoaderDetected : ntStatus;
}
break;
case TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG:
{
GetSystemDriveConfigurationRequest *request = (GetSystemDriveConfigurationRequest *) Irp->AssociatedIrp.SystemBuffer;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE NtFileHandle;
UNICODE_STRING FullFileName;
IO_STATUS_BLOCK IoStatus;
LARGE_INTEGER offset;
byte readBuffer [SECTOR_SIZE];
if (!ValidateIOBufferSize (Irp, sizeof (GetSystemDriveConfigurationRequest), ValidateInputOutput))
break;
EnsureNullTerminatedString (request->DevicePath, sizeof (request->DevicePath));
RtlInitUnicodeString (&FullFileName, request->DevicePath);
InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
ntStatus = ZwCreateFile (&NtFileHandle,
SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL,
FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_RANDOM_ACCESS, NULL, 0);
if (NT_SUCCESS (ntStatus))
{
// Determine if the first sector contains a portion of the TrueCrypt Boot Loader
offset.QuadPart = 0; // MBR
ntStatus = ZwReadFile (NtFileHandle,
NULL,
NULL,
NULL,
&IoStatus,
readBuffer,
sizeof(readBuffer),
&offset,
NULL);
if (NT_SUCCESS (ntStatus))
{
size_t i;
// Check for dynamic drive
request->DriveIsDynamic = FALSE;
if (readBuffer[510] == 0x55 && readBuffer[511] == 0xaa)
{
int i;
for (i = 0; i < 4; ++i)
{
if (readBuffer[446 + i * 16 + 4] == PARTITION_LDM)
{
request->DriveIsDynamic = TRUE;
break;
}
}
}
request->BootLoaderVersion = 0;
request->Configuration = 0;
request->UserConfiguration = 0;
request->CustomUserMessage[0] = 0;
// Search for the string "TrueCrypt"
for (i = 0; i < sizeof (readBuffer) - strlen (TC_APP_NAME); ++i)
{
if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0)
{
request->BootLoaderVersion = BE16 (*(uint16 *) (readBuffer + TC_BOOT_SECTOR_VERSION_OFFSET));
request->Configuration = readBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET];
if (request->BootLoaderVersion != 0)
{
request->UserConfiguration = readBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET];
memcpy (request->CustomUserMessage, readBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
}
break;
}
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof (*request);
}
else
{
Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = 0;
}
ZwClose (NtFileHandle);
}
else
{
Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = 0;
}
}
break;
case TC_IOCTL_WIPE_PASSWORD_CACHE:
DriverMutexWait ();
WipeCache ();
DriverMutexRelease ();
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
case TC_IOCTL_GET_PASSWORD_CACHE_STATUS:
Irp->IoStatus.Status = cacheEmpty ? STATUS_PIPE_EMPTY : STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
case TC_IOCTL_SET_TRAVELER_MODE_STATUS:
if (!UserCanAccessDriveDevice())
{
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
}
else
{
TravelerMode = TRUE;
Dump ("Setting traveler mode\n");
}
break;
case TC_IOCTL_GET_TRAVELER_MODE_STATUS:
Irp->IoStatus.Status = TravelerMode ? STATUS_SUCCESS : STATUS_PIPE_EMPTY;
Irp->IoStatus.Information = 0;
break;
case TC_IOCTL_GET_MOUNTED_VOLUMES:
if (ValidateIOBufferSize (Irp, sizeof (MOUNT_LIST_STRUCT), ValidateOutput))
{
MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
PDEVICE_OBJECT ListDevice;
DriverMutexWait ();
list->ulMountedDrives = 0;
for (ListDevice = DeviceObject->DriverObject->DeviceObject;
ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
{
PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
if (!ListExtension->bRootDevice
&& ListExtension->IsVolumeDevice
&& !ListExtension->bShuttingDown
&& ListExtension->lMagicNumber == 0xabfeacde
&& IsVolumeAccessibleByCurrentUser (ListExtension))
{
list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo);
wcscpy (list->wszVolume[ListExtension->nDosDriveNo], ListExtension->wszVolume);
list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength;
list->ea[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->ea;
if (ListExtension->cryptoInfo->hiddenVolume)
list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_HIDDEN; // Hidden volume
else if (ListExtension->cryptoInfo->bHiddenVolProtectionAction)
list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED; // Normal/outer volume (hidden volume protected AND write already prevented)
else if (ListExtension->cryptoInfo->bProtectHiddenVolume)
list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_OUTER; // Normal/outer volume (hidden volume protected)
else
list->volumeType[ListExtension->nDosDriveNo] = PROP_VOL_TYPE_NORMAL; // Normal volume
}
}
DriverMutexRelease ();
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT);
}
break;
case TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES:
if (ValidateIOBufferSize (Irp, sizeof (uint32), ValidateOutput))
{
// Prevent the user from downgrading to versions lower than 5.0 by faking mounted volumes.
// The user could render the system unbootable by downgrading when boot encryption
// is active or being set up.
memset (Irp->AssociatedIrp.SystemBuffer, 0, irpSp->Parameters.DeviceIoControl.OutputBufferLength);
*(uint32 *) Irp->AssociatedIrp.SystemBuffer = 0xffffFFFF;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
}
break;
case TC_IOCTL_GET_VOLUME_PROPERTIES:
if (ValidateIOBufferSize (Irp, sizeof (VOLUME_PROPERTIES_STRUCT), ValidateInputOutput))
{
VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
PDEVICE_OBJECT ListDevice;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
DriverMutexWait ();
for (ListDevice = DeviceObject->DriverObject->DeviceObject;
ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
{
PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
if (!ListExtension->bRootDevice
&& ListExtension->IsVolumeDevice
&& !ListExtension->bShuttingDown
&& ListExtension->nDosDriveNo == prop->driveNo
&& IsVolumeAccessibleByCurrentUser (ListExtension))
{
prop->uniqueId = ListExtension->UniqueVolumeId;
wcscpy (prop->wszVolume, ListExtension->wszVolume);
prop->diskLength = ListExtension->DiskLength;
prop->ea = ListExtension->cryptoInfo->ea;
prop->mode = ListExtension->cryptoInfo->mode;
prop->pkcs5 = ListExtension->cryptoInfo->pkcs5;
prop->pkcs5Iterations = ListExtension->cryptoInfo->noIterations;
#if 0
prop->volumeCreationTime = ListExtension->cryptoInfo->volume_creation_time;
prop->headerCreationTime = ListExtension->cryptoInfo->header_creation_time;
#endif
prop->volumeHeaderFlags = ListExtension->cryptoInfo->HeaderFlags;
prop->readOnly = ListExtension->bReadOnly;
prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume;
if (ListExtension->cryptoInfo->bProtectHiddenVolume)
prop->hiddenVolProtection = ListExtension->cryptoInfo->bHiddenVolProtectionAction ? HIDVOL_PROT_STATUS_ACTION_TAKEN : HIDVOL_PROT_STATUS_ACTIVE;
else
prop->hiddenVolProtection = HIDVOL_PROT_STATUS_NONE;
prop->totalBytesRead = ListExtension->Queue.TotalBytesRead;
prop->totalBytesWritten = ListExtension->Queue.TotalBytesWritten;
prop->volFormatVersion = ListExtension->cryptoInfo->LegacyVolume ? TC_VOLUME_FORMAT_VERSION_PRE_6_0 : TC_VOLUME_FORMAT_VERSION;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT);
break;
}
}
DriverMutexRelease ();
}
break;
case TC_IOCTL_GET_RESOLVED_SYMLINK:
if (ValidateIOBufferSize (Irp, sizeof (RESOLVE_SYMLINK_STRUCT), ValidateInputOutput))
{
RESOLVE_SYMLINK_STRUCT *resolve = (RESOLVE_SYMLINK_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
{
NTSTATUS ntStatus;
EnsureNullTerminatedString (resolve->symLinkName, sizeof (resolve->symLinkName));
ntStatus = SymbolicLinkToTarget (resolve->symLinkName,
resolve->targetName,
sizeof (resolve->targetName));
Irp->IoStatus.Information = sizeof (RESOLVE_SYMLINK_STRUCT);
Irp->IoStatus.Status = ntStatus;
}
}
break;
case TC_IOCTL_GET_DRIVE_PARTITION_INFO:
if (ValidateIOBufferSize (Irp, sizeof (DISK_PARTITION_INFO_STRUCT), ValidateInputOutput))
{
DISK_PARTITION_INFO_STRUCT *info = (DISK_PARTITION_INFO_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
{
PARTITION_INFORMATION_EX pi;
NTSTATUS ntStatus;
EnsureNullTerminatedString (info->deviceName, sizeof (info->deviceName));
ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pi, sizeof (pi));
if (NT_SUCCESS(ntStatus))
{
memset (&info->partInfo, 0, sizeof (info->partInfo));
info->partInfo.PartitionLength = pi.PartitionLength;
info->partInfo.PartitionNumber = pi.PartitionNumber;
info->partInfo.StartingOffset = pi.StartingOffset;
if (pi.PartitionStyle == PARTITION_STYLE_MBR)
{
info->partInfo.PartitionType = pi.Mbr.PartitionType;
info->partInfo.BootIndicator = pi.Mbr.BootIndicator;
}
info->IsGPT = pi.PartitionStyle == PARTITION_STYLE_GPT;
}
else
{
// Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX
ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &info->partInfo, sizeof (info->partInfo));
info->IsGPT = FALSE;
}
if (!NT_SUCCESS (ntStatus))
{
GET_LENGTH_INFORMATION lengthInfo;
ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &lengthInfo, sizeof (lengthInfo));
if (NT_SUCCESS (ntStatus))
{
memset (&info->partInfo, 0, sizeof (info->partInfo));
info->partInfo.PartitionLength = lengthInfo.Length;
}
}
info->IsDynamic = FALSE;
if (NT_SUCCESS (ntStatus) && OsMajorVersion >= 6)
{
# define IOCTL_VOLUME_IS_DYNAMIC CTL_CODE(IOCTL_VOLUME_BASE, 18, METHOD_BUFFERED, FILE_ANY_ACCESS)
if (!NT_SUCCESS (TCDeviceIoControl (info->deviceName, IOCTL_VOLUME_IS_DYNAMIC, NULL, 0, &info->IsDynamic, sizeof (info->IsDynamic))))
info->IsDynamic = FALSE;
}
Irp->IoStatus.Information = sizeof (DISK_PARTITION_INFO_STRUCT);
Irp->IoStatus.Status = ntStatus;
}
}
break;
case TC_IOCTL_GET_DRIVE_GEOMETRY:
if (ValidateIOBufferSize (Irp, sizeof (DISK_GEOMETRY_STRUCT), ValidateInputOutput))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -