是否已经编写了一个函数来计算c++中用于文件系统的迷你过滤器驱动程序的MD5哈希?

时间:2022-10-28 18:39:19

I'm looking for a function that calculates the MD5 hash in C++ for a mini filter driver. Is there a function written in C++ already that can calculate the MD5 hash of a file as it comes into a file system mini filter driver?

我正在寻找一个函数,它计算一个微型过滤器驱动程序的c++ MD5散列。是否有一个函数在c++中编写,可以在文件系统的迷你过滤器驱动程序中计算文件的MD5哈希?

Basically, I'm going off the sample for the WDK 8.1 called "Scanner File System Minifilter Driver"

基本上,我要从WDK 8.1的样本中取下"扫描仪文件系统Minifilter Driver"

In the scanner.c file I want to be able to calculate a file's MD5 hash before I send up data about a file into usermode code (user >> scanuser.c).

扫描仪。在我将一个文件的数据发送到usermode代码(用户>> scanuser.c)之前,我希望能够计算一个文件的MD5哈希。

You can view the source code here:

你可以在这里查看源代码:

https://code.msdn.microsoft.com/windowshardware/Scanner-File-System-426c8cbe/view/SourceCode#content

https://code.msdn.microsoft.com/windowshardware/scanner -文件-系统- 426 c8cbe/view/sourcecode #内容

But here is the function I want to modify in filter >> scanner.c:

这里是我想在>> scanner.c中修改的函数。

NTSTATUS
ScannerpScanFileInUserMode (
    _In_ PFLT_INSTANCE Instance,
    _In_ PFILE_OBJECT FileObject,
    _Out_ PBOOLEAN SafeToOpen
    )
/*++

Routine Description:

    This routine is called to send a request up to user mode to scan a given
    file and tell our caller whether it's safe to open this file.

    Note that if the scan fails, we set SafeToOpen to TRUE.  The scan may fail
    because the service hasn't started, or perhaps because this create/cleanup
    is for a directory, and there's no data to read & scan.

    If we failed creates when the service isn't running, there'd be a
    bootstrapping problem -- how would we ever load the .exe for the service?

Arguments:

    Instance - Handle to the filter instance for the scanner on this volume.

    FileObject - File to be scanned.

    SafeToOpen - Set to FALSE if the file is scanned successfully and it contains
                 foul language.

Return Value:

    The status of the operation, hopefully STATUS_SUCCESS.  The common failure
    status will probably be STATUS_INSUFFICIENT_RESOURCES.

--*/

