@@ -88,103 +88,134 @@ static std::wstring GetExecutablePath() {
88
88
}
89
89
}
90
90
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) {
93
94
HCRYPTPROV hProv = 0 ;
94
95
HCRYPTHASH hHash = 0 ;
95
- std::vector<BYTE> result_hash_value;
96
96
97
+ // Ensure the file pointer is at the beginning of the file.
97
98
if (SetFilePointer (hFile, 0 , NULL , FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
98
99
DWORD dwError = GetLastError ();
99
100
LogError (LOG_TAG " CalculateFileSha256.SetFilePointer failed. Error: %u" ,
100
101
dwError);
101
- return result_hash_value;
102
+ return " " ; // Return empty string on failure
102
103
}
103
104
104
105
// 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.
107
107
if (!CryptAcquireContextW (&hProv, NULL , NULL , PROV_RSA_AES,
108
108
CRYPT_VERIFYCONTEXT)) {
109
109
DWORD dwError = GetLastError ();
110
110
LogError (LOG_TAG
111
111
" CalculateFileSha256.CryptAcquireContextW failed. Error: %u" ,
112
112
dwError);
113
- return result_hash_value ;
113
+ return " " ;
114
114
}
115
115
116
+ // Create a hash object.
116
117
if (!CryptCreateHash (hProv, CALG_SHA_256, 0 , 0 , &hHash)) {
117
118
DWORD dwError = GetLastError ();
118
119
LogError (LOG_TAG " CalculateFileSha256.CryptCreateHash failed. Error: %u" ,
119
120
dwError);
120
121
CryptReleaseContext (hProv, 0 );
121
- return result_hash_value ;
122
+ return " " ;
122
123
}
123
124
125
+ // Read the file in chunks and hash the data.
124
126
BYTE rgbFile[1024 ];
125
127
DWORD cbRead = 0 ;
126
- BOOL bReadSuccessLoop = TRUE ;
127
-
128
128
while (true ) {
129
- bReadSuccessLoop = ReadFile (hFile, rgbFile, sizeof (rgbFile), &cbRead, NULL );
130
- if (!bReadSuccessLoop) {
129
+ if (!ReadFile (hFile, rgbFile, sizeof (rgbFile), &cbRead, NULL )) {
131
130
DWORD dwError = GetLastError ();
132
131
LogError (LOG_TAG " CalculateFileSha256.ReadFile failed. Error: %u" ,
133
132
dwError);
134
133
CryptDestroyHash (hHash);
135
134
CryptReleaseContext (hProv, 0 );
136
- return result_hash_value ;
135
+ return " " ;
137
136
}
137
+ // End of file
138
138
if (cbRead == 0 ) {
139
139
break ;
140
140
}
141
+ // Add the chunk to the hash object.
141
142
if (!CryptHashData (hHash, rgbFile, cbRead, 0 )) {
142
143
DWORD dwError = GetLastError ();
143
144
LogError (LOG_TAG " CalculateFileSha256.CryptHashData failed. Error: %u" ,
144
145
dwError);
145
146
CryptDestroyHash (hHash);
146
147
CryptReleaseContext (hProv, 0 );
147
- return result_hash_value ;
148
+ return " " ;
148
149
}
149
150
}
150
151
152
+ // --- Get the binary hash value ---
151
153
DWORD cbHashValue = 0 ;
152
154
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 )) {
155
156
DWORD dwError = GetLastError ();
156
157
LogError (LOG_TAG
157
- " CalculateFileSha256.CryptGetHashParam "
158
- " (HP_HASHSIZE) failed. Error: "
159
- " %u" ,
158
+ " CalculateFileSha256.CryptGetHashParam (HP_HASHSIZE) failed. "
159
+ " Error: %u" ,
160
160
dwError);
161
161
CryptDestroyHash (hHash);
162
162
CryptReleaseContext (hProv, 0 );
163
- return result_hash_value ;
163
+ return " " ;
164
164
}
165
165
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 (),
168
168
&cbHashValue, 0 )) {
169
169
DWORD dwError = GetLastError ();
170
170
LogError (LOG_TAG
171
171
" CalculateFileSha256.CryptGetHashParam (HP_HASHVAL) failed. "
172
172
" Error: %u" ,
173
173
dwError);
174
- result_hash_value.clear ();
175
174
CryptDestroyHash (hHash);
176
175
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 " " ;
178
191
}
179
192
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 ---
180
210
CryptDestroyHash (hHash);
181
211
CryptReleaseContext (hProv, 0 );
182
- return result_hash_value;
212
+
213
+ return hex_hash_string;
183
214
}
184
215
185
216
HMODULE VerifyAndLoadAnalyticsLibrary (
186
217
const wchar_t * library_filename,
187
- const std::vector<std::vector< unsigned char > >& allowed_hashes) {
218
+ const std::vector<std::string >& allowed_hashes) {
188
219
if (library_filename == nullptr || library_filename[0 ] == L' \0 ' ) {
189
220
LogError (LOG_TAG " Invalid arguments." );
190
221
return nullptr ;
@@ -245,22 +276,14 @@ HMODULE VerifyAndLoadAnalyticsLibrary(
245
276
246
277
HMODULE hModule = nullptr ;
247
278
248
- std::vector<BYTE> calculated_hash = CalculateFileSha256 (hFile);
279
+ std::string calculated_hash = CalculateFileSha256 (hFile);
249
280
250
- if (calculated_hash.empty () ) {
281
+ if (calculated_hash.length () == 0 ) {
251
282
LogError (LOG_TAG " Hash failed for Analytics DLL." );
252
283
} else {
253
284
bool hash_matched = false ;
254
285
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) {
264
287
hash_matched = true ;
265
288
break ;
266
289
}
0 commit comments