@@ -88,103 +88,134 @@ static std::wstring GetExecutablePath() {
8888 }
8989}
9090
91- // Helper function to calculate SHA256 hash of a file.
92- static std::vector<BYTE> CalculateFileSha256 (HANDLE hFile) {
91+ // Helper function to calculate the SHA256 hash of a file and return it as a hex
92+ // string (upper-case).
93+ static std::string CalculateFileSha256 (HANDLE hFile) {
9394 HCRYPTPROV hProv = 0 ;
9495 HCRYPTHASH hHash = 0 ;
95- std::vector<BYTE> result_hash_value;
9696
97+ // Ensure the file pointer is at the beginning of the file.
9798 if (SetFilePointer (hFile, 0 , NULL , FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
9899 DWORD dwError = GetLastError ();
99100 LogError (LOG_TAG " CalculateFileSha256.SetFilePointer failed. Error: %u" ,
100101 dwError);
101- return result_hash_value;
102+ return " " ; // Return empty string on failure
102103 }
103104
104105 // Acquire Crypto Provider.
105- // Using CRYPT_VERIFYCONTEXT for operations that don't require private key
106- // access.
106+ // Using CRYPT_VERIFYCONTEXT for operations that don't require private key access.
107107 if (!CryptAcquireContextW (&hProv, NULL , NULL , PROV_RSA_AES,
108108 CRYPT_VERIFYCONTEXT)) {
109109 DWORD dwError = GetLastError ();
110110 LogError (LOG_TAG
111111 " CalculateFileSha256.CryptAcquireContextW failed. Error: %u" ,
112112 dwError);
113- return result_hash_value ;
113+ return " " ;
114114 }
115115
116+ // Create a hash object.
116117 if (!CryptCreateHash (hProv, CALG_SHA_256, 0 , 0 , &hHash)) {
117118 DWORD dwError = GetLastError ();
118119 LogError (LOG_TAG " CalculateFileSha256.CryptCreateHash failed. Error: %u" ,
119120 dwError);
120121 CryptReleaseContext (hProv, 0 );
121- return result_hash_value ;
122+ return " " ;
122123 }
123124
125+ // Read the file in chunks and hash the data.
124126 BYTE rgbFile[1024 ];
125127 DWORD cbRead = 0 ;
126- BOOL bReadSuccessLoop = TRUE ;
127-
128128 while (true ) {
129- bReadSuccessLoop = ReadFile (hFile, rgbFile, sizeof (rgbFile), &cbRead, NULL );
130- if (!bReadSuccessLoop) {
129+ if (!ReadFile (hFile, rgbFile, sizeof (rgbFile), &cbRead, NULL )) {
131130 DWORD dwError = GetLastError ();
132131 LogError (LOG_TAG " CalculateFileSha256.ReadFile failed. Error: %u" ,
133132 dwError);
134133 CryptDestroyHash (hHash);
135134 CryptReleaseContext (hProv, 0 );
136- return result_hash_value ;
135+ return " " ;
137136 }
137+ // End of file
138138 if (cbRead == 0 ) {
139139 break ;
140140 }
141+ // Add the chunk to the hash object.
141142 if (!CryptHashData (hHash, rgbFile, cbRead, 0 )) {
142143 DWORD dwError = GetLastError ();
143144 LogError (LOG_TAG " CalculateFileSha256.CryptHashData failed. Error: %u" ,
144145 dwError);
145146 CryptDestroyHash (hHash);
146147 CryptReleaseContext (hProv, 0 );
147- return result_hash_value ;
148+ return " " ;
148149 }
149150 }
150151
152+ // --- Get the binary hash value ---
151153 DWORD cbHashValue = 0 ;
152154 DWORD dwCount = sizeof (DWORD);
153- if (!CryptGetHashParam (hHash, HP_HASHSIZE, (BYTE*)&cbHashValue, &dwCount,
154- 0 )) {
155+ if (!CryptGetHashParam (hHash, HP_HASHSIZE, (BYTE*)&cbHashValue, &dwCount, 0 )) {
155156 DWORD dwError = GetLastError ();
156157 LogError (LOG_TAG
157- " CalculateFileSha256.CryptGetHashParam "
158- " (HP_HASHSIZE) failed. Error: "
159- " %u" ,
158+ " CalculateFileSha256.CryptGetHashParam (HP_HASHSIZE) failed. "
159+ " Error: %u" ,
160160 dwError);
161161 CryptDestroyHash (hHash);
162162 CryptReleaseContext (hProv, 0 );
163- return result_hash_value ;
163+ return " " ;
164164 }
165165
166- result_hash_value. resize (cbHashValue);
167- if (!CryptGetHashParam (hHash, HP_HASHVAL, result_hash_value .data (),
166+ std::vector<BYTE> binary_hash_value (cbHashValue);
167+ if (!CryptGetHashParam (hHash, HP_HASHVAL, binary_hash_value .data (),
168168 &cbHashValue, 0 )) {
169169 DWORD dwError = GetLastError ();
170170 LogError (LOG_TAG
171171 " CalculateFileSha256.CryptGetHashParam (HP_HASHVAL) failed. "
172172 " Error: %u" ,
173173 dwError);
174- result_hash_value.clear ();
175174 CryptDestroyHash (hHash);
176175 CryptReleaseContext (hProv, 0 );
177- return result_hash_value;
176+ return " " ;
177+ }
178+
179+ // --- Convert the binary hash to a hex string ---
180+ DWORD hex_string_size = 0 ;
181+ if (!CryptBinaryToStringA (binary_hash_value.data (), binary_hash_value.size (),
182+ CRYPT_STRING_HEXRAW | CRYPT_STRING_NOCRLF,
183+ NULL , &hex_string_size)) {
184+ DWORD dwError = GetLastError ();
185+ LogError (LOG_TAG
186+ " CalculateFileSha256.CryptBinaryToStringA (size) failed. Error: %u" ,
187+ dwError);
188+ CryptDestroyHash (hHash);
189+ CryptReleaseContext (hProv, 0 );
190+ return " " ;
178191 }
179192
193+ std::string hex_hash_string (hex_string_size, ' \0 ' );
194+ if (!CryptBinaryToStringA (binary_hash_value.data (), binary_hash_value.size (),
195+ CRYPT_STRING_HEXRAW | CRYPT_STRING_NOCRLF,
196+ &hex_hash_string[0 ], &hex_string_size)) {
197+ DWORD dwError = GetLastError ();
198+ LogError (LOG_TAG
199+ " CalculateFileSha256.CryptBinaryToStringA (conversion) failed. Error: %u" ,
200+ dwError);
201+ CryptDestroyHash (hHash);
202+ CryptReleaseContext (hProv, 0 );
203+ return " " ;
204+ }
205+
206+ // Remove the null terminator from the string.
207+ hex_hash_string.resize (hex_string_size - 1 );
208+
209+ // --- Final Cleanup ---
180210 CryptDestroyHash (hHash);
181211 CryptReleaseContext (hProv, 0 );
182- return result_hash_value;
212+
213+ return hex_hash_string;
183214}
184215
185216HMODULE VerifyAndLoadAnalyticsLibrary (
186217 const wchar_t * library_filename,
187- const std::vector<std::vector< unsigned char > >& allowed_hashes) {
218+ const std::vector<std::string >& allowed_hashes) {
188219 if (library_filename == nullptr || library_filename[0 ] == L' \0 ' ) {
189220 LogError (LOG_TAG " Invalid arguments." );
190221 return nullptr ;
@@ -245,22 +276,14 @@ HMODULE VerifyAndLoadAnalyticsLibrary(
245276
246277 HMODULE hModule = nullptr ;
247278
248- std::vector<BYTE> calculated_hash = CalculateFileSha256 (hFile);
279+ std::string calculated_hash = CalculateFileSha256 (hFile);
249280
250- if (calculated_hash.empty () ) {
281+ if (calculated_hash.length () == 0 ) {
251282 LogError (LOG_TAG " Hash failed for Analytics DLL." );
252283 } else {
253284 bool hash_matched = false ;
254285 for (const auto & expected_hash : allowed_hashes) {
255- if (calculated_hash.size () != expected_hash.size ()) {
256- LogDebug (LOG_TAG
257- " Hash size mismatch for Analytics DLL. Expected: %zu, "
258- " Calculated: %zu. Trying next allowed hash." ,
259- expected_hash.size (), calculated_hash.size ());
260- continue ;
261- }
262- if (memcmp (calculated_hash.data (), expected_hash.data (),
263- expected_hash.size ()) == 0 ) {
286+ if (calculated_hash == expected_hash) {
264287 hash_matched = true ;
265288 break ;
266289 }
0 commit comments