2015-01-17 20 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

相关问题