15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome_elf/blacklist/blacklist.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <assert.h> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string.h> 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <vector> 1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome_elf/blacklist/blacklist_interceptions.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome_elf/chrome_elf_constants.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome_elf/chrome_elf_util.h" 1623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome_elf/thunk_getter.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "sandbox/win/src/interception_internal.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "sandbox/win/src/internal_types.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "sandbox/win/src/service_resolver.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)extern "C" IMAGE_DOS_HEADER __ImageBase; 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace blacklist{ 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// The DLLs listed here are known (or under strong suspicion) of causing crashes 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// when they are loaded in the browser. DLLs should only be added to this list 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// if there is nothing else Chrome can do to prevent those crashes. 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// For more information about how this list is generated, and how to get off 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// of it, see: 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// https://sites.google.com/a/chromium.org/dev/Home/third-party-developers 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// NOTE: Please remember to update the DllHash enum in histograms.xml when 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// adding a new value to the blacklist. 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = { 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) L"activedetect32.dll", // Lenovo One Key Theater. 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // See crbug.com/379218. 37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) L"activedetect64.dll", // Lenovo One Key Theater. 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) L"bitguard.dll", // Unknown (suspected malware). 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) L"chrmxtn.dll", // Unknown (keystroke logger). 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch L"cplushook.dll", // Unknown (suspected malware). 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) L"datamngr.dll", // Unknown (suspected adware). 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) L"hk.dll", // Unknown (keystroke logger). 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) L"libapi2hook.dll", // V-Bates. 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) L"libinject.dll", // V-Bates. 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) L"libinject2.dll", // V-Bates. 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) L"libredir2.dll", // V-Bates. 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) L"libsvn_tsvn32.dll", // TortoiseSVN. 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) L"libwinhook.dll", // V-Bates. 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) L"lmrn.dll", // Unknown. 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch L"minisp.dll", // Unknown (suspected malware). 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch L"scdetour.dll", // Quick Heal Antivirus. 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // See crbug.com/382561. 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) L"systemk.dll", // Unknown (suspected adware). 545b892326406927b709cdaf6c384d4ababf456332Ben Murdoch L"wajam_goblin_64.dll", // Wajam Internet Technologies. 555b892326406927b709cdaf6c384d4ababf456332Ben Murdoch L"wajam_goblin.dll", // Wajam Internet Technologies. 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) L"windowsapihookdll32.dll", // Lenovo One Key Theater. 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // See crbug.com/379218. 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) L"windowsapihookdll64.dll", // Lenovo One Key Theater. 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Keep this null pointer here to mark the end of the list. 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool g_blocked_dlls[kTroublesomeDllsMaxCount] = {}; 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int g_num_blocked_dlls = 0; 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace blacklist 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Allocate storage for thunks in a page of this module to save on doing 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// an extra allocation at run time. 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#pragma section(".crthunk",read,execute) 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)__declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage; 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Record if the blacklist was successfully initialized so processes can easily 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// determine if the blacklist is enabled for them. 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool g_blacklist_initialized = false; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Helper to set DWORD registry values. 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)DWORD SetDWValue(HKEY* key, const wchar_t* property, DWORD value) { 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ::RegSetValueEx(*key, 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) property, 83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 0, 84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) REG_DWORD, 85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) reinterpret_cast<LPBYTE>(&value), 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sizeof(value)); 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool GenerateStateFromBeaconAndAttemptCount(HKEY* key, DWORD blacklist_state) { 90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) LONG result = 0; 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (blacklist_state == blacklist::BLACKLIST_ENABLED) { 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If the blacklist succeeded on the previous run reset the failure 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // counter. 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (SetDWValue(key, 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blacklist::kBeaconAttemptCount, 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<DWORD>(0)) == ERROR_SUCCESS); 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Some part of the blacklist setup failed last time. If this has occured 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // blacklist::kBeaconMaxAttempts times in a row we switch the state to 100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // failed and skip setting up the blacklist. 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DWORD attempt_count = 0; 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DWORD attempt_count_size = sizeof(attempt_count); 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result = ::RegQueryValueEx(*key, 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) blacklist::kBeaconAttemptCount, 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 0, 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) NULL, 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) reinterpret_cast<LPBYTE>(&attempt_count), 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &attempt_count_size); 109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (result == ERROR_FILE_NOT_FOUND) 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) attempt_count = 0; 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) else if (result != ERROR_SUCCESS) 113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ++attempt_count; 116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SetDWValue(key, blacklist::kBeaconAttemptCount, attempt_count); 117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (attempt_count >= blacklist::kBeaconMaxAttempts) { 119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) blacklist_state = blacklist::BLACKLIST_SETUP_FAILED; 120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SetDWValue(key, blacklist::kBeaconState, blacklist_state); 121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace blacklist { 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(_WIN64) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Allocate storage for the pointer to the old NtMapViewOfSectionFunction. 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#pragma section(".oldntmap",write,read) 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) __declspec(allocate(".oldntmap")) 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NtMapViewOfSectionFunction g_nt_map_view_of_section_func = NULL; 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool LeaveSetupBeacon() { 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HKEY key = NULL; 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DWORD disposition = 0; 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER, 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kRegistryBeaconPath, 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) REG_OPTION_NON_VOLATILE, 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) KEY_QUERY_VALUE | KEY_SET_VALUE, 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &key, 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &disposition); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result != ERROR_SUCCESS) 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Retrieve the current blacklist state. 154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DWORD blacklist_state = BLACKLIST_STATE_MAX; 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DWORD blacklist_state_size = sizeof(blacklist_state); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DWORD type = 0; 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = ::RegQueryValueEx(key, 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kBeaconState, 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &type, 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) reinterpret_cast<LPBYTE>(&blacklist_state), 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &blacklist_state_size); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (blacklist_state == BLACKLIST_DISABLED || result != ERROR_SUCCESS || 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) type != REG_DWORD) { 166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ::RegCloseKey(key); 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!GenerateStateFromBeaconAndAttemptCount(&key, blacklist_state)) { 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ::RegCloseKey(key); 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result = SetDWValue(&key, kBeaconState, BLACKLIST_SETUP_RUNNING); 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ::RegCloseKey(key); 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (result == ERROR_SUCCESS); 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ResetBeacon() { 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HKEY key = NULL; 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DWORD disposition = 0; 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER, 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kRegistryBeaconPath, 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 0, 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) REG_OPTION_NON_VOLATILE, 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) KEY_QUERY_VALUE | KEY_SET_VALUE, 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &key, 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &disposition); 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result != ERROR_SUCCESS) 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DWORD blacklist_state = BLACKLIST_STATE_MAX; 197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DWORD blacklist_state_size = sizeof(blacklist_state); 198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DWORD type = 0; 199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result = ::RegQueryValueEx(key, 200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) kBeaconState, 201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 0, 202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &type, 203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) reinterpret_cast<LPBYTE>(&blacklist_state), 204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &blacklist_state_size); 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (result != ERROR_SUCCESS || type != REG_DWORD) { 207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ::RegCloseKey(key); 208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 2116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Reaching this point with the setup running state means the setup did not 2126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // crash, so we reset to enabled. Any other state indicates that setup was 2136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // skipped; in that case we leave the state alone for later recording. 214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (blacklist_state == BLACKLIST_SETUP_RUNNING) 215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result = SetDWValue(&key, kBeaconState, BLACKLIST_ENABLED); 216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ::RegCloseKey(key); 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (result == ERROR_SUCCESS); 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BlacklistSize() { 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int size = -1; 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (blacklist::g_troublesome_dlls[++size] != NULL) {} 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return size; 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IsBlacklistInitialized() { 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return g_blacklist_initialized; 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int GetBlacklistIndex(const wchar_t* dll_name) { 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (int i = 0; i < kTroublesomeDllsMaxCount, g_troublesome_dlls[i]; ++i) { 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (_wcsicmp(dll_name, g_troublesome_dlls[i]) == 0) 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return i; 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return -1; 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool AddDllToBlacklist(const wchar_t* dll_name) { 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int blacklist_size = BlacklistSize(); 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We need to leave one space at the end for the null pointer. 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (blacklist_size + 1 >= kTroublesomeDllsMaxCount) 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < blacklist_size; ++i) { 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!_wcsicmp(g_troublesome_dlls[i], dll_name)) 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Copy string to blacklist. 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) wchar_t* str_buffer = new wchar_t[wcslen(dll_name) + 1]; 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) wcscpy(str_buffer, dll_name); 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_troublesome_dlls[blacklist_size] = str_buffer; 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_blocked_dlls[blacklist_size] = false; 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool RemoveDllFromBlacklist(const wchar_t* dll_name) { 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int blacklist_size = BlacklistSize(); 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < blacklist_size; ++i) { 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!_wcsicmp(g_troublesome_dlls[i], dll_name)) { 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Found the thing to remove. Delete it then replace it with the last 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // element. 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete[] g_troublesome_dlls[i]; 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_troublesome_dlls[i] = g_troublesome_dlls[blacklist_size - 1]; 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_troublesome_dlls[blacklist_size - 1] = NULL; 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Also update the stats recording if we have blocked this dll or not. 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (g_blocked_dlls[i]) 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) --g_num_blocked_dlls; 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_blocked_dlls[i] = g_blocked_dlls[blacklist_size - 1]; 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// TODO(csharp): Maybe store these values in the registry so we can 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// still report them if Chrome crashes early. 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SuccessfullyBlocked(const wchar_t** blocked_dlls, int* size) { 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (size == NULL) 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If the array isn't valid or big enough, just report the size it needs to 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // be and return. 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (blocked_dlls == NULL && *size < g_num_blocked_dlls) { 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *size = g_num_blocked_dlls; 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *size = g_num_blocked_dlls; 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int strings_to_fill = 0; 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (int i = 0; strings_to_fill < g_num_blocked_dlls && g_troublesome_dlls[i]; 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++i) { 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (g_blocked_dlls[i]) { 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blocked_dlls[strings_to_fill] = g_troublesome_dlls[i]; 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++strings_to_fill; 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BlockedDll(size_t blocked_index) { 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) assert(blocked_index < kTroublesomeDllsMaxCount); 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!g_blocked_dlls[blocked_index] && 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blocked_index < kTroublesomeDllsMaxCount) { 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++g_num_blocked_dlls; 310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_blocked_dlls[blocked_index] = true; 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Initialize(bool force) { 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Check to see that we found the functions we need in ntdll. 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!InitializeInterceptImports()) 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Check to see if this is a non-browser process, abort if so. 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsNonBrowserProcess()) 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Check to see if the blacklist beacon is still set to running (indicating a 324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // failure) or disabled, and abort if so. 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!force && !LeaveSetupBeacon()) 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 328effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // It is possible for other dlls to have already patched code by now and 329effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // attempting to patch their code might result in crashes. 330effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const bool kRelaxed = false; 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 33223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Create a thunk via the appropriate ServiceResolver instance. 33323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) sandbox::ServiceResolverThunk* thunk = GetThunk(kRelaxed); 33423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 33523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Don't try blacklisting on unsupported OS versions. 33623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!thunk) 33723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 33823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Mark the thunk storage as readable and writeable, since we 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // ready to write to it. 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DWORD old_protect = 0; 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!VirtualProtect(&g_thunk_storage, 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sizeof(g_thunk_storage), 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PAGE_EXECUTE_READWRITE, 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &old_protect)) { 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) thunk->AllowLocalPatches(); 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We declare this early so it can be used in the 64-bit block below and 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // still work on 32-bit build when referenced at the end of the function. 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BOOL page_executable = false; 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Replace the default NtMapViewOfSection with our patched version. 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(_WIN64) 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) reinterpret_cast<void*>(&__ImageBase), 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "NtMapViewOfSection", 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &blacklist::BlNtMapViewOfSection64, 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) thunk_storage, 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sizeof(sandbox::ThunkData), 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL); 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Keep a pointer to the original code, we don't have enough space to 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // add it directly to the call. 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_nt_map_view_of_section_func = reinterpret_cast<NtMapViewOfSectionFunction>( 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) thunk_storage); 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ensure that the pointer to the old function can't be changed. 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) page_executable = VirtualProtect(&g_nt_map_view_of_section_func, 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sizeof(g_nt_map_view_of_section_func), 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PAGE_EXECUTE_READ, 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &old_protect); 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) reinterpret_cast<void*>(&__ImageBase), 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "NtMapViewOfSection", 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &blacklist::BlNtMapViewOfSection, 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) thunk_storage, 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sizeof(sandbox::ThunkData), 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL); 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete thunk; 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Record if we have initialized the blacklist. 391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) g_blacklist_initialized = NT_SUCCESS(ret); 392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Mark the thunk storage as executable and prevent any future writes to it. 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) page_executable = page_executable && VirtualProtect(&g_thunk_storage, 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sizeof(g_thunk_storage), 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PAGE_EXECUTE_READ, 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &old_protect); 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AddDllsFromRegistryToBlacklist(); 40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NT_SUCCESS(ret) && page_executable; 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 404116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AddDllsFromRegistryToBlacklist() { 40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) HKEY key = NULL; 40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LONG result = ::RegOpenKeyEx(HKEY_CURRENT_USER, 40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) kRegistryFinchListPath, 40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 0, 40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) KEY_QUERY_VALUE | KEY_SET_VALUE, 41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &key); 41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (result != ERROR_SUCCESS) 413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // We add dlls from the registry to the blacklist. 41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DWORD value_len; 41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DWORD name_len = MAX_PATH; 41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::vector<wchar_t> name_buffer(name_len); 41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (int i = 0; result == ERROR_SUCCESS; ++i) { 42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) name_len = MAX_PATH; 42146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) value_len = 0; 42246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) result = ::RegEnumValue( 42346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) key, i, &name_buffer[0], &name_len, NULL, NULL, NULL, &value_len); 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (result != ERROR_SUCCESS) 425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 42746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) name_len = name_len + 1; 42846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) value_len = value_len + 1; 42946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::vector<wchar_t> value_buffer(value_len); 43046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) result = ::RegEnumValue(key, i, &name_buffer[0], &name_len, NULL, NULL, 43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) reinterpret_cast<BYTE*>(&value_buffer[0]), 43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) &value_len); 433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (result != ERROR_SUCCESS) 434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) value_buffer[value_len - 1] = L'\0'; 436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AddDllToBlacklist(&value_buffer[0]); 43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ::RegCloseKey(key); 440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 44146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace blacklist 444