2

I want to develop an encrypt-virtual-disk based on the FileDisk-17 opensource project.

Here is my solution:

In IPR_MJ_READ, when the ZwReadFile returns, I use function 'DecryptData' to decrypt the data read by ZwReadFile.

In IPR_MJ_WRITE, before call ZwWriteFile, I use function 'EncryptData' to encrypt the data which will be written to the disk.

I put EncryptData & DecryptData functions in a single C source file.

The question is; when I loaded my driver, I get the ERROR_PROC_NOT_FOUND(127) error code every time, even there are only one line in the EncryptData or DecryptData function.

Who can tell me what caused this and how to fix it?

filedisk.c

switch (io_stack->MajorFunction)
        {
        case IRP_MJ_READ:
            system_buffer = (PUCHAR) MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
            if (system_buffer == NULL)
            {
                irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                irp->IoStatus.Information = 0;
                break;
            }
            buffer = (PUCHAR) ExAllocatePool(PagedPool, io_stack->Parameters.Read.Length);
            if (buffer == NULL)
            {
                irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                irp->IoStatus.Information = 0;
                break;
            }
            ZwReadFile(
                device_extension->file_handle,
                NULL,
                NULL,
                NULL,
                &irp->IoStatus,
                buffer,
                io_stack->Parameters.Read.Length,
                &io_stack->Parameters.Read.ByteOffset,
                NULL
                );
            *if(bEncrypt)
            {
                cipher = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, irp->IoStatus.Information, 'TAG');
                if(cipher)
                {   
                    **DecryptData**(buffer, cipher, irp->IoStatus.Information);
                    RtlCopyMemory(system_buffer, cipher, irp->IoStatus.Information);
                    ExFreePool(cipher);
                }
                else
                {
                    irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                    irp->IoStatus.Information = 0;
                    break;
                }
            }*
            else
            {
                RtlCopyMemory(system_buffer, buffer, io_stack->Parameters.Read.Length);
                ExFreePool(buffer);
            }

crypto.c

    VOID EncryptData(PUCHAR src, PUCHAR dst, ULONG length)
{
    BF_LONG data[2];
    BF_KEY  key;

    BF_set_key(&key, pCryptoInformation->CryptoKey, sizeof(pCryptoInformation->CryptoKey));
}

VOID DecryptData(PUCHAR src, PUCHAR dst, ULONG length)
{
    BF_LONG data[2];
    BF_KEY  key;

    BF_set_key(&key, pCryptoInformation->CryptoKey, sizeof(pCryptoInformation->CryptoKey));
}
Kecise
  • 61
  • 6
  • Is `crypto.c` statically linked into the driver? Are you using the right build tool, i.e., the Windows DDK? Have you successfully built the unmodified project? – Harry Johnston Jun 18 '13 at 05:00
  • I added the 'crypto.c' into the SOURCES part of the Source file, like this: 'SOURCES=filedisk.c filedisk.rc bf_skey.c bf_enc.c crypto.c'; I uses the DDK's build tool and the DDK's version is 7600.16385.1. – Kecise Jun 18 '13 at 05:51
  • So if you take the calls to EncryptData and DecryptData out, does the driver then load properly? Are the functions properly labelled as non-pageable? – Harry Johnston Jun 18 '13 at 05:55
  • Have you successfully built and loaded the unmodified project? – Harry Johnston Jun 18 '13 at 06:01
  • Yes, I can loaded the unmodified project successfully. Yesterday, I commented a pre-process instruction:#pragma code_seg(), when I load the driver, I got a system crash with PAGE_FALUT_IN_NONPAGED_AREA error code. I uncommented the #pragma code_seg() pre-process instruction and deleted all code inside the EncryptData and DecryptData functions, the driver can loaded successfully. Is this a PAGED problem? – Kecise Jun 20 '13 at 01:26
  • Doesn't sound like it. If removing the code in EncryptData/DecryptData resolved the problem, the problem is probably something to do with BF_set_key. What if you put the call to BF_set_key back in but remove the code in BF_set_key? I assume you've turned off all compiler optimizations? – Harry Johnston Jun 20 '13 at 03:53
  • Hold on ... when you commented out the `#pragma` the driver would successfully load? That does suggest the problem is something to do with the segmentation. Give me a moment. – Harry Johnston Jun 20 '13 at 04:02
  • OK, having refreshed my memory, I don't believe commenting out `#pragma code_seg()` would cause a page fault unless there was a previous `#pragma` that changed the current segment. Try commenting out all segment-related `#pragma` commands and see what happens. – Harry Johnston Jun 20 '13 at 04:12
  • According to your suggestion, I commented the code one by one of the DecryptData and EncryptData function. Finally, I found that it is the BF_KEY casued the problem. Whether I commented all of the '#pragma', the driver can loaded successfully, but if I uncommented the 'BF_KEY', the ERROR_PROC_NOT_FOUND happed. The BF_KEY is defined like this: `typedef struct bf_key_st { BF_LONG P[BF_ROUNDS+2]; BF_LONG S[4*256]; } BF_KEY;` In Windows Server 2003 R2, `sizeof(BF_KEY)=4168`. Is The BF_KEY larger than the maximum stack space in driver-mode? – Kecise Jun 20 '13 at 07:57
  • It probably shouldn't be on the stack, no, but I'm puzzled as to how that would cause a load-time error. Random thought: try renaming the `EncryptData` and `DecryptData` functions, just in case there's a naming conflict. – Harry Johnston Jun 20 '13 at 21:04

0 Answers0