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 <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "chrome_elf/blacklist/blacklist_interceptions.h" | 10 #include "chrome_elf/blacklist/blacklist_interceptions.h" |
11 #include "sandbox/win/src/interception_internal.h" | 11 #include "sandbox/win/src/interception_internal.h" |
12 #include "sandbox/win/src/internal_types.h" | 12 #include "sandbox/win/src/internal_types.h" |
13 #include "sandbox/win/src/sandbox_utils.h" | 13 #include "sandbox/win/src/sandbox_utils.h" |
14 #include "sandbox/win/src/service_resolver.h" | 14 #include "sandbox/win/src/service_resolver.h" |
15 #include "version.h" // NOLINT | |
16 | 15 |
17 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx | 16 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx |
18 extern "C" IMAGE_DOS_HEADER __ImageBase; | 17 extern "C" IMAGE_DOS_HEADER __ImageBase; |
19 | 18 |
20 namespace blacklist{ | 19 namespace blacklist{ |
21 | 20 |
22 const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = {}; | 21 const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = {}; |
23 int g_troublesome_dlls_cur_index = 0; | 22 int g_troublesome_dlls_cur_index = 0; |
24 | 23 |
25 const wchar_t kRegistryBeaconPath[] = L"SOFTWARE\\Google\\Chrome\\BLBeacon"; | 24 const wchar_t kRegistryBeaconPath[] = L"SOFTWARE\\Google\\Chrome\\BLBeacon"; |
26 const wchar_t kBeaconVersion[] = L"version"; | |
27 const wchar_t kBeaconState[] = L"state"; | |
28 | 25 |
29 } // namespace blacklist | 26 } // namespace blacklist |
30 | 27 |
31 // Allocate storage for thunks in a page of this module to save on doing | 28 // Allocate storage for thunks in a page of this module to save on doing |
32 // an extra allocation at run time. | 29 // an extra allocation at run time. |
33 #pragma section(".crthunk",read,execute) | 30 #pragma section(".crthunk",read,execute) |
34 __declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage; | 31 __declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage; |
35 | 32 |
36 namespace { | 33 namespace { |
37 | 34 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 | 133 |
137 bool IsNonBrowserProcess() { | 134 bool IsNonBrowserProcess() { |
138 wchar_t* command_line = GetCommandLine(); | 135 wchar_t* command_line = GetCommandLine(); |
139 return (command_line && wcsstr(command_line, L"--type")); | 136 return (command_line && wcsstr(command_line, L"--type")); |
140 } | 137 } |
141 | 138 |
142 } // namespace | 139 } // namespace |
143 | 140 |
144 namespace blacklist { | 141 namespace blacklist { |
145 | 142 |
146 bool LeaveSetupBeacon() { | 143 bool CreateBeacon() { |
147 DWORD blacklist_state = BLACKLIST_DISABLED; | 144 HKEY beacon_key = NULL; |
148 DWORD blacklist_state_size = sizeof(blacklist_state); | 145 DWORD disposition = 0; |
149 LONG result = ::RegGetValue(HKEY_CURRENT_USER, | 146 LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER, |
150 kRegistryBeaconPath, | 147 kRegistryBeaconPath, |
151 kBeaconState, | 148 0, |
152 RRF_RT_REG_DWORD, | 149 NULL, |
153 NULL, | 150 0, |
154 &blacklist_state, | 151 KEY_WRITE, |
155 &blacklist_state_size); | 152 NULL, |
| 153 &beacon_key, |
| 154 &disposition); |
| 155 bool success = (result == ERROR_SUCCESS && |
| 156 disposition != REG_OPENED_EXISTING_KEY); |
| 157 if (result == ERROR_SUCCESS) |
| 158 ::RegCloseKey(beacon_key); |
| 159 return success; |
| 160 } |
156 | 161 |
157 if (blacklist_state != BLACKLIST_ENABLED || | 162 bool ClearBeacon() { |
158 result != ERROR_SUCCESS) | 163 LONG result = ::RegDeleteKey(HKEY_CURRENT_USER, kRegistryBeaconPath); |
159 return false; | |
160 | |
161 // If the blacklist wasn't set as enabled for this version, don't | |
162 // use it. | |
163 wchar_t key_data[255] = {}; | |
164 DWORD key_data_size = sizeof(key_data); | |
165 result = ::RegGetValue(HKEY_CURRENT_USER, | |
166 blacklist::kRegistryBeaconPath, | |
167 blacklist::kBeaconVersion, | |
168 RRF_RT_REG_SZ, | |
169 NULL, | |
170 key_data, | |
171 &key_data_size); | |
172 if (wcscmp(key_data, TEXT(CHROME_VERSION_STRING)) != 0 || | |
173 result != ERROR_SUCCESS) | |
174 return false; | |
175 | |
176 // Mark the blacklist setup code as running so if it crashes the blacklist | |
177 // won't be enabled for the next run. | |
178 blacklist_state = BLACKLIST_SETUP_RUNNING; | |
179 result = ::RegSetKeyValue(HKEY_CURRENT_USER, | |
180 kRegistryBeaconPath, | |
181 kBeaconState, | |
182 REG_DWORD, | |
183 &blacklist_state, | |
184 sizeof(blacklist_state)); | |
185 | |
186 return (result == ERROR_SUCCESS); | 164 return (result == ERROR_SUCCESS); |
187 } | 165 } |
188 | 166 |
189 bool ResetBeacon() { | |
190 DWORD blacklist_state = BLACKLIST_ENABLED; | |
191 LONG result = ::RegSetKeyValue(HKEY_CURRENT_USER, | |
192 kRegistryBeaconPath, | |
193 kBeaconState, | |
194 REG_DWORD, | |
195 &blacklist_state, | |
196 sizeof(blacklist_state)); | |
197 | |
198 return (result == ERROR_SUCCESS); | |
199 } | |
200 | |
201 bool AddDllToBlacklist(const wchar_t* dll_name) { | 167 bool AddDllToBlacklist(const wchar_t* dll_name) { |
202 if (g_troublesome_dlls_cur_index >= kTroublesomeDllsMaxCount) | 168 if (g_troublesome_dlls_cur_index >= kTroublesomeDllsMaxCount) |
203 return false; | 169 return false; |
204 for (int i = 0; i < g_troublesome_dlls_cur_index; ++i) { | 170 for (int i = 0; i < g_troublesome_dlls_cur_index; ++i) { |
205 if (!wcscmp(g_troublesome_dlls[i], dll_name)) | 171 if (!wcscmp(g_troublesome_dlls[i], dll_name)) |
206 return true; | 172 return true; |
207 } | 173 } |
208 | 174 |
209 // Copy string to blacklist. | 175 // Copy string to blacklist. |
210 wchar_t* str_buffer = new wchar_t[wcslen(dll_name) + 1]; | 176 wchar_t* str_buffer = new wchar_t[wcslen(dll_name) + 1]; |
(...skipping 28 matching lines...) Expand all Loading... |
239 | 205 |
240 // Check to see that we found the functions we need in ntdll. | 206 // Check to see that we found the functions we need in ntdll. |
241 if (!InitializeInterceptImports()) | 207 if (!InitializeInterceptImports()) |
242 return false; | 208 return false; |
243 | 209 |
244 // Check to see if this is a non-browser process, abort if so. | 210 // Check to see if this is a non-browser process, abort if so. |
245 if (IsNonBrowserProcess()) | 211 if (IsNonBrowserProcess()) |
246 return false; | 212 return false; |
247 | 213 |
248 // Check to see if a beacon is present, abort if so. | 214 // Check to see if a beacon is present, abort if so. |
249 if (!force && !LeaveSetupBeacon()) | 215 if (!force && !CreateBeacon()) |
250 return false; | 216 return false; |
251 | 217 |
252 // Don't try blacklisting on unsupported OS versions. | 218 // Don't try blacklisting on unsupported OS versions. |
253 OSInfo os_info; | 219 OSInfo os_info; |
254 if (os_info.version() <= VERSION_PRE_XP_SP2) | 220 if (os_info.version() <= VERSION_PRE_XP_SP2) |
255 return false; | 221 return false; |
256 | 222 |
257 // Pseudo-handle, no need to close. | 223 // Pseudo-handle, no need to close. |
258 HANDLE current_process = ::GetCurrentProcess(); | 224 HANDLE current_process = ::GetCurrentProcess(); |
259 | 225 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 // Mark the thunk storage as executable and prevent any future writes to it. | 272 // Mark the thunk storage as executable and prevent any future writes to it. |
307 BOOL page_executable = VirtualProtect(&g_thunk_storage, | 273 BOOL page_executable = VirtualProtect(&g_thunk_storage, |
308 sizeof(g_thunk_storage), | 274 sizeof(g_thunk_storage), |
309 PAGE_EXECUTE_READ, | 275 PAGE_EXECUTE_READ, |
310 &old_protect); | 276 &old_protect); |
311 | 277 |
312 return NT_SUCCESS(ret) && page_executable; | 278 return NT_SUCCESS(ret) && page_executable; |
313 } | 279 } |
314 | 280 |
315 } // namespace blacklist | 281 } // namespace blacklist |
OLD | NEW |