2015-01-17 35 views
1

我在這裏是新的,我希望我做這個權利。md5爲EXE不給予預期的摘要

我做了一個C++應用程序,計算MD5哈希值以下摘要的文件 微軟執行這一環節http://msdn.microsoft.com/en-us/library/windows/desktop/aa382380%28v=vs.85%29.aspx 的情況是MD5哈希值與任何現成的工具,計算MD5摘要進行比較時,它消化爲任何類型的文件正確。除非手中的文件是像cmd.exe這樣的可執行文件。散列摘要是不同的並且取決於exe的位置。如果將cmd.exe移動到另一個位置,則摘要會再次變得不同。所以我繼續使用openssl庫實現相同的功能來面對同樣的問題。我注意到來自微軟實現和openssl的哈希摘要是一樣的。所以我認爲在傳遞它來計算摘要之前,在讀取文件時會有缺失。但我搜索很多找不到任何東西。 我試着從win API和「fopen」中使用「createfile」讀取文件以得到相同的結果...所以請幫助我,我錯過了什麼?

這裏是源代碼

#include "stdafx.h" 
#include <stdio.h> 
#include <windows.h> 
#include <Wincrypt.h> 

#define BUFSIZE 1024 
#define MD5LEN 16 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    DWORD dwStatus = 0; 
    BOOL bResult = FALSE; 
    HCRYPTPROV hProv = 0; 
    HCRYPTHASH hHash = 0; 
    HANDLE hFile = NULL; 
    BYTE rgbFile[BUFSIZE]; 
    DWORD cbRead = 0; 
    BYTE rgbHash[MD5LEN]; 
    DWORD cbHash = 0; 
    CHAR rgbDigits[] = "abcdef"; 
    LPCWSTR filename=L"C:\\Windows\\System32\\cmd.exe"; 
    // Logic to check usage goes here. 

    hFile = CreateFile(filename, 
     GENERIC_READ, 
     FILE_SHARE_READ, 
     NULL, 
     OPEN_EXISTING, 
     FILE_FLAG_SEQUENTIAL_SCAN, 
     NULL); 

    if (INVALID_HANDLE_VALUE == hFile) 
    { 
     dwStatus = GetLastError(); 
     printf("Error opening file %s\nError: %d\n", filename, 
      dwStatus); 
     return dwStatus; 
    } 

    // Get handle to the crypto provider 
    if (!CryptAcquireContext(&hProv, 
     NULL, 
     NULL, 
     PROV_RSA_FULL, 
     CRYPT_VERIFYCONTEXT)) 
    { 
     dwStatus = GetLastError(); 
     printf("CryptAcquireContext failed: %d\n", dwStatus); 
     CloseHandle(hFile); 
     return dwStatus; 
    } 

    if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) 
    { 
     dwStatus = GetLastError(); 
     printf("CryptAcquireContext failed: %d\n", dwStatus); 
     CloseHandle(hFile); 
     CryptReleaseContext(hProv, 0); 
     return dwStatus; 
    } 

    while (bResult = ReadFile(hFile, rgbFile, BUFSIZE, 
     &cbRead, NULL)) 
    { 
     if (0 == cbRead) 
     { 
      break; 
     } 

     if (!CryptHashData(hHash, rgbFile, cbRead, 0)) 
     { 
      dwStatus = GetLastError(); 
      printf("CryptHashData failed: %d\n", dwStatus); 
      CryptReleaseContext(hProv, 0); 
      CryptDestroyHash(hHash); 
      CloseHandle(hFile); 
      return dwStatus; 
     } 
    } 

    if (!bResult) 
    { 
     dwStatus = GetLastError(); 
     printf("ReadFile failed: %d\n", dwStatus); 
     CryptReleaseContext(hProv, 0); 
     CryptDestroyHash(hHash); 
     CloseHandle(hFile); 
     return dwStatus; 
    } 

    cbHash = MD5LEN; 
    if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) 
    { 
     printf("MD5 hash of file %s is: ", filename); 
     for (DWORD i = 0; i < cbHash; i++) 
     { 
      printf("%c%c", rgbDigits[rgbHash[i] >> 4], 
       rgbDigits[rgbHash[i] & 0xf]); 
     } 
     printf("\n"); 
    } 
    else 
    { 
     dwStatus = GetLastError(); 
     printf("CryptGetHashParam failed: %d\n", dwStatus); 
    } 

    CryptDestroyHash(hHash); 
    CryptReleaseContext(hProv, 0); 
    CloseHandle(hFile); 

    return dwStatus; 


    return 0; 
} 

此代碼計算,另一方面「數字火山哈希工具」和「MD5和SHA校驗工具V2.1」計算哈希值「哈希「59a1d4facd7b333f76c4142cd42d3aba」 fc0b4a626881d7c5980d757214db2d25「

+3

我們無法知道您錯過了什麼 - 我們不知道您擁有什麼。請閱讀http://stackoverflow.com/help/mcve – Mat

+1

如果md5代碼不存在問題,則文件的md5散列應該獨立於路徑。 – drescherjm

+0

我已經添加源代碼 – user4464366

回答

3

您的代碼是正確的!你已經遇到了Windows的特質。

您正在閱讀的文件位於C:\Windows\System32目錄中。

在64位Windows上,如果32位應用程序試圖訪問該目錄it gets redirectedC:\Windows\SysWow64

由於有cmd.exe文件都C:\Windows\System32C:\Windows\SysWow64,但他們是不同的構建等不同的哈希值,程序檢查C:\Windows\System32\cmd.exe哈希會產生不同的結果,這取決於它們是否是32位或64位。

您可以通過構建您的示例程序(32位和64位)並觀察它們給出不同的答案來看到這一點。

+1

非常感謝親愛的。 – user4464366

相關問題