{
    NTSTATUS status = STATUS_SUCCESS;
    PVOID buffer = NULL;
    ULONG bytesRead;
    PSCANNER_NOTIFICATION notification = NULL;
    FLT_VOLUME_PROPERTIES volumeProps;
    LARGE_INTEGER offset;
    ULONG replyLength, length;
    PFLT_VOLUME volume = NULL;

    *SafeToOpen = TRUE;

    //
    //  If not client port just return.
    //

    if (ScannerData.ClientPort == NULL) {

        return STATUS_SUCCESS;
    }

    try {

        //
        //  Obtain the volume object .
        //

        status = FltGetVolumeFromInstance( Instance, &volume );

        if (!NT_SUCCESS( status )) {

            leave;
        }

        //
        //  Determine sector size. Noncached I/O can only be done at sector size offsets, and in lengths which are
        //  multiples of sector size. A more efficient way is to make this call once and remember the sector size in the
        //  instance setup routine and setup an instance context where we can cache it.
        //

        status = FltGetVolumeProperties( volume,
                                         &volumeProps,
                                         sizeof( volumeProps ),
                                         &length );
        //
        //  STATUS_BUFFER_OVERFLOW can be returned - however we only need the properties, not the names
        //  hence we only check for error status.
        //

        if (NT_ERROR( status )) {

            leave;
        }

        length = max( SCANNER_READ_BUFFER_SIZE, volumeProps.SectorSize );

        //
        //  Use non-buffered i/o, so allocate aligned pool
        //

        buffer = FltAllocatePoolAlignedWithTag( Instance,
                                                NonPagedPool,
                                                length,
                                                'nacS' );

        if (NULL == buffer) {

            status = STATUS_INSUFFICIENT_RESOURCES;
            leave;
        }

        notification = ExAllocatePoolWithTag( NonPagedPool,
                                              sizeof( SCANNER_NOTIFICATION ),
                                              'nacS' );

        if(NULL == notification) {

            status = STATUS_INSUFFICIENT_RESOURCES;
            leave;
        }

        //
        //  Read the beginning of the file and pass the contents to user mode.
        //

        offset.QuadPart = bytesRead = 0;
        status = FltReadFile( Instance,
                              FileObject,
                              &offset,
                              length,
                              buffer,
                              FLTFL_IO_OPERATION_NON_CACHED |
                              FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET,
                              &bytesRead,
                              NULL,
                              NULL );

        if (NT_SUCCESS( status ) && (0 != bytesRead)) {

            notification->BytesToScan = (ULONG) bytesRead;

            //
            //  Copy only as much as the buffer can hold
            //

            RtlCopyMemory( &notification->Contents,
                           buffer,
                           min( notification->BytesToScan, SCANNER_READ_BUFFER_SIZE ) );

            replyLength = sizeof( SCANNER_REPLY );

// TODO: Calculate MD5 Hash of the filter here and send up the data using the FltSendMessage function below. How do I go about calculating the MD5 here? Is there a function already written to handle such a thing?

// TODO:在这里计算过滤器的MD5散列,并使用下面的FltSendMessage函数发送数据。我该如何计算MD5呢?是否有一个函数已经写好来处理这样的事情?

            status = FltSendMessage( ScannerData.Filter,
                                     &ScannerData.ClientPort,
                                     notification,
                                     sizeof(SCANNER_NOTIFICATION),
                                     notification,
                                     &replyLength,
                                     NULL );

            if (STATUS_SUCCESS == status) {

                *SafeToOpen = ((PSCANNER_REPLY) notification)->SafeToOpen;

            } else {

                //
                //  Couldn't send message
                //

                DbgPrint( "!!! scanner.sys --- couldn't send message to user-mode to scan file, status 0x%X\n", status );
            }
        }

    } finally {

        if (NULL != buffer) {

            FltFreePoolAlignedWithTag( Instance, buffer, 'nacS' );
        }

        if (NULL != notification) {

            ExFreePoolWithTag( notification, 'nacS' );
        }

        if (NULL != volume) {

            FltObjectDereference( volume );
        }
    }

    return status;
}

2 个解决方案

#1


0  

void MD5( BYTE *szData, unsigned int uiSize, BYTE *bHash )
{
   HCRYPTPROV hCryptProv; 
   HCRYPTHASH hHash; 
   DWORD dwHashLen = 16; 

   if( CryptAcquireContext( &hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET ) )
   {
     if( CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash ) )
     {
       if( CryptHashData(hHash, (const BYTE *)szData, uiSize, 0))
       {
         CryptGetHashParam( hHash, HP_HASHVAL, bHash, &dwHashLen, 0 );
       }
     }
   }

   CryptDestroyHash(hHash); 
   CryptReleaseContext(hCryptProv, 0);
}

#2


0  

Though the original poster did not post any steps or attempts to show his own research in that set of problem(s) he is facing. The answer is easy, but so as not to reinvent the wheel, I am copying and pasting the code from rohitab

虽然最初的海报没有张贴任何步骤或试图展示他自己的研究在那一套问题(s)他面对。答案很简单,但是为了不重新发明*,我正在复制并粘贴rohitab的代码。

Here is the sample, you might want to adapt to the existing code of the mini-filter which should be easy if you read through the code.

