| 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 |