Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(316)

Side by Side Diff: chrome_elf/blacklist/blacklist.cc

Issue 183833004: Make chrome_elf use thunks instead of function pointers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments, add scoped ptr Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome_elf/chrome_elf.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "base/basictypes.h" 10 #include "base/basictypes.h"
11 #include "chrome_elf/blacklist/blacklist_interceptions.h" 11 #include "chrome_elf/blacklist/blacklist_interceptions.h"
12 #include "chrome_elf/chrome_elf_constants.h" 12 #include "chrome_elf/chrome_elf_constants.h"
13 #include "chrome_elf/chrome_elf_util.h" 13 #include "chrome_elf/chrome_elf_util.h"
14 #include "chrome_elf/thunk_getter.h"
14 #include "sandbox/win/src/interception_internal.h" 15 #include "sandbox/win/src/interception_internal.h"
15 #include "sandbox/win/src/internal_types.h" 16 #include "sandbox/win/src/internal_types.h"
16 #include "sandbox/win/src/sandbox_utils.h"
17 #include "sandbox/win/src/service_resolver.h" 17 #include "sandbox/win/src/service_resolver.h"
18 18
19 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx 19 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
20 extern "C" IMAGE_DOS_HEADER __ImageBase; 20 extern "C" IMAGE_DOS_HEADER __ImageBase;
21 21
22 namespace blacklist{ 22 namespace blacklist{
23 23
24 const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = { 24 const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = {
25 L"datamngr.dll", // Unknown (suspected adware). 25 L"datamngr.dll", // Unknown (suspected adware).
26 L"hk.dll", // Unknown (keystroke logger). 26 L"hk.dll", // Unknown (keystroke logger).
27 L"libsvn_tsvn32.dll", // TortoiseSVN. 27 L"libsvn_tsvn32.dll", // TortoiseSVN.
28 L"lmrn.dll", // Unknown. 28 L"lmrn.dll", // Unknown.
29 // Keep this null pointer here to mark the end of the list. 29 // Keep this null pointer here to mark the end of the list.
30 NULL, 30 NULL,
31 }; 31 };
32 32
33 bool g_blocked_dlls[kTroublesomeDllsMaxCount] = {}; 33 bool g_blocked_dlls[kTroublesomeDllsMaxCount] = {};
34 int g_num_blocked_dlls = 0; 34 int g_num_blocked_dlls = 0;
35 35
36 } // namespace blacklist 36 } // namespace blacklist
37 37
38 // Allocate storage for thunks in a page of this module to save on doing 38 // Allocate storage for thunks in a page of this module to save on doing
39 // an extra allocation at run time. 39 // an extra allocation at run time.
40 #pragma section(".crthunk",read,execute) 40 #pragma section(".crthunk",read,execute)
41 __declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage; 41 __declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage;
42 42
43 namespace { 43 namespace {
44 44
45 enum Version {
46 VERSION_PRE_XP_SP2 = 0, // Not supported.
47 VERSION_XP_SP2,
48 VERSION_SERVER_2003, // Also includes XP Pro x64 and Server 2003 R2.
49 VERSION_VISTA, // Also includes Windows Server 2008.
50 VERSION_WIN7, // Also includes Windows Server 2008 R2.
51 VERSION_WIN8, // Also includes Windows Server 2012.
52 VERSION_WIN8_1,
53 VERSION_WIN_LAST, // Indicates error condition.
54 };
55
56 // Whether a process is running under WOW64 (the wrapper that allows 32-bit
57 // processes to run on 64-bit versions of Windows). This will return
58 // WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit
59 // Chrome on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g.
60 // the process does not have sufficient access rights to determine this.
61 enum WOW64Status {
62 WOW64_DISABLED,
63 WOW64_ENABLED,
64 WOW64_UNKNOWN,
65 };
66
67 // Record if the blacklist was successfully initialized so processes can easily 45 // Record if the blacklist was successfully initialized so processes can easily
68 // determine if the blacklist is enabled for them. 46 // determine if the blacklist is enabled for them.
69 bool g_blacklist_initialized = false; 47 bool g_blacklist_initialized = false;
70 48
71 WOW64Status GetWOW64StatusForCurrentProcess() {
72 typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL);
73 IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
74 GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
75 if (!is_wow64_process)
76 return WOW64_DISABLED;
77 BOOL is_wow64 = FALSE;
78 if (!(*is_wow64_process)(GetCurrentProcess(), &is_wow64))
79 return WOW64_UNKNOWN;
80 return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
81 }
82
83 class OSInfo {
84 public:
85 struct VersionNumber {
86 int major;
87 int minor;
88 int build;
89 };
90
91 struct ServicePack {
92 int major;
93 int minor;
94 };
95
96 OSInfo() {
97 OSVERSIONINFOEX version_info = { sizeof(version_info) };
98 GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
99 version_number_.major = version_info.dwMajorVersion;
100 version_number_.minor = version_info.dwMinorVersion;
101 version_number_.build = version_info.dwBuildNumber;
102 if ((version_number_.major == 5) && (version_number_.minor > 0)) {
103 // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003.
104 version_ = (version_number_.minor == 1) ? VERSION_XP_SP2 :
105 VERSION_SERVER_2003;
106 if (version_ == VERSION_XP_SP2 && version_info.wServicePackMajor < 2)
107 version_ = VERSION_PRE_XP_SP2;
108 } else if (version_number_.major == 6) {
109 switch (version_number_.minor) {
110 case 0:
111 // Treat Windows Server 2008 the same as Windows Vista.
112 version_ = VERSION_VISTA;
113 break;
114 case 1:
115 // Treat Windows Server 2008 R2 the same as Windows 7.
116 version_ = VERSION_WIN7;
117 break;
118 case 2:
119 // Treat Windows Server 2012 the same as Windows 8.
120 version_ = VERSION_WIN8;
121 break;
122 default:
123 version_ = VERSION_WIN8_1;
124 break;
125 }
126 } else if (version_number_.major > 6) {
127 version_ = VERSION_WIN_LAST;
128 } else {
129 version_ = VERSION_PRE_XP_SP2;
130 }
131
132 service_pack_.major = version_info.wServicePackMajor;
133 service_pack_.minor = version_info.wServicePackMinor;
134 }
135
136 Version version() const { return version_; }
137 VersionNumber version_number() const { return version_number_; }
138 ServicePack service_pack() const { return service_pack_; }
139
140 private:
141 Version version_;
142 VersionNumber version_number_;
143 ServicePack service_pack_;
144
145 DISALLOW_COPY_AND_ASSIGN(OSInfo);
146 };
147
148 // Record that the thunk setup completed succesfully and close the registry 49 // Record that the thunk setup completed succesfully and close the registry
149 // key handle since it is no longer needed. 50 // key handle since it is no longer needed.
150 void RecordSuccessfulThunkSetup(HKEY* key) { 51 void RecordSuccessfulThunkSetup(HKEY* key) {
151 if (key != NULL) { 52 if (key != NULL) {
152 DWORD blacklist_state = blacklist::BLACKLIST_SETUP_RUNNING; 53 DWORD blacklist_state = blacklist::BLACKLIST_SETUP_RUNNING;
153 ::RegSetValueEx(*key, 54 ::RegSetValueEx(*key,
154 blacklist::kBeaconState, 55 blacklist::kBeaconState,
155 0, 56 0,
156 REG_DWORD, 57 REG_DWORD,
157 reinterpret_cast<LPBYTE>(&blacklist_state), 58 reinterpret_cast<LPBYTE>(&blacklist_state),
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 return false; 237 return false;
337 238
338 // Check to see if this is a non-browser process, abort if so. 239 // Check to see if this is a non-browser process, abort if so.
339 if (IsNonBrowserProcess()) 240 if (IsNonBrowserProcess())
340 return false; 241 return false;
341 242
342 // Check to see if a beacon is present, abort if so. 243 // Check to see if a beacon is present, abort if so.
343 if (!force && !LeaveSetupBeacon()) 244 if (!force && !LeaveSetupBeacon())
344 return false; 245 return false;
345 246
346 // Don't try blacklisting on unsupported OS versions.
347 OSInfo os_info;
348 if (os_info.version() <= VERSION_PRE_XP_SP2)
349 return false;
350
351 // Pseudo-handle, no need to close.
352 HANDLE current_process = ::GetCurrentProcess();
353
354 // Tells the resolver to patch already patched functions. 247 // Tells the resolver to patch already patched functions.
355 const bool kRelaxed = true; 248 const bool kRelaxed = true;
356 249
250 // Create a thunk via the appropriate ServiceResolver instance.
251 sandbox::ServiceResolverThunk* thunk = GetThunk(kRelaxed);
252
253 // Don't try blacklisting on unsupported OS versions.
254 if (!thunk)
255 return false;
256
357 // Record that we are starting the thunk setup code. 257 // Record that we are starting the thunk setup code.
358 HKEY key = NULL; 258 HKEY key = NULL;
359 DWORD disposition = 0; 259 DWORD disposition = 0;
360 LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER, 260 LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER,
361 kRegistryBeaconPath, 261 kRegistryBeaconPath,
362 0, 262 0,
363 NULL, 263 NULL,
364 REG_OPTION_NON_VOLATILE, 264 REG_OPTION_NON_VOLATILE,
365 KEY_QUERY_VALUE | KEY_SET_VALUE, 265 KEY_QUERY_VALUE | KEY_SET_VALUE,
366 NULL, 266 NULL,
367 &key, 267 &key,
368 &disposition); 268 &disposition);
369 if (result == ERROR_SUCCESS) { 269 if (result == ERROR_SUCCESS) {
370 DWORD blacklist_state = BLACKLIST_THUNK_SETUP; 270 DWORD blacklist_state = BLACKLIST_THUNK_SETUP;
371 ::RegSetValueEx(key, 271 ::RegSetValueEx(key,
372 kBeaconState, 272 kBeaconState,
373 0, 273 0,
374 REG_DWORD, 274 REG_DWORD,
375 reinterpret_cast<LPBYTE>(&blacklist_state), 275 reinterpret_cast<LPBYTE>(&blacklist_state),
376 sizeof(blacklist_state)); 276 sizeof(blacklist_state));
377 } else { 277 } else {
378 key = NULL; 278 key = NULL;
379 } 279 }
380 280
381 // Create a thunk via the appropriate ServiceResolver instance.
382 sandbox::ServiceResolverThunk* thunk = NULL;
383 #if defined(_WIN64)
384 // Because Windows 8 and 8.1 have different stubs in 64-bit,
385 // ServiceResolverThunk can handle all the formats in 64-bit (instead only
386 // handling 1 like it does in 32-bit versions).
387 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed);
388 #else
389 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) {
390 if (os_info.version() >= VERSION_WIN8)
391 thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed);
392 else
393 thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed);
394 } else if (os_info.version() >= VERSION_WIN8) {
395 thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed);
396 } else {
397 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed);
398 }
399 #endif
400
401 // Record that we have initialized the blacklist. 281 // Record that we have initialized the blacklist.
402 g_blacklist_initialized = true; 282 g_blacklist_initialized = true;
403 283
404 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); 284 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage);
405 285
406 // Mark the thunk storage as readable and writeable, since we 286 // Mark the thunk storage as readable and writeable, since we
407 // ready to write to it. 287 // ready to write to it.
408 DWORD old_protect = 0; 288 DWORD old_protect = 0;
409 if (!VirtualProtect(&g_thunk_storage, 289 if (!VirtualProtect(&g_thunk_storage,
410 sizeof(g_thunk_storage), 290 sizeof(g_thunk_storage),
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 sizeof(g_thunk_storage), 338 sizeof(g_thunk_storage),
459 PAGE_EXECUTE_READ, 339 PAGE_EXECUTE_READ,
460 &old_protect); 340 &old_protect);
461 341
462 RecordSuccessfulThunkSetup(&key); 342 RecordSuccessfulThunkSetup(&key);
463 343
464 return NT_SUCCESS(ret) && page_executable; 344 return NT_SUCCESS(ret) && page_executable;
465 } 345 }
466 346
467 } // namespace blacklist 347 } // namespace blacklist
OLDNEW
« no previous file with comments | « no previous file | chrome_elf/chrome_elf.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698