这里有一个示例,您可能想要适应这个微型过滤器的现有代码,如果您仔细阅读代码,它应该是很容易的。

#include <ntifs.h>
#include <wdm.h>

typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef unsigned int md5_word_t; /* 32-bit word */

/* Define the state of the MD5 Algorithm. */
typedef struct md5_state_s {
    md5_word_t count[2];    /* message length in bits, lsw first */
    md5_word_t abcd[4];     /* digest buffer */
    md5_byte_t buf[64];     /* accumulate block */
} md5_state_t;

#define T_MASK ((md5_word_t)~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3    0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6    0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9    0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13    0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16    0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19    0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22    0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25    0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28    0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31    0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35    0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38    0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41    0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44    0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47    0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50    0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53    0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57    0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60    0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63    0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)

static void
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
    md5_word_t
        a = pms->abcd[0], b = pms->abcd[1],
        c = pms->abcd[2], d = pms->abcd[3];
    md5_word_t t;
#if BYTE_ORDER > 0
    /* Define storage only for big-endian CPUs. */
    md5_word_t X[16];
#else
    /* Define storage for little-endian or both types of CPUs. */
    md5_word_t xbuf[16];
    const md5_word_t *X;
#endif

    {
#if BYTE_ORDER == 0
        /*
        * Determine dynamically whether this is a big-endian or
        * little-endian machine, since we can use a more efficient
        * algorithm on the latter.
        */
        static const int w = 1;

        if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0      /* little-endian */
        {
            /*
            * On little-endian machines, we can process properly aligned
            * data without copying it.
            */
            if (!((data - (const md5_byte_t *)0) & 3)) {
                /* data are properly aligned */
                X = (const md5_word_t *)data;
            }
            else {
                /* not aligned */
                memcpy(xbuf, data, 64);
                X = xbuf;
            }
        }
#endif
#if BYTE_ORDER == 0
        else            /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0      /* big-endian */
        {
            /*
            * On big-endian machines, we must arrange the bytes in the
            * right order.
            */
            const md5_byte_t *xp = data;
            int i;

#  if BYTE_ORDER == 0
            X = xbuf;       /* (dynamic only) */
#  else
#    define xbuf X      /* (static only) */
#  endif
            for (i = 0; i < 16; ++i, xp += 4)
                xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
        }
#endif
    }

#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))

    /* Round 1. */
    /* Let [abcd k s i] denote the operation
    a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
    t = a + F(b, c, d) + X[k] + Ti; \
    a = ROTATE_LEFT(t, s) + b
    /* Do the following 16 operations. */
    SET(a, b, c, d, 0, 7, T1);
    SET(d, a, b, c, 1, 12, T2);
    SET(c, d, a, b, 2, 17, T3);
    SET(b, c, d, a, 3, 22, T4);
    SET(a, b, c, d, 4, 7, T5);
    SET(d, a, b, c, 5, 12, T6);
    SET(c, d, a, b, 6, 17, T7);
    SET(b, c, d, a, 7, 22, T8);
    SET(a, b, c, d, 8, 7, T9);
    SET(d, a, b, c, 9, 12, T10);
    SET(c, d, a, b, 10, 17, T11);
    SET(b, c, d, a, 11, 22, T12);
    SET(a, b, c, d, 12, 7, T13);
    SET(d, a, b, c, 13, 12, T14);
    SET(c, d, a, b, 14, 17, T15);
    SET(b, c, d, a, 15, 22, T16);
