im learning about windows API. I try to create a program that list all the file from start path "C:\*" and get hash of those file. It work very well on debug mode, but when i build release, CryptGetHashParam give me 234 (More data is available). Here is a code and the output:
#include<Windows.h>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include "Header.h"
#pragma comment(lib,"Advapi32.lib")
using namespace std;
#define SAFE_FREE(block){free(block); block = NULL;}
int main() {
WCHAR wStartPath[] = L"C:";
WCHAR wFinalPath[MAX_PATH] = { NULL };
ListFile(wStartPath);
}
void ListFile(WCHAR* wPath) {
WIN32_FIND_DATAW wFindFileData = { 0 };
HANDLE hFile = 0;
WCHAR wFinalPath[MAX_PATH] = { 0 };
WCHAR wSource[MAX_PATH] = { 0 };
swprintf(wFinalPath, L"%s\\*", wPath);
hFile = FindFirstFileW(wFinalPath, &wFindFileData);
if (hFile == INVALID_HANDLE_VALUE) {
cout << "ListFile: FindFirstFileW failed " << GetLastError() << endl;
}
BOOL Check = TRUE;
while (Check) {
if (!wcsncmp(L".", wFindFileData.cFileName, 1) || !wcsncmp(L"..", wFindFileData.cFileName, 2)) {
Check = FindNextFileW(hFile, &wFindFileData);
continue;
}
else {
if (wFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
swprintf(wFinalPath, L"%s\\%s", wPath, wFindFileData.cFileName);
//wcout << wFinalPath << endl;
ListFile(wFinalPath);
}
else {
swprintf(wFinalPath, L"%s\\%s", wPath, wFindFileData.cFileName);
CheckFile(wFinalPath);
}
}
Check = FindNextFileW(hFile, &wFindFileData);
}
if (hFile != NULL && hFile != INVALID_HANDLE_VALUE) {
FindClose(hFile);
}
}
int CheckFile(WCHAR * wPath) {
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HANDLE hFile = CreateFileW(wPath,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE) {
wcout << "Check file: CreateFileW failed - " << GetLastError() << endl;
return 0;
}
DWORD dwFileSize = GetFileSize(hFile, NULL);
BYTE* bFileData = (BYTE*) malloc(dwFileSize 1);
if (bFileData == NULL) {
wcout << "Check file: malloc failed - " << endl;
CloseHandle(hFile);
return 0;
}
memset(bFileData, 0, dwFileSize);
DWORD dwBytesRead = 0;
if (!ReadFile(hFile, bFileData, dwFileSize, &dwBytesRead, NULL)) {
SAFE_FREE(bFileData);
CloseHandle(hFile);
wcout << "Check file: ReadFile failed - " << GetLastError() << endl;
return 0;
}
if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
wcout << "Check file: CryptAcquireContextW failed - " << GetLastError() << endl;
SAFE_FREE(bFileData);
CloseHandle(hFile);
return 0;
}
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
wcout << "Check file: CryptCreateHash failed - " << GetLastError() << endl;
SAFE_FREE(bFileData);
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CloseHandle(hFile);
return 0;
}
if (!CryptHashData(hHash, bFileData, dwFileSize, 0)) {
wcout << "Check file: CryptHashData failed - " << GetLastError() << endl;
SAFE_FREE(bFileData);
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CloseHandle(hFile);
return 0;
}
BYTE bMD5Hash[16] = { 0 };
DWORD dwHash,i ;
string sHexStr;
if (CryptGetHashParam(hHash, HP_HASHVAL, bMD5Hash, &dwHash, 0)) {
for (i = 0; i < dwHash; i ) {
char tmp[3] = { 0 };
sprintf(tmp, "x", bMD5Hash[i]);
sHexStr.append(tmp);
}
}
else {
wcout << GetLastError() << endl;
}
wcout << wPath << ": " << sHexStr.c_str() << endl;
}
Debug output:
C:\$GetCurrent\Logs\PartnerSetupCompleteResult.log: 13015015dd907d28996153df14881252
C:\$GetCurrent\SafeOS\GetCurrentOOBE.dll: 90c7b320b95a37aa058b0d42c35aa7a8
C:\$GetCurrent\SafeOS\GetCurrentRollback.ini: 5cf0b461170777de13f6460bcc527db8
C:\$GetCurrent\SafeOS\PartnerSetupComplete.cmd: dd592f713b9944941b6670157d5bf706
C:\$GetCurrent\SafeOS\preoobe.cmd: 2f9537b7f7cb5b559ed6ec3694832fe6
C:\$GetCurrent\SafeOS\SetupComplete.cmd: 0582b19fa3b500db28f976ed33efa487
Release ouptut:
C:\$GetCurrent\Logs\PartnerSetupCompleteResult.log:
234
C:\$GetCurrent\SafeOS\GetCurrentOOBE.dll:
234
C:\$GetCurrent\SafeOS\GetCurrentRollback.ini:
234
C:\$GetCurrent\SafeOS\PartnerSetupComplete.cmd:
234
C:\$GetCurrent\SafeOS\preoobe.cmd:
234
What just happend there ?
CodePudding user response:
You're not initializing pdwDataLen
, which is used as both input and output parameter:
[in, out] pdwDataLen
A pointer to a
DWORD
value specifying the size, in bytes, of thepbData
buffer. When the function returns, theDWORD
value contains the number of bytes stored in the buffer.
So initialize it:
DWORD dwHash = sizeof(bMD5hash), i;