OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome_elf/blacklist/blacklist.h" | 5 #include "chrome_elf/blacklist/blacklist.h" |
6 | 6 |
7 #include <assert.h> | 7 #include <assert.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "chrome/install_static/install_util.h" | 12 #include "chrome/install_static/install_util.h" |
13 #include "chrome_elf/blacklist/blacklist_interceptions.h" | 13 #include "chrome_elf/blacklist/blacklist_interceptions.h" |
14 #include "chrome_elf/chrome_elf_constants.h" | 14 #include "chrome_elf/chrome_elf_constants.h" |
15 #include "chrome_elf/thunk_getter.h" | 15 #include "chrome_elf/hook_util/thunk_getter.h" |
| 16 #include "chrome_elf/nt_registry/nt_registry.h" |
16 #include "sandbox/win/src/interception_internal.h" | 17 #include "sandbox/win/src/interception_internal.h" |
17 #include "sandbox/win/src/internal_types.h" | 18 #include "sandbox/win/src/internal_types.h" |
18 #include "sandbox/win/src/service_resolver.h" | 19 #include "sandbox/win/src/service_resolver.h" |
19 | 20 |
20 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx | 21 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx |
21 extern "C" IMAGE_DOS_HEADER __ImageBase; | 22 extern "C" IMAGE_DOS_HEADER __ImageBase; |
22 | 23 |
23 namespace blacklist{ | 24 namespace blacklist { |
24 | 25 |
25 // The DLLs listed here are known (or under strong suspicion) of causing crashes | 26 // The DLLs listed here are known (or under strong suspicion) of causing crashes |
26 // when they are loaded in the browser. DLLs should only be added to this list | 27 // when they are loaded in the browser. DLLs should only be added to this list |
27 // if there is nothing else Chrome can do to prevent those crashes. | 28 // if there is nothing else Chrome can do to prevent those crashes. |
28 // For more information about how this list is generated, and how to get off | 29 // For more information about how this list is generated, and how to get off |
29 // of it, see: | 30 // of it, see: |
30 // https://sites.google.com/a/chromium.org/dev/Home/third-party-developers | 31 // https://sites.google.com/a/chromium.org/dev/Home/third-party-developers |
31 // NOTE: Please remember to update the DllHash enum in histograms.xml when | 32 // NOTE: Please remember to update the DllHash enum in histograms.xml when |
32 // adding a new value to the blacklist. | 33 // adding a new value to the blacklist. |
33 const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = { | 34 const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = { |
34 L"949ba8b6a9.dll", // Coupon Time. | 35 L"949ba8b6a9.dll", // Coupon Time. |
35 L"activedetect32.dll", // Lenovo One Key Theater. | 36 L"activedetect32.dll", // Lenovo One Key Theater. |
36 // See crbug.com/379218. | 37 // See crbug.com/379218. |
37 L"activedetect64.dll", // Lenovo One Key Theater. | 38 L"activedetect64.dll", // Lenovo One Key Theater. |
38 L"bitguard.dll", // Unknown (suspected malware). | 39 L"bitguard.dll", // Unknown (suspected malware). |
39 L"bsvc.dll", // Unknown (suspected adware). | 40 L"bsvc.dll", // Unknown (suspected adware). |
40 L"chrmxtn.dll", // Unknown (keystroke logger). | 41 L"chrmxtn.dll", // Unknown (keystroke logger). |
41 L"cplushook.dll", // Unknown (suspected malware). | 42 L"cplushook.dll", // Unknown (suspected malware). |
42 L"crdli.dll", // Linkury Inc. | 43 L"crdli.dll", // Linkury Inc. |
43 L"crdli64.dll", // Linkury Inc. | 44 L"crdli64.dll", // Linkury Inc. |
44 L"datamngr.dll", // Unknown (suspected adware). | 45 L"datamngr.dll", // Unknown (suspected adware). |
45 L"dpinterface32.dll", // Unknown (suspected adware). | 46 L"dpinterface32.dll", // Unknown (suspected adware). |
46 L"explorerex.dll", // Unknown (suspected adware). | 47 L"explorerex.dll", // Unknown (suspected adware). |
47 L"hk.dll", // Unknown (keystroke logger). | 48 L"hk.dll", // Unknown (keystroke logger). |
48 L"libapi2hook.dll", // V-Bates. | 49 L"libapi2hook.dll", // V-Bates. |
49 L"libinject.dll", // V-Bates. | 50 L"libinject.dll", // V-Bates. |
50 L"libinject2.dll", // V-Bates. | 51 L"libinject2.dll", // V-Bates. |
51 L"libredir2.dll", // V-Bates. | 52 L"libredir2.dll", // V-Bates. |
52 L"libsvn_tsvn32.dll", // TortoiseSVN. | 53 L"libsvn_tsvn32.dll", // TortoiseSVN. |
53 L"libwinhook.dll", // V-Bates. | 54 L"libwinhook.dll", // V-Bates. |
54 L"lmrn.dll", // Unknown. | 55 L"lmrn.dll", // Unknown. |
55 L"minisp.dll", // Unknown (suspected malware). | 56 L"minisp.dll", // Unknown (suspected malware). |
56 L"minisp32.dll", // Unknown (suspected malware). | 57 L"minisp32.dll", // Unknown (suspected malware). |
57 L"offerswizarddll.dll", // Unknown (suspected adware). | 58 L"offerswizarddll.dll", // Unknown (suspected adware). |
58 L"safetynut.dll", // Unknown (suspected adware). | 59 L"safetynut.dll", // Unknown (suspected adware). |
59 L"smdmf.dll", // Unknown (suspected adware). | 60 L"smdmf.dll", // Unknown (suspected adware). |
60 L"spappsv32.dll", // Unknown (suspected adware). | 61 L"spappsv32.dll", // Unknown (suspected adware). |
61 L"systemk.dll", // Unknown (suspected adware). | 62 L"systemk.dll", // Unknown (suspected adware). |
62 L"vntsrv.dll", // Virtual New Tab by APN LLC. | 63 L"vntsrv.dll", // Virtual New Tab by APN LLC. |
63 L"wajam_goblin_64.dll", // Wajam Internet Technologies. | 64 L"wajam_goblin_64.dll", // Wajam Internet Technologies. |
64 L"wajam_goblin.dll", // Wajam Internet Technologies. | 65 L"wajam_goblin.dll", // Wajam Internet Technologies. |
65 L"windowsapihookdll32.dll", // Lenovo One Key Theater. | 66 L"windowsapihookdll32.dll", // Lenovo One Key Theater. |
66 // See crbug.com/379218. | 67 // See crbug.com/379218. |
67 L"windowsapihookdll64.dll", // Lenovo One Key Theater. | 68 L"windowsapihookdll64.dll", // Lenovo One Key Theater. |
68 L"virtualcamera.ax", // %PROGRAMFILES%\ASUS\VirtualCamera. | 69 L"virtualcamera.ax", // %PROGRAMFILES%\ASUS\VirtualCamera. |
69 // See crbug.com/422522. | 70 // See crbug.com/422522. |
70 L"ycwebcamerasource.ax", // CyberLink Youcam, crbug.com/424159 | 71 L"ycwebcamerasource.ax", // CyberLink Youcam, crbug.com/424159 |
71 // Keep this null pointer here to mark the end of the list. | 72 // Keep this null pointer here to mark the end of the list. |
72 NULL, | 73 NULL, |
73 }; | 74 }; |
74 | 75 |
75 bool g_blocked_dlls[kTroublesomeDllsMaxCount] = {}; | 76 bool g_blocked_dlls[kTroublesomeDllsMaxCount] = {}; |
76 int g_num_blocked_dlls = 0; | 77 int g_num_blocked_dlls = 0; |
77 | 78 |
78 } // namespace blacklist | 79 } // namespace blacklist |
79 | 80 |
80 // Allocate storage for thunks in a page of this module to save on doing | 81 // Allocate storage for thunks in a page of this module to save on doing |
81 // an extra allocation at run time. | 82 // an extra allocation at run time. |
82 #pragma section(".crthunk",read,execute) | 83 #pragma section(".crthunk", read, execute) |
83 __declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage; | 84 __declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage; |
84 | 85 |
85 namespace { | 86 namespace { |
86 | 87 |
87 // Record if the blacklist was successfully initialized so processes can easily | 88 // Record if the blacklist was successfully initialized so processes can easily |
88 // determine if the blacklist is enabled for them. | 89 // determine if the blacklist is enabled for them. |
89 bool g_blacklist_initialized = false; | 90 bool g_blacklist_initialized = false; |
90 | 91 |
91 // Helper to set DWORD registry values. | |
92 DWORD SetDWValue(HKEY* key, const wchar_t* property, DWORD value) { | |
93 return ::RegSetValueEx(*key, | |
94 property, | |
95 0, | |
96 REG_DWORD, | |
97 reinterpret_cast<LPBYTE>(&value), | |
98 sizeof(value)); | |
99 } | |
100 | |
101 bool GenerateStateFromBeaconAndAttemptCount(HKEY* key, DWORD blacklist_state) { | |
102 LONG result = 0; | |
103 if (blacklist_state == blacklist::BLACKLIST_ENABLED) { | |
104 // If the blacklist succeeded on the previous run reset the failure | |
105 // counter. | |
106 return (SetDWValue(key, | |
107 blacklist::kBeaconAttemptCount, | |
108 static_cast<DWORD>(0)) == ERROR_SUCCESS); | |
109 } else { | |
110 // Some part of the blacklist setup failed last time. If this has occured | |
111 // blacklist::kBeaconMaxAttempts times in a row we switch the state to | |
112 // failed and skip setting up the blacklist. | |
113 DWORD attempt_count = 0; | |
114 DWORD attempt_count_size = sizeof(attempt_count); | |
115 result = ::RegQueryValueEx(*key, | |
116 blacklist::kBeaconAttemptCount, | |
117 0, | |
118 NULL, | |
119 reinterpret_cast<LPBYTE>(&attempt_count), | |
120 &attempt_count_size); | |
121 | |
122 if (result == ERROR_FILE_NOT_FOUND) | |
123 attempt_count = 0; | |
124 else if (result != ERROR_SUCCESS) | |
125 return false; | |
126 | |
127 ++attempt_count; | |
128 SetDWValue(key, blacklist::kBeaconAttemptCount, attempt_count); | |
129 | |
130 if (attempt_count >= blacklist::kBeaconMaxAttempts) { | |
131 blacklist_state = blacklist::BLACKLIST_SETUP_FAILED; | |
132 SetDWValue(key, blacklist::kBeaconState, blacklist_state); | |
133 } | |
134 | |
135 return false; | |
136 } | |
137 } | |
138 | |
139 } // namespace | 92 } // namespace |
140 | 93 |
141 namespace blacklist { | 94 namespace blacklist { |
142 | 95 |
143 #if defined(_WIN64) | 96 #if defined(_WIN64) |
144 // Allocate storage for the pointer to the old NtMapViewOfSectionFunction. | 97 // Allocate storage for the pointer to the old NtMapViewOfSectionFunction. |
145 #pragma section(".oldntmap",write,read) | 98 #pragma section(".oldntmap", write, read) |
146 __declspec(allocate(".oldntmap")) | 99 __declspec(allocate(".oldntmap")) |
147 NtMapViewOfSectionFunction g_nt_map_view_of_section_func = NULL; | 100 NtMapViewOfSectionFunction g_nt_map_view_of_section_func = NULL; |
148 #endif | 101 #endif |
149 | 102 |
150 bool LeaveSetupBeacon() { | 103 bool LeaveSetupBeacon() { |
151 HKEY key = NULL; | 104 HANDLE key_handle = INVALID_HANDLE_VALUE; |
152 DWORD disposition = 0; | 105 |
153 LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER, | 106 if (!nt::CreateRegKey(nt::HKCU, kRegistryBeaconPath, |
154 kRegistryBeaconPath, | 107 KEY_QUERY_VALUE | KEY_SET_VALUE, &key_handle)) |
155 0, | |
156 NULL, | |
157 REG_OPTION_NON_VOLATILE, | |
158 KEY_QUERY_VALUE | KEY_SET_VALUE, | |
159 NULL, | |
160 &key, | |
161 &disposition); | |
162 if (result != ERROR_SUCCESS) | |
163 return false; | 108 return false; |
164 | 109 |
165 // Retrieve the current blacklist state. | |
166 DWORD blacklist_state = BLACKLIST_STATE_MAX; | 110 DWORD blacklist_state = BLACKLIST_STATE_MAX; |
167 DWORD blacklist_state_size = sizeof(blacklist_state); | 111 if (!nt::QueryRegValueDWORD(key_handle, kBeaconState, &blacklist_state) || |
168 DWORD type = 0; | 112 blacklist_state == BLACKLIST_DISABLED) { |
169 result = ::RegQueryValueEx(key, | 113 nt::CloseRegKey(key_handle); |
170 kBeaconState, | |
171 0, | |
172 &type, | |
173 reinterpret_cast<LPBYTE>(&blacklist_state), | |
174 &blacklist_state_size); | |
175 | |
176 if (result != ERROR_SUCCESS || blacklist_state == BLACKLIST_DISABLED || | |
177 type != REG_DWORD) { | |
178 ::RegCloseKey(key); | |
179 return false; | 114 return false; |
180 } | 115 } |
181 | 116 |
182 if (!GenerateStateFromBeaconAndAttemptCount(&key, blacklist_state)) { | 117 // Handle attempt count. |
183 ::RegCloseKey(key); | 118 // Only return true if BL is enabled and succeeded on previous run. |
184 return false; | 119 bool success = false; |
| 120 if (blacklist_state == BLACKLIST_ENABLED) { |
| 121 // If the blacklist succeeded on the previous run reset the failure |
| 122 // counter. Then update the beacon state. |
| 123 if (nt::SetRegValueDWORD(key_handle, kBeaconAttemptCount, |
| 124 static_cast<DWORD>(0))) { |
| 125 if (nt::SetRegValueDWORD(key_handle, kBeaconState, |
| 126 BLACKLIST_SETUP_RUNNING)) |
| 127 success = true; |
| 128 } |
| 129 } else { |
| 130 // Some part of the blacklist setup failed last time. If this has occured |
| 131 // blacklist::kBeaconMaxAttempts times in a row we switch the state to |
| 132 // failed and skip setting up the blacklist. |
| 133 DWORD attempt_count = 0; |
| 134 |
| 135 nt::QueryRegValueDWORD(key_handle, blacklist::kBeaconAttemptCount, |
| 136 &attempt_count); |
| 137 ++attempt_count; |
| 138 nt::SetRegValueDWORD(key_handle, blacklist::kBeaconAttemptCount, |
| 139 attempt_count); |
| 140 |
| 141 if (attempt_count >= blacklist::kBeaconMaxAttempts) { |
| 142 blacklist_state = blacklist::BLACKLIST_SETUP_FAILED; |
| 143 nt::SetRegValueDWORD(key_handle, blacklist::kBeaconState, |
| 144 blacklist_state); |
| 145 } |
185 } | 146 } |
186 | 147 |
187 result = SetDWValue(&key, kBeaconState, BLACKLIST_SETUP_RUNNING); | 148 nt::CloseRegKey(key_handle); |
188 ::RegCloseKey(key); | 149 return success; |
189 | |
190 return (result == ERROR_SUCCESS); | |
191 } | 150 } |
192 | 151 |
193 bool ResetBeacon() { | 152 bool ResetBeacon() { |
194 HKEY key = NULL; | 153 HANDLE key_handle = INVALID_HANDLE_VALUE; |
195 DWORD disposition = 0; | 154 |
196 LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER, | 155 if (!nt::CreateRegKey(nt::HKCU, kRegistryBeaconPath, |
197 kRegistryBeaconPath, | 156 KEY_QUERY_VALUE | KEY_SET_VALUE, &key_handle)) |
198 0, | |
199 NULL, | |
200 REG_OPTION_NON_VOLATILE, | |
201 KEY_QUERY_VALUE | KEY_SET_VALUE, | |
202 NULL, | |
203 &key, | |
204 &disposition); | |
205 if (result != ERROR_SUCCESS) | |
206 return false; | 157 return false; |
207 | 158 |
208 DWORD blacklist_state = BLACKLIST_STATE_MAX; | 159 DWORD blacklist_state = BLACKLIST_STATE_MAX; |
209 DWORD blacklist_state_size = sizeof(blacklist_state); | 160 if (!nt::QueryRegValueDWORD(key_handle, kBeaconState, &blacklist_state)) { |
210 DWORD type = 0; | 161 nt::CloseRegKey(key_handle); |
211 result = ::RegQueryValueEx(key, | |
212 kBeaconState, | |
213 0, | |
214 &type, | |
215 reinterpret_cast<LPBYTE>(&blacklist_state), | |
216 &blacklist_state_size); | |
217 | |
218 if (result != ERROR_SUCCESS || type != REG_DWORD) { | |
219 ::RegCloseKey(key); | |
220 return false; | 162 return false; |
221 } | 163 } |
222 | 164 |
223 // Reaching this point with the setup running state means the setup did not | 165 // Reaching this point with the setup running state means the setup did not |
224 // crash, so we reset to enabled. Any other state indicates that setup was | 166 // crash, so we reset to enabled. Any other state indicates that setup was |
225 // skipped; in that case we leave the state alone for later recording. | 167 // skipped; in that case we leave the state alone for later recording. |
226 if (blacklist_state == BLACKLIST_SETUP_RUNNING) | 168 if (blacklist_state == BLACKLIST_SETUP_RUNNING) { |
227 result = SetDWValue(&key, kBeaconState, BLACKLIST_ENABLED); | 169 if (!nt::SetRegValueDWORD(key_handle, kBeaconState, BLACKLIST_ENABLED)) { |
| 170 nt::CloseRegKey(key_handle); |
| 171 return false; |
| 172 } |
| 173 } |
228 | 174 |
229 ::RegCloseKey(key); | 175 nt::CloseRegKey(key_handle); |
230 return (result == ERROR_SUCCESS); | 176 return true; |
231 } | 177 } |
232 | 178 |
233 int BlacklistSize() { | 179 int BlacklistSize() { |
234 int size = -1; | 180 int size = -1; |
235 while (blacklist::g_troublesome_dlls[++size] != NULL) {} | 181 while (blacklist::g_troublesome_dlls[++size] != NULL) { |
| 182 } |
236 | 183 |
237 return size; | 184 return size; |
238 } | 185 } |
239 | 186 |
240 bool IsBlacklistInitialized() { | 187 bool IsBlacklistInitialized() { |
241 return g_blacklist_initialized; | 188 return g_blacklist_initialized; |
242 } | 189 } |
243 | 190 |
244 int GetBlacklistIndex(const wchar_t* dll_name) { | 191 int GetBlacklistIndex(const wchar_t* dll_name) { |
245 for (int i = 0; | 192 for (int i = 0; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 | 295 |
349 // Don't try blacklisting on unsupported OS versions. | 296 // Don't try blacklisting on unsupported OS versions. |
350 if (!thunk) | 297 if (!thunk) |
351 return false; | 298 return false; |
352 | 299 |
353 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); | 300 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); |
354 | 301 |
355 // Mark the thunk storage as readable and writeable, since we | 302 // Mark the thunk storage as readable and writeable, since we |
356 // ready to write to it. | 303 // ready to write to it. |
357 DWORD old_protect = 0; | 304 DWORD old_protect = 0; |
358 if (!VirtualProtect(&g_thunk_storage, | 305 if (!VirtualProtect(&g_thunk_storage, sizeof(g_thunk_storage), |
359 sizeof(g_thunk_storage), | 306 PAGE_EXECUTE_READWRITE, &old_protect)) { |
360 PAGE_EXECUTE_READWRITE, | |
361 &old_protect)) { | |
362 return false; | 307 return false; |
363 } | 308 } |
364 | 309 |
365 thunk->AllowLocalPatches(); | 310 thunk->AllowLocalPatches(); |
366 | 311 |
367 // We declare this early so it can be used in the 64-bit block below and | 312 // We declare this early so it can be used in the 64-bit block below and |
368 // still work on 32-bit build when referenced at the end of the function. | 313 // still work on 32-bit build when referenced at the end of the function. |
369 BOOL page_executable = false; | 314 BOOL page_executable = false; |
370 | 315 |
371 // Replace the default NtMapViewOfSection with our patched version. | 316 // Replace the default NtMapViewOfSection with our patched version. |
372 #if defined(_WIN64) | 317 #if defined(_WIN64) |
373 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), | 318 NTSTATUS ret = |
374 reinterpret_cast<void*>(&__ImageBase), | 319 thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), |
375 "NtMapViewOfSection", | 320 reinterpret_cast<void*>(&__ImageBase), "NtMapViewOfSection", |
376 NULL, | 321 NULL, &blacklist::BlNtMapViewOfSection64, thunk_storage, |
377 &blacklist::BlNtMapViewOfSection64, | 322 sizeof(sandbox::ThunkData), NULL); |
378 thunk_storage, | |
379 sizeof(sandbox::ThunkData), | |
380 NULL); | |
381 | 323 |
382 // Keep a pointer to the original code, we don't have enough space to | 324 // Keep a pointer to the original code, we don't have enough space to |
383 // add it directly to the call. | 325 // add it directly to the call. |
384 g_nt_map_view_of_section_func = reinterpret_cast<NtMapViewOfSectionFunction>( | 326 g_nt_map_view_of_section_func = |
385 thunk_storage); | 327 reinterpret_cast<NtMapViewOfSectionFunction>(thunk_storage); |
386 | 328 |
387 // Ensure that the pointer to the old function can't be changed. | 329 // Ensure that the pointer to the old function can't be changed. |
388 page_executable = VirtualProtect(&g_nt_map_view_of_section_func, | 330 page_executable = VirtualProtect(&g_nt_map_view_of_section_func, |
389 sizeof(g_nt_map_view_of_section_func), | 331 sizeof(g_nt_map_view_of_section_func), |
390 PAGE_EXECUTE_READ, | 332 PAGE_EXECUTE_READ, &old_protect); |
391 &old_protect); | |
392 #else | 333 #else |
393 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), | 334 NTSTATUS ret = |
394 reinterpret_cast<void*>(&__ImageBase), | 335 thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), |
395 "NtMapViewOfSection", | 336 reinterpret_cast<void*>(&__ImageBase), "NtMapViewOfSection", |
396 NULL, | 337 NULL, &blacklist::BlNtMapViewOfSection, thunk_storage, |
397 &blacklist::BlNtMapViewOfSection, | 338 sizeof(sandbox::ThunkData), NULL); |
398 thunk_storage, | |
399 sizeof(sandbox::ThunkData), | |
400 NULL); | |
401 #endif | 339 #endif |
402 delete thunk; | 340 delete thunk; |
403 | 341 |
404 // Record if we have initialized the blacklist. | 342 // Record if we have initialized the blacklist. |
405 g_blacklist_initialized = NT_SUCCESS(ret); | 343 g_blacklist_initialized = NT_SUCCESS(ret); |
406 | 344 |
407 // Mark the thunk storage as executable and prevent any future writes to it. | 345 // Mark the thunk storage as executable and prevent any future writes to it. |
408 page_executable = page_executable && VirtualProtect(&g_thunk_storage, | 346 page_executable = page_executable && |
409 sizeof(g_thunk_storage), | 347 VirtualProtect(&g_thunk_storage, sizeof(g_thunk_storage), |
410 PAGE_EXECUTE_READ, | 348 PAGE_EXECUTE_READ, &old_protect); |
411 &old_protect); | |
412 | 349 |
413 AddDllsFromRegistryToBlacklist(); | 350 AddDllsFromRegistryToBlacklist(); |
414 | 351 |
415 return NT_SUCCESS(ret) && page_executable; | 352 return NT_SUCCESS(ret) && page_executable; |
416 } | 353 } |
417 | 354 |
418 void AddDllsFromRegistryToBlacklist() { | 355 void AddDllsFromRegistryToBlacklist() { |
419 HKEY key = NULL; | 356 std::vector<std::wstring> dlls; |
420 LONG result = ::RegOpenKeyEx(HKEY_CURRENT_USER, | |
421 kRegistryFinchListPath, | |
422 0, | |
423 KEY_QUERY_VALUE | KEY_SET_VALUE, | |
424 &key); | |
425 | 357 |
426 if (result != ERROR_SUCCESS) | 358 if (!nt::QueryRegValueMULTISZ(nt::HKCU, kRegistryFinchListPath, |
| 359 kRegistryFinchListValueName, &dlls) || |
| 360 dlls.empty()) |
427 return; | 361 return; |
428 | 362 |
429 // We add dlls from the registry to the blacklist. | 363 // Add each DLL to the BL in memory |
430 DWORD value_len; | 364 for (auto name : dlls) { |
431 DWORD name_len = MAX_PATH; | 365 AddDllToBlacklist(name.c_str()); |
432 std::vector<wchar_t> name_buffer(name_len); | |
433 for (int i = 0; result == ERROR_SUCCESS; ++i) { | |
434 name_len = MAX_PATH; | |
435 value_len = 0; | |
436 result = ::RegEnumValue( | |
437 key, i, &name_buffer[0], &name_len, NULL, NULL, NULL, &value_len); | |
438 if (result != ERROR_SUCCESS) | |
439 break; | |
440 | |
441 name_len = name_len + 1; | |
442 value_len = value_len + 1; | |
443 std::vector<wchar_t> value_buffer(value_len); | |
444 result = ::RegEnumValue(key, i, &name_buffer[0], &name_len, NULL, NULL, | |
445 reinterpret_cast<BYTE*>(&value_buffer[0]), | |
446 &value_len); | |
447 if (result != ERROR_SUCCESS) | |
448 break; | |
449 value_buffer[value_len - 1] = L'\0'; | |
450 AddDllToBlacklist(&value_buffer[0]); | |
451 } | 366 } |
452 | 367 |
453 ::RegCloseKey(key); | |
454 return; | 368 return; |
455 } | 369 } |
456 | 370 |
457 } // namespace blacklist | 371 } // namespace blacklist |
OLD | NEW |