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

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: No bad thunks in the lookup table 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') | chrome_elf/thunk_getter.h » ('J')
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 <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 "chrome_elf/thunk_getter.h"
11 #include "sandbox/win/src/interception_internal.h" 12 #include "sandbox/win/src/interception_internal.h"
12 #include "sandbox/win/src/internal_types.h" 13 #include "sandbox/win/src/internal_types.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 15 #include "version.h" // NOLINT
16 16
17 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx 17 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
18 extern "C" IMAGE_DOS_HEADER __ImageBase; 18 extern "C" IMAGE_DOS_HEADER __ImageBase;
19 19
20 namespace blacklist{ 20 namespace blacklist{
21 21
22 const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = { 22 const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = {
23 L"datamngr.dll", // Unknown (suspected adware). 23 L"datamngr.dll", // Unknown (suspected adware).
(...skipping 10 matching lines...) Expand all
34 34
35 } // namespace blacklist 35 } // namespace blacklist
36 36
37 // Allocate storage for thunks in a page of this module to save on doing 37 // Allocate storage for thunks in a page of this module to save on doing
38 // an extra allocation at run time. 38 // an extra allocation at run time.
39 #pragma section(".crthunk",read,execute) 39 #pragma section(".crthunk",read,execute)
40 __declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage; 40 __declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage;
41 41
42 namespace { 42 namespace {
43 43
44 enum Version {
45 VERSION_PRE_XP_SP2 = 0, // Not supported.
46 VERSION_XP_SP2,
47 VERSION_SERVER_2003, // Also includes XP Pro x64 and Server 2003 R2.
48 VERSION_VISTA, // Also includes Windows Server 2008.
49 VERSION_WIN7, // Also includes Windows Server 2008 R2.
50 VERSION_WIN8, // Also includes Windows Server 2012.
51 VERSION_WIN8_1,
52 VERSION_WIN_LAST, // Indicates error condition.
53 };
54
55 // Whether a process is running under WOW64 (the wrapper that allows 32-bit
56 // processes to run on 64-bit versions of Windows). This will return
57 // WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit
58 // Chrome on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g.
59 // the process does not have sufficient access rights to determine this.
60 enum WOW64Status {
61 WOW64_DISABLED,
62 WOW64_ENABLED,
63 WOW64_UNKNOWN,
64 };
65
66 // Record if the blacklist was successfully initialized so processes can easily 44 // Record if the blacklist was successfully initialized so processes can easily
67 // determine if the blacklist is enabled for them. 45 // determine if the blacklist is enabled for them.
68 bool g_blacklist_initialized = false; 46 bool g_blacklist_initialized = false;
69 47
70 WOW64Status GetWOW64StatusForCurrentProcess() {
71 typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL);
72 IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
73 GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
74 if (!is_wow64_process)
75 return WOW64_DISABLED;
76 BOOL is_wow64 = FALSE;
77 if (!(*is_wow64_process)(GetCurrentProcess(), &is_wow64))
78 return WOW64_UNKNOWN;
79 return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
80 }
81
82 class OSInfo {
83 public:
84 struct VersionNumber {
85 int major;
86 int minor;
87 int build;
88 };
89
90 struct ServicePack {
91 int major;
92 int minor;
93 };
94
95 OSInfo() {
96 OSVERSIONINFOEX version_info = { sizeof(version_info) };
97 GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
98 version_number_.major = version_info.dwMajorVersion;
99 version_number_.minor = version_info.dwMinorVersion;
100 version_number_.build = version_info.dwBuildNumber;
101 if ((version_number_.major == 5) && (version_number_.minor > 0)) {
102 // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003.
103 version_ = (version_number_.minor == 1) ? VERSION_XP_SP2 :
104 VERSION_SERVER_2003;
105 if (version_ == VERSION_XP_SP2 && version_info.wServicePackMajor < 2)
106 version_ = VERSION_PRE_XP_SP2;
107 } else if (version_number_.major == 6) {
108 switch (version_number_.minor) {
109 case 0:
110 // Treat Windows Server 2008 the same as Windows Vista.
111 version_ = VERSION_VISTA;
112 break;
113 case 1:
114 // Treat Windows Server 2008 R2 the same as Windows 7.
115 version_ = VERSION_WIN7;
116 break;
117 case 2:
118 // Treat Windows Server 2012 the same as Windows 8.
119 version_ = VERSION_WIN8;
120 break;
121 default:
122 version_ = VERSION_WIN8_1;
123 break;
124 }
125 } else if (version_number_.major > 6) {
126 version_ = VERSION_WIN_LAST;
127 } else {
128 version_ = VERSION_PRE_XP_SP2;
129 }
130
131 service_pack_.major = version_info.wServicePackMajor;
132 service_pack_.minor = version_info.wServicePackMinor;
133 }
134
135 Version version() const { return version_; }
136 VersionNumber version_number() const { return version_number_; }
137 ServicePack service_pack() const { return service_pack_; }
138
139 private:
140 Version version_;
141 VersionNumber version_number_;
142 ServicePack service_pack_;
143
144 DISALLOW_COPY_AND_ASSIGN(OSInfo);
145 };
146
147 bool IsNonBrowserProcess() { 48 bool IsNonBrowserProcess() {
148 typedef bool (*IsSandboxedProcessFunc)(); 49 typedef bool (*IsSandboxedProcessFunc)();
149 IsSandboxedProcessFunc is_sandboxed_process = 50 IsSandboxedProcessFunc is_sandboxed_process =
150 reinterpret_cast<IsSandboxedProcessFunc>( 51 reinterpret_cast<IsSandboxedProcessFunc>(
151 GetProcAddress(GetModuleHandle(NULL), "IsSandboxedProcess")); 52 GetProcAddress(GetModuleHandle(NULL), "IsSandboxedProcess"));
152 if (is_sandboxed_process && is_sandboxed_process()) 53 if (is_sandboxed_process && is_sandboxed_process())
153 return true; 54 return true;
154 55
155 return false; 56 return false;
156 } 57 }
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 return false; 223 return false;
323 224
324 // Check to see if this is a non-browser process, abort if so. 225 // Check to see if this is a non-browser process, abort if so.
325 if (IsNonBrowserProcess()) 226 if (IsNonBrowserProcess())
326 return false; 227 return false;
327 228
328 // Check to see if a beacon is present, abort if so. 229 // Check to see if a beacon is present, abort if so.
329 if (!force && !LeaveSetupBeacon()) 230 if (!force && !LeaveSetupBeacon())
330 return false; 231 return false;
331 232
332 // Don't try blacklisting on unsupported OS versions.
333 OSInfo os_info;
334 if (os_info.version() <= VERSION_PRE_XP_SP2)
335 return false;
336
337 // Pseudo-handle, no need to close.
338 HANDLE current_process = ::GetCurrentProcess();
339
340 // Tells the resolver to patch already patched functions. 233 // Tells the resolver to patch already patched functions.
341 const bool kRelaxed = true; 234 const bool kRelaxed = true;
342 235
236 // Create a thunk via the appropriate ServiceResolver instance.
237 sandbox::ServiceResolverThunk* thunk = GetThunk(kRelaxed);
238
239 // Don't try blacklisting on unsupported OS versions.
240 if (!thunk)
241 return false;
242
343 // Record that we are starting the thunk setup code. 243 // Record that we are starting the thunk setup code.
344 HKEY key = NULL; 244 HKEY key = NULL;
345 DWORD disposition = 0; 245 DWORD disposition = 0;
346 LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER, 246 LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER,
347 kRegistryBeaconPath, 247 kRegistryBeaconPath,
348 0, 248 0,
349 NULL, 249 NULL,
350 REG_OPTION_NON_VOLATILE, 250 REG_OPTION_NON_VOLATILE,
351 KEY_QUERY_VALUE | KEY_SET_VALUE, 251 KEY_QUERY_VALUE | KEY_SET_VALUE,
352 NULL, 252 NULL,
353 &key, 253 &key,
354 &disposition); 254 &disposition);
355 if (result == ERROR_SUCCESS) { 255 if (result == ERROR_SUCCESS) {
356 DWORD blacklist_state = BLACKLIST_THUNK_SETUP; 256 DWORD blacklist_state = BLACKLIST_THUNK_SETUP;
357 ::RegSetValueEx(key, 257 ::RegSetValueEx(key,
358 kBeaconState, 258 kBeaconState,
359 0, 259 0,
360 REG_DWORD, 260 REG_DWORD,
361 reinterpret_cast<LPBYTE>(&blacklist_state), 261 reinterpret_cast<LPBYTE>(&blacklist_state),
362 sizeof(blacklist_state)); 262 sizeof(blacklist_state));
363 } else { 263 } else {
364 key = NULL; 264 key = NULL;
365 } 265 }
366 266
367 // Create a thunk via the appropriate ServiceResolver instance.
368 sandbox::ServiceResolverThunk* thunk = NULL;
369 #if defined(_WIN64)
370 // Because Windows 8 and 8.1 have different stubs in 64-bit,
371 // ServiceResolverThunk can handle all the formats in 64-bit (instead only
372 // handling 1 like it does in 32-bit versions).
373 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed);
374 #else
375 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) {
376 if (os_info.version() >= VERSION_WIN8)
377 thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed);
378 else
379 thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed);
380 } else if (os_info.version() >= VERSION_WIN8) {
381 thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed);
382 } else {
383 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed);
384 }
385 #endif
386
387 // Record that we have initialized the blacklist. 267 // Record that we have initialized the blacklist.
388 g_blacklist_initialized = true; 268 g_blacklist_initialized = true;
389 269
390 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); 270 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage);
391 271
392 // Mark the thunk storage as readable and writeable, since we 272 // Mark the thunk storage as readable and writeable, since we
393 // ready to write to it. 273 // ready to write to it.
394 DWORD old_protect = 0; 274 DWORD old_protect = 0;
395 if (!VirtualProtect(&g_thunk_storage, 275 if (!VirtualProtect(&g_thunk_storage,
396 sizeof(g_thunk_storage), 276 sizeof(g_thunk_storage),
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 sizeof(g_thunk_storage), 324 sizeof(g_thunk_storage),
445 PAGE_EXECUTE_READ, 325 PAGE_EXECUTE_READ,
446 &old_protect); 326 &old_protect);
447 327
448 RecordSuccessfulThunkSetup(&key); 328 RecordSuccessfulThunkSetup(&key);
449 329
450 return NT_SUCCESS(ret) && page_executable; 330 return NT_SUCCESS(ret) && page_executable;
451 } 331 }
452 332
453 } // namespace blacklist 333 } // namespace blacklist
OLDNEW
« no previous file with comments | « no previous file | chrome_elf/chrome_elf.gyp » ('j') | chrome_elf/thunk_getter.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698