#undef SET

    /* Round 2. */
    /* Let [abcd k s i] denote the operation
    a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
    t = a + G(b, c, d) + X[k] + Ti; \
    a = ROTATE_LEFT(t, s) + b
    /* Do the following 16 operations. */
    SET(a, b, c, d, 1, 5, T17);
    SET(d, a, b, c, 6, 9, T18);
    SET(c, d, a, b, 11, 14, T19);
    SET(b, c, d, a, 0, 20, T20);
    SET(a, b, c, d, 5, 5, T21);
    SET(d, a, b, c, 10, 9, T22);
    SET(c, d, a, b, 15, 14, T23);
    SET(b, c, d, a, 4, 20, T24);
    SET(a, b, c, d, 9, 5, T25);
    SET(d, a, b, c, 14, 9, T26);
    SET(c, d, a, b, 3, 14, T27);
    SET(b, c, d, a, 8, 20, T28);
    SET(a, b, c, d, 13, 5, T29);
    SET(d, a, b, c, 2, 9, T30);
    SET(c, d, a, b, 7, 14, T31);
    SET(b, c, d, a, 12, 20, T32);
#undef SET

    /* Round 3. */
    /* Let [abcd k s t] denote the operation
    a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
    t = a + H(b, c, d) + X[k] + Ti; \
    a = ROTATE_LEFT(t, s) + b
    /* Do the following 16 operations. */
    SET(a, b, c, d, 5, 4, T33);
    SET(d, a, b, c, 8, 11, T34);
    SET(c, d, a, b, 11, 16, T35);
    SET(b, c, d, a, 14, 23, T36);
    SET(a, b, c, d, 1, 4, T37);
    SET(d, a, b, c, 4, 11, T38);
    SET(c, d, a, b, 7, 16, T39);
    SET(b, c, d, a, 10, 23, T40);
    SET(a, b, c, d, 13, 4, T41);
    SET(d, a, b, c, 0, 11, T42);
    SET(c, d, a, b, 3, 16, T43);
    SET(b, c, d, a, 6, 23, T44);
    SET(a, b, c, d, 9, 4, T45);
    SET(d, a, b, c, 12, 11, T46);
    SET(c, d, a, b, 15, 16, T47);
    SET(b, c, d, a, 2, 23, T48);
#undef SET

    /* Round 4. */
    /* Let [abcd k s t] denote the operation
    a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
    t = a + I(b, c, d) + X[k] + Ti; \
    a = ROTATE_LEFT(t, s) + b
    /* Do the following 16 operations. */
    SET(a, b, c, d, 0, 6, T49);
    SET(d, a, b, c, 7, 10, T50);
    SET(c, d, a, b, 14, 15, T51);
    SET(b, c, d, a, 5, 21, T52);
    SET(a, b, c, d, 12, 6, T53);
    SET(d, a, b, c, 3, 10, T54);
    SET(c, d, a, b, 10, 15, T55);
    SET(b, c, d, a, 1, 21, T56);
    SET(a, b, c, d, 8, 6, T57);
    SET(d, a, b, c, 15, 10, T58);
    SET(c, d, a, b, 6, 15, T59);
    SET(b, c, d, a, 13, 21, T60);
    SET(a, b, c, d, 4, 6, T61);
    SET(d, a, b, c, 11, 10, T62);
    SET(c, d, a, b, 2, 15, T63);
    SET(b, c, d, a, 9, 21, T64);
#undef SET

    /* Then perform the following additions. (That is increment each
    of the four registers by the value it had before this block
    was started.) */
    pms->abcd[0] += a;
    pms->abcd[1] += b;
    pms->abcd[2] += c;
    pms->abcd[3] += d;
}

void
md5_init(md5_state_t *pms)
{
    pms->count[0] = pms->count[1] = 0;
    pms->abcd[0] = 0x67452301;
    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
    pms->abcd[3] = 0x10325476;
}

void
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
{
    const md5_byte_t *p = data;
    int left = nbytes;
    int offset = (pms->count[0] >> 3) & 63;
    md5_word_t nbits = (md5_word_t)(nbytes << 3);

    if (nbytes <= 0)
        return;

    /* Update the message length. */
    pms->count[1] += nbytes >> 29;
    pms->count[0] += nbits;
    if (pms->count[0] < nbits)
        pms->count[1]++;

    /* Process an initial partial block. */
    if (offset) {
        int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);

        memcpy(pms->buf + offset, p, copy);
        if (offset + copy < 64)
            return;
        p += copy;
        left -= copy;
        md5_process(pms, pms->buf);
    }

    /* Process full blocks. */
    for (; left >= 64; p += 64, left -= 64)
        md5_process(pms, p);

    /* Process a final partial block. */
    if (left)
        memcpy(pms->buf, p, left);
}

void
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
{
    static const md5_byte_t pad[64] = {
        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
    md5_byte_t data[8];
    int i;

    for (i = 0; i < 8; ++i)
        data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));

    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);

    md5_append(pms, data, 8);
    for (i = 0; i < 16; ++i)
        digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}

VOID
MyUnload(
struct _DRIVER_OBJECT  *DriverObject
    )
{
    // Function body
}

char *                  /* O - MD5 sum in hex */
httpMD5String(const md5_byte_t *sum,    /* I - MD5 sum data */
char             md5[33])   /* O - MD5 sum in hex */
{
    int     i;          /* Looping var */
    char        *md5ptr;        /* Pointer into MD5 string */
    static char *hex = "0123456789abcdef";
    /* Hex digits */

    for (i = 16, md5ptr = md5; i > 0; i--, sum++)
    {
        *md5ptr++ = hex[*sum >> 4];
        *md5ptr++ = hex[*sum & 15];
    }

    *md5ptr = '\0';

    return (md5);
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath){
    md5_state_t state;          /* MD5 state info */
    md5_byte_t  sum[16];        /* Sum data */
    char mmd5[33];
    NTSTATUS status;
    UNICODE_STRING fileNameU;
    OBJECT_ATTRIBUTES objectAttributes;
    HANDLE fileHandle;
    IO_STATUS_BLOCK ioStatusBlock;
    unsigned char readBuffer[4096];

    memset(&ioStatusBlock, 0, sizeof(ioStatusBlock));
    memset(&objectAttributes, 0, sizeof(objectAttributes));

    objectAttributes.Length = sizeof(objectAttributes);
    objectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
    RtlInitUnicodeString(&fileNameU, L"\\??\\C:\\test.txt");
    objectAttributes.ObjectName = &fileNameU;

    status = NtCreateFile(&fileHandle, FILE_READ_ATTRIBUTES | GENERIC_READ | SYNCHRONIZE, &objectAttributes, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);

    DbgPrint("MD5 Init\n");
    md5_init(&state);
    DbgPrint("MD5 Append\n");

    memset(readBuffer, 0, 4096);

    while (1){
        status = NtReadFile(fileHandle, NULL, NULL, NULL, (PVOID)&ioStatusBlock, (PVOID)&readBuffer, 1024, NULL, NULL);
        if (NT_SUCCESS(status)){
            md5_append(&state, (unsigned char*)readBuffer, strlen(readBuffer));
            memset(readBuffer, 0, 4096);
        }
        else {
            break;
        }
    }

    DbgPrint("MD5 Finish\n");
    md5_finish(&state, sum);
    DbgPrint("Attempting to print Checksum\n");

    httpMD5String(sum, mmd5);
    DbgPrint("%s", mmd5);

    return STATUS_SUCCESS;
}

#1


0  

void MD5( BYTE *szData, unsigned int uiSize, BYTE *bHash )
{
   HCRYPTPROV hCryptProv; 
   HCRYPTHASH hHash; 
   DWORD dwHashLen = 16; 

   if( CryptAcquireContext( &hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET ) )
   {
     if( CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash ) )
     {
       if( CryptHashData(hHash, (const BYTE *)szData, uiSize, 0))
       {
         CryptGetHashParam( hHash, HP_HASHVAL, bHash, &dwHashLen, 0 );
       }
     }
   }

   CryptDestroyHash(hHash); 
   CryptReleaseContext(hCryptProv, 0);
}

#2


0  

Though the original poster did not post any steps or attempts to show his own research in that set of problem(s) he is facing. The answer is easy, but so as not to reinvent the wheel, I am copying and pasting the code from rohitab

虽然最初的海报没有张贴任何步骤或试图展示他自己的研究在那一套问题(s)他面对。答案很简单,但是为了不重新发明*,我正在复制并粘贴rohitab的代码。

Here is the sample, you might want to adapt to the existing code of the mini-filter which should be easy if you read through the code.

这里有一个示例,您可能想要适应这个微型过滤器的现有代码,如果您仔细阅读代码,它应该是很容易的。

#include <ntifs.h>
#include <wdm.h>

typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef unsigned int md5_word_t; /* 32-bit word */

/* Define the state of the MD5 Algorithm. */
typedef struct md5_state_s {
    md5_word_t count[2];    /* message length in bits, lsw first */
    md5_word_t abcd[4];     /* digest buffer */
    md5_byte_t buf[64];     /* accumulate block */
} md5_state_t;

#define T_MASK ((md5_word_t)~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3    0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6    0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9    0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13    0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16    0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19    0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22    0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25    0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28    0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31    0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35    0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38    0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41    0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44    0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47    0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50    0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53    0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57    0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60    0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63    0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)

static void
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
    md5_word_t
        a = pms->abcd[0], b = pms->abcd[1],
        c = pms->abcd[2], d = pms->abcd[3];
    md5_word_t t;
#if BYTE_ORDER > 0
    /* Define storage only for big-endian CPUs. */
    md5_word_t X[16];
#else
    /* Define storage for little-endian or both types of CPUs. */
    md5_word_t xbuf[16];
    const md5_word_t *X;
#endif

    {
#if BYTE_ORDER == 0
        /*
        * Determine dynamically whether this is a big-endian or
        * little-endian machine, since we can use a more efficient
        * algorithm on the latter.
        */
        static const int w = 1;

        if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0      /* little-endian */
        {
            /*
            * On little-endian machines, we can process properly aligned
            * data without copying it.
            */
            if (!((data - (const md5_byte_t *)0) & 3)) {
                /* data are properly aligned */
                X = (const md5_word_t *)data;
            }
            else {
                /* not aligned */
                memcpy(xbuf, data, 64);
                X = xbuf;
            }
        }
#endif
#if BYTE_ORDER == 0
        else            /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0      /* big-endian */
        {
            /*
            * On big-endian machines, we must arrange the bytes in the
            * right order.
            */
            const md5_byte_t *xp = data;
            int i;

#  if BYTE_ORDER == 0
            X = xbuf;       /* (dynamic only) */
#  else
#    define xbuf X      /* (static only) */
#  endif
            for (i = 0; i < 16; ++i, xp += 4)
                xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
        }
#endif
    }

#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))

    /* Round 1. */
    /* Let [abcd k s i] denote the operation
    a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
    t = a + F(b, c, d) + X[k] + Ti; \
    a = ROTATE_LEFT(t, s) + b
    /* Do the following 16 operations. */
    SET(a, b, c, d, 0, 7, T1);
    SET(d, a, b, c, 1, 12, T2);
    SET(c, d, a, b, 2, 17, T3);
    SET(b, c, d, a, 3, 22, T4);
    SET(a, b, c, d, 4, 7, T5);
    SET(d, a, b, c, 5, 12, T6);
    SET(c, d, a, b, 6, 17, T7);
    SET(b, c, d, a, 7, 22, T8);
    SET(a, b, c, d, 8, 7, T9);
    SET(d, a, b, c, 9, 12, T10);
    SET(c, d, a, b, 10, 17, T11);
    SET(b, c, d, a, 11, 22, T12);
    SET(a, b, c, d, 12, 7, T13);
    SET(d, a, b, c, 13, 12, T14);
    SET(c, d, a, b, 14, 17, T15);
    SET(b, c, d, a, 15, 22, T16);
