📄 filedisk.c
字号:
case IRP_MJ_WRITE:
if ((io_stack->Parameters.Write.ByteOffset.QuadPart +
io_stack->Parameters.Write.Length) >
device_extension->file_size.QuadPart)
{
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
irp->IoStatus.Information = 0;
}
if (device_extension->KeyType) {
dest = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
li = io_stack->Parameters.Write.ByteOffset;
totlen = 0;
for (off = 0;off == 0 || off < io_stack->Parameters.Write.Length;off += sizeof(tmpSect)) {
ULONG len = io_stack->Parameters.Read.Length-off;
NTSTATUS st;
if (len > sizeof(tmpSect)) len = sizeof(tmpSect);
switch (device_extension->KeyType ) {
case 1:
blockEncrypt_CBC(&device_extension->f2k,dest,tmpSect,len);
break;
case 2: //AES
case 3:
case 4:
sect.li.QuadPart = li.QuadPart >> 9;
memcpy(tmpSect,dest,len);
AESEncryptCBC(tmpSect,len,sect.devSect,&device_extension->aes);
break;
}
st = ZwWriteFile(
device_extension->file_handle,
NULL,
NULL,
NULL,
&irp->IoStatus,
tmpSect,
len,
&li,
NULL
);
if (!NT_SUCCESS(st)) break;
totlen = totlen + (ULONG)(irp->IoStatus.Information);
if (len != (ULONG)irp->IoStatus.Information) break; //EOF
dest = dest+len;
li.QuadPart += len;
}
if (NT_SUCCESS(irp->IoStatus.Status)) {
irp->IoStatus.Information = (ULONG_PTR)totlen;
}
} else {
ZwWriteFile(
device_extension->file_handle,
NULL,
NULL,
NULL,
&irp->IoStatus,
MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority),
io_stack->Parameters.Write.Length,
&io_stack->Parameters.Write.ByteOffset,
NULL
);
}
break;
case IRP_MJ_DEVICE_CONTROL:
switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_FILE_DISK_OPEN_FILE:
SeImpersonateClient(device_extension->security_client_context, NULL);
irp->IoStatus.Status = FileDiskOpenFile(device_object, irp);
PsRevertToSelf();
break;
case IOCTL_FILE_DISK_CLOSE_FILE:
irp->IoStatus.Status = FileDiskCloseFile(device_object, irp);
break;
default:
irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
}
break;
default:
irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
}
IoCompleteRequest(
irp,
(CCHAR) (NT_SUCCESS(irp->IoStatus.Status) ?
IO_DISK_INCREMENT : IO_NO_INCREMENT)
);
}
}
}
//#pragma code_seg("PAGE")
#pragma code_seg()
NTSTATUS
FileDiskOpenFile (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
POPEN_FILE_INFORMATION open_file_information;
UNICODE_STRING ufile_name;
NTSTATUS status;
OBJECT_ATTRIBUTES object_attributes;
FILE_END_OF_FILE_INFORMATION file_eof;
FILE_BASIC_INFORMATION file_basic;
FILE_STANDARD_INFORMATION file_standard;
FILE_ALIGNMENT_INFORMATION file_alignment;
//RMD160_CTX ctx;
//unsigned char tmp[64];
// PAGED_CODE();
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
open_file_information = (POPEN_FILE_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
if (DeviceObject->DeviceType != FILE_DEVICE_CD_ROM)
{
device_extension->read_only = open_file_information->ReadOnly;
}
device_extension->file_name.Length = open_file_information->FileNameLength;
device_extension->file_name.MaximumLength = open_file_information->FileNameLength;
device_extension->file_name.Buffer = ExAllocatePool(NonPagedPool, open_file_information->FileNameLength);
device_extension->KeyType = open_file_information->KeyType;
switch (device_extension->KeyType) {
case 1: //2fish
//RMD160Init(&ctx);
//RMD160Update(&ctx,open_file_information->Key,open_file_information->KeyLength);
//RMD160Final(device_extension->f2k.key,&ctx);
memcpy(device_extension->f2k.key,open_file_information->Key[0],20);
device_extension->f2k.keyLen = (DWORD32)(20<<3);
init_key(&device_extension->f2k);
break;
case 2: //AES256
//sha512_hash_buffer(open_file_information->Key,open_file_information->KeyLength,tmp,32);
if (rijndael_setup(open_file_information->Key[0], 32, 0, &device_extension->aes)) {
KdPrint(("AES256 KeySetup faild"));
}
break;
case 3: //AES128
//sha256_hash_buffer(open_file_information->Key,open_file_information->KeyLength,tmp,16);
if (rijndael_setup(open_file_information->Key[0], 16, 0, &device_extension->aes)) {
KdPrint(("AES128 KeySetup faild"));
}
break;
case 4: //AES192
//sha384_hash_buffer(open_file_information->Key,open_file_information->KeyLength,tmp,24);
if (rijndael_setup(open_file_information->Key[0], 24, 0, &device_extension->aes)) {
KdPrint(("AES192 KeySetup faild"));
}
break;
}
device_extension->DriveLetter = open_file_information->DriveLetter;
RtlCopyMemory(
device_extension->file_name.Buffer,
open_file_information->FileName,
open_file_information->FileNameLength
);
status = RtlAnsiStringToUnicodeString(
&ufile_name,
&device_extension->file_name,
TRUE
);
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
return status;
}
InitializeObjectAttributes(
&object_attributes,
&ufile_name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
KdPrint(("FileDisk: %s \n",open_file_information->FileName));
status = ZwCreateFile(
&device_extension->file_handle,
device_extension->read_only ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
&object_attributes,
&Irp->IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
//device_extension->read_only ? FILE_SHARE_READ : 0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE |
FILE_RANDOM_ACCESS |
FILE_NO_INTERMEDIATE_BUFFERING |
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
KdPrint(("FileDisk: 2 \n"));
if (status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_NO_SUCH_FILE)
{
KdPrint(("FileDisk: 3 \n"));
if (device_extension->read_only || open_file_information->FileSize.QuadPart == 0)
{
ExFreePool(device_extension->file_name.Buffer);
RtlFreeUnicodeString(&ufile_name);
Irp->IoStatus.Status = STATUS_NO_SUCH_FILE;
Irp->IoStatus.Information = 0;
return STATUS_NO_SUCH_FILE;
}
else
{
status = ZwCreateFile(
&device_extension->file_handle,
GENERIC_READ | GENERIC_WRITE,
&object_attributes,
&Irp->IoStatus,
&open_file_information->FileSize,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN_IF,
FILE_NON_DIRECTORY_FILE |
FILE_RANDOM_ACCESS |
FILE_NO_INTERMEDIATE_BUFFERING |
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
RtlFreeUnicodeString(&ufile_name);
return status;
}
if (Irp->IoStatus.Information == FILE_CREATED)
{
file_eof.EndOfFile.QuadPart = open_file_information->FileSize.QuadPart;
status = ZwSetInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_eof,
sizeof(FILE_END_OF_FILE_INFORMATION),
FileEndOfFileInformation
);
if (!NT_SUCCESS(status))
{
ExFreePool(device_extension->file_name.Buffer);
RtlFreeUnicodeString(&ufile_name);
ZwClose(device_extension->file_handle);
return status;
}
}
}
}
else if (!NT_SUCCESS(status))
{
KdPrint(("FileDisk: 4 \n"));
ExFreePool(device_extension->file_name.Buffer);
RtlFreeUnicodeString(&ufile_name);
return status;
}
RtlFreeUnicodeString(&ufile_name);
KdPrint(("FileDisk: 5 \n"));
status = ZwQueryInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_basic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation
);
KdPrint(("FileDisk: 6 \n"));
if (!NT_SUCCESS(status))
{
KdPrint(("FileDisk: 6.1 ignore \n"));
//ExFreePool(device_extension->file_name.Buffer);
//ZwClose(device_extension->file_handle);
//return status;
}
//
// The NT cache manager can deadlock if a filesystem that is using the cache
// manager is used in a virtual disk that stores its file on a filesystem
// that is also using the cache manager, this is why we open the file with
// FILE_NO_INTERMEDIATE_BUFFERING above, however if the file is compressed
// or encrypted NT will not honor this request and cache it anyway since it
// need to store the decompressed/unencrypted data somewhere, therefor we put
// an extra check here and don't alow disk images to be compressed/encrypted.
//
KdPrint(("FileDisk: 7 \n"));
if (!device_extension->read_only && (file_basic.FileAttributes & (FILE_ATTRIBUTE_COMPRESSED | FILE_ATTRIBUTE_ENCRYPTED)))
{
ExFreePool(device_extension->file_name.Buffer);
ZwClose(device_extension->file_handle);
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
return STATUS_ACCESS_DENIED;
}
KdPrint(("FileDisk: 8 \n"));
status = ZwQueryInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_standard,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation
);
if (!NT_SUCCESS(status))
{
KdPrint(("FileDisk: 9.1 ignore \n"));
//ExFreePool(device_extension->file_name.Buffer);
//ZwClose(device_extension->file_handle);
//return status;
}
device_extension->file_size.QuadPart = file_standard.EndOfFile.QuadPart;
KdPrint(("FileDisk: 10 \n"));
status = ZwQueryInformationFile(
device_extension->file_handle,
&Irp->IoStatus,
&file_alignment,
sizeof(FILE_ALIGNMENT_INFORMATION),
FileAlignmentInformation
);
if (!NT_SUCCESS(status))
{
KdPrint(("FileDisk: 11 ignotre\n"));
//ExFreePool(device_extension->file_name.Buffer);
//ZwClose(device_extension->file_handle);
//return status;
}
DeviceObject->AlignmentRequirement = file_alignment.AlignmentRequirement;
KdPrint(("FileDisk: 12 \n"));
if (device_extension->read_only)
{
DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
}
else
{
DeviceObject->Characteristics &= ~FILE_READ_ONLY_DEVICE;
}
KdPrint(("FileDisk: 13 \n"));
device_extension->media_in_device = TRUE;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
}
NTSTATUS
FileDiskCloseFile (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION device_extension;
// PAGED_CODE();
ASSERT(DeviceObject != NULL);
ASSERT(Irp != NULL);
device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
ExFreePool(device_extension->file_name.Buffer);
ZwClose(device_extension->file_handle);
device_extension->media_in_device = FALSE;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -