2017-04-13 50 views
0

我试图编写一个实现md5哈希单向链表的驱动程序。迭代一个单向链表不工作驱动程序

我到目前为止的代码是:

Signature.h

#ifndef SIGNATURE_H 
#define SIGNATURE_H 

typedef struct { 
    char hash[33]; // last byte for null terminator 
    SINGLE_LIST_ENTRY next; 
} SIGNATURE, *PSIGNATURE; 

#endif 

SignatureList.h

#define CopyCharArrays(src, dest, len)  \ 
do {         \ 
    for (int i = 0; i < len; i++)  \ 
     dest[i] = src[i];    \ 
    dest[len] = '\0';     \ 
} while(0)   

/* Return TRUE if strings are equal */ 
static BOOLEAN IsEqual(char* str1, char* str2, int len) 
{ 
    for (int i = 0; i < len; i++) 
     if (str1[i] != str2[i]) 
      return FALSE; 

    return TRUE; 
} 
SINGLE_LIST_ENTRY Head; 

static void AddToSignatureList(char hash[32]) { 
    PSIGNATURE Sig = ExAllocatePool(NonPagedPoolNx, sizeof(SIGNATURE)); // allocate memory to store a SIGNATURE node 

    CopyCharArrays(hash, Sig->hash, 32); // place the hash in our new allocated node (puts null terminator at position 33) 

    DbgPrintEx(0, DPFLTR_ERROR_LEVEL, "Hash: %s\n", Sig->hash); 
    PushEntryList(&Head, &Sig->next); // insert the new node in our list 
} 

/*Returns TRUE if the hash is in the library*/ 
static BOOLEAN SignatureScan(char hash[32]) 
{ 
    if (IsListEmpty(Head)) { // if there is no signature in the index 
     return FALSE; 
    } 
    else { 
     PSINGLE_LIST_ENTRY pSig = Head; // this is the pointer we will use to iterate 
     PSIGNATURE Sig; 

     do { 
      Sig = CONTAINING_RECORD(pSig, SIGNATURE, next); // get the PSIGNATURE on the current pointer 

      DbgPrintEx(0, DPFLTR_ERROR_LEVEL, "%s - %s\n", Sig->hash, hash); 
      if (!IsEqual(Sig->hash, hash, 32)) { 
       return TRUE; 
      } 

      pSig = &Sig->next; // go to the next node 
     } while (pSig != Head); 

     return FALSE; 
    } 
} 

MAIN.C

AddToSignatureList("2d75cc1bf8e57872781f9cd04a529256"); 
AddToSignatureList("00f538c3d410822e241486ca061a57ee"); 
AddToSignatureList("3f066dd1f1da052248aed5abc4a0c6a1"); 
AddToSignatureList("781770fda3bd3236d0ab8274577dddde"); 
AddToSignatureList("86b6c59aa48a69e16d3313d982791398"); 

DbgPrintEx(0, DPFLTR_ERROR_LEVEL, "Should return TRUE: %d\n", SignatureScan("3f066dd1f1da052248aed5abc4a0c6a1")); 
DbgPrintEx(0, DPFLTR_ERROR_LEVEL, "Should return FALSE: %d\n", SignatureScan("3f066dd1f1da052248aed5abc4a0c6a2")); 
DbgPrintEx(0, DPFLTR_ERROR_LEVEL, "Should return FALSE: %d\n", SignatureScan("526ae1b5f10eccfa069f4fd1c8b18097")); 

我真的不能弄清楚。它不会崩溃,WinDbg的输出是: WinDBG output

我已阅读并this blog postthis msdn article我还是不知道什么是错在我的司机

+1

听起来像你需要使用调试器。 – aschepler

+0

@aschepler我正在使用WinDBG ..但你的意思是用它来查看内存空间? – L3n

+1

逐步浏览您的代码,看看这些值的位置是不是您所期望的。 – aschepler

回答

2

我看到几个可能的问题。

  • 您的循环未正确初始化。

    PSINGLE_LIST_ENTRY pSig = Head; 
    PSIGNATURE Sig; 
    
    do { 
        Sig = CONTAINING_RECORD(pSig, SIGNATURE, next); 
    

第一次通过该循环中,在pSigHead指向其为SIGNATURE结构的一部分,所以在无意义指针调用CONTAINING_RECORD结果。

  • 您还没有正确退出循环。单链表的结尾由空指针表示,而不是由指向标头的指针表示。

  • 而且,去三联供,你是不是递增列表中正确或者:

    pSig = &Sig->next; // go to the next node 
    

Sig->next指向当前节点,而不是下一个节点。

  • IsListEmpty用于双链表,而不是单链表。该代码甚至不应该编译。

  • PSINGLE_LIST_ENTRY而非SINGLE_LIST_ENTRYHead的选择是奇数,并且初始化Head代码丢失。

  • 参数hash被声明为32个字符的数组,它应该是33个字符以允许空终止符。

我认为功能应该看起来更像是这样的:

SINGLE_LIST_ENTRY Head = {NULL}; 

static BOOLEAN SignatureScan(char hash[33]) 
{ 
    PSINGLE_LIST_ENTRY pSig = Head->Next; 
    PSIGNATURE Sig; 

    while (pSig != NULL) 
    { 
     Sig = CONTAINING_RECORD(pSig, SIGNATURE, next); 

     DbgPrintEx(0, DPFLTR_ERROR_LEVEL, "%s - %s\n", Sig->hash, hash); 

     if (!strcmp(Sig->hash, hash)) return TRUE; 

     pSig = pSig->Next; 
    } 

    return FALSE; 
} 

另外请注意,这是更常见的SINGLE_LINKED_LIST是结构的第一个元素,并调用它next是误导。像这样的东西可能会更好:

typedef struct { 
    SINGLE_LIST_ENTRY list_node; 
    char hash[33]; // last byte for null terminator 
} SIGNATURE, *PSIGNATURE; 
+0

感谢您的努力,顺便说一句,我可以把32长度的权利?也是AddToSignatureList的权利? – L3n

+1

您正在使用'strcmp',因此'hash'数组必须允许空终止符。如果您使用'memcmp',而不是使用'memcmp',但您也必须相应地更新调试语句。我在'AddToSignatureList'中看不到任何错误,假设'CopyCharArrays'没有问题。 –

+0

添加到signaturelist btw我用while(0)while(0)无用,因为我得到一个编译器错误,并在谷歌搜索后,我断定我需要。 – L3n