#undef SET

    /* Round 2. */
    /* Let [abcd k s i] denote the operation
    a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
    t = a + G(b, c, d) + X[k] + Ti; \
    a = ROTATE_LEFT(t, s) + b
    /* Do the following 16 operations. */
    SET(a, b, c, d, 1, 5, T17);
    SET(d, a, b, c, 6, 9, T18);
    SET(c, d, a, b, 11, 14, T19);
    SET(b, c, d, a, 0, 20, T20);
    SET(a, b, c, d, 5, 5, T21);
    SET(d, a, b, c, 10, 9, T22);
    SET(c, d, a, b, 15, 14, T23);
    SET(b, c, d, a, 4, 20, T24);
    SET(a, b, c, d, 9, 5, T25);
    SET(d, a, b, c, 14, 9, T26);
    SET(c, d, a, b, 3, 14, T27);
    SET(b, c, d, a, 8, 20, T28);
    SET(a, b, c, d, 13, 5, T29);
    SET(d, a, b, c, 2, 9, T30);
    SET(c, d, a, b, 7, 14, T31);
    SET(b, c, d, a, 12, 20, T32);
#undef SET

    /* Round 3. */
    /* Let [abcd k s t] denote the operation
    a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
    t = a + H(b, c, d) + X[k] + Ti; \
    a = ROTATE_LEFT(t, s) + b
    /* Do the following 16 operations. */
    SET(a, b, c, d, 5, 4, T33);
    SET(d, a, b, c, 8, 11, T34);
    SET(c, d, a, b, 11, 16, T35);
    SET(b, c, d, a, 14, 23, T36);
    SET(a, b, c, d, 1, 4, T37);
    SET(d, a, b, c, 4, 11, T38);
    SET(c, d, a, b, 7, 16, T39);
    SET(b, c, d, a, 10, 23, T40);
    SET(a, b, c, d, 13, 4, T41);
    SET(d, a, b, c, 0, 11, T42);
    SET(c, d, a, b, 3, 16, T43);
    SET(b, c, d, a, 6, 23, T44);
    SET(a, b, c, d, 9, 4, T45);
    SET(d, a, b, c, 12, 11, T46);
    SET(c, d, a, b, 15, 16, T47);
    SET(b, c, d, a, 2, 23, T48);
#undef SET

    /* Round 4. */
    /* Let [abcd k s t] denote the operation
    a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
    t = a + I(b, c, d) + X[k] + Ti; \
    a = ROTATE_LEFT(t, s) + b
    /* Do the following 16 operations. */
    SET(a, b, c, d, 0, 6, T49);
    SET(d, a, b, c, 7, 10, T50);
    SET(c, d, a, b, 14, 15, T51);
    SET(b, c, d, a, 5, 21, T52);
    SET(a, b, c, d, 12, 6, T53);
    SET(d, a, b, c, 3, 10, T54);
    SET(c, d, a, b, 10, 15, T55);
    SET(b, c, d, a, 1, 21, T56);
    SET(a, b, c, d, 8, 6, T57);
    SET(d, a, b, c, 15, 10, T58);
    SET(c, d, a, b, 6, 15, T59);
    SET(b, c, d, a, 13, 21, T60);
    SET(a, b, c, d, 4, 6, T61);
    SET(d, a, b, c, 11, 10, T62);
    SET(c, d, a, b, 2, 15, T63);
    SET(b, c, d, a, 9, 21, T64);
#undef SET

    /* Then perform the following additions. (That is increment each
    of the four registers by the value it had before this block
    was started.) */
    pms->abcd[0] += a;
    pms->abcd[1] += b;
    pms->abcd[2] += c;
    pms->abcd[3] += d;
}

void
md5_init(md5_state_t *pms)
{
    pms->count[0] = pms->count[1] = 0;
    pms->abcd[0] = 0x67452301;
    pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
    pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
    pms->abcd[3] = 0x10325476;
}

void
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
{
    const md5_byte_t *p = data;
    int left = nbytes;
    int offset = (pms->count[0] >> 3) & 63;
    md5_word_t nbits = (md5_word_t)(nbytes << 3);

    if (nbytes <= 0)
        return;

    /* Update the message length. */
    pms->count[1] += nbytes >> 29;
    pms->count[0] += nbits;
    if (pms->count[0] < nbits)
        pms->count[1]++;

    /* Process an initial partial block. */
    if (offset) {
        int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);

        memcpy(pms->buf + offset, p, copy);
        if (offset + copy < 64)
            return;
        p += copy;
        left -= copy;
        md5_process(pms, pms->buf);
    }

    /* Process full blocks. */
    for (; left >= 64; p += 64, left -= 64)
        md5_process(pms, p);

    /* Process a final partial block. */
    if (left)
        memcpy(pms->buf, p, left);
}

void
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
{
    static const md5_byte_t pad[64] = {
        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    };
    md5_byte_t data[8];
    int i;

    for (i = 0; i < 8; ++i)
        data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));

    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);

    md5_append(pms, data, 8);
    for (i = 0; i < 16; ++i)
        digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}

VOID
MyUnload(
struct _DRIVER_OBJECT  *DriverObject
    )
{
    // Function body
}

char *                  /* O - MD5 sum in hex */
httpMD5String(const md5_byte_t *sum,    /* I - MD5 sum data */
char             md5[33])   /* O - MD5 sum in hex */
{
    int     i;          /* Looping var */
    char        *md5ptr;        /* Pointer into MD5 string */
    static char *hex = "0123456789abcdef";
    /* Hex digits */

    for (i = 16, md5ptr = md5; i > 0; i--, sum++)
    {
        *md5ptr++ = hex[*sum >> 4];
        *md5ptr++ = hex[*sum & 15];
    }

    *md5ptr = '\0';

    return (md5);
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath){
    md5_state_t state;          /* MD5 state info */
    md5_byte_t  sum[16];        /* Sum data */
    char mmd5[33];
    NTSTATUS status;
    UNICODE_STRING fileNameU;
    OBJECT_ATTRIBUTES objectAttributes;
    HANDLE fileHandle;
    IO_STATUS_BLOCK ioStatusBlock;
    unsigned char readBuffer[4096];

    memset(&ioStatusBlock, 0, sizeof(ioStatusBlock));
    memset(&objectAttributes, 0, sizeof(objectAttributes));

    objectAttributes.Length = sizeof(objectAttributes);
    objectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
    RtlInitUnicodeString(&fileNameU, L"\\??\\C:\\test.txt");
    objectAttributes.ObjectName = &fileNameU;

    status = NtCreateFile(&fileHandle, FILE_READ_ATTRIBUTES | GENERIC_READ | SYNCHRONIZE, &objectAttributes, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);

    DbgPrint("MD5 Init\n");
    md5_init(&state);
    DbgPrint("MD5 Append\n");

    memset(readBuffer, 0, 4096);

    while (1){
        status = NtReadFile(fileHandle, NULL, NULL, NULL, (PVOID)&ioStatusBlock, (PVOID)&readBuffer, 1024, NULL, NULL);
        if (NT_SUCCESS(status)){
            md5_append(&state, (unsigned char*)readBuffer, strlen(readBuffer));
            memset(readBuffer, 0, 4096);
        }
        else {
            break;
        }
    }

    DbgPrint("MD5 Finish\n");
    md5_finish(&state, sum);
    DbgPrint("Attempting to print Checksum\n");

    httpMD5String(sum, mmd5);
    DbgPrint("%s", mmd5);

    return STATUS_SUCCESS;
}