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

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

Issue 118343004: Reland of http://crrev.com/241548. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years 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 | « chrome_elf/blacklist/blacklist.h ('k') | chrome_elf/blacklist/blacklist_interceptions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome_elf/blacklist/blacklist.h"
6
7 #include <string.h>
8
9 #include "base/basictypes.h"
10 #include "chrome_elf/blacklist/blacklist_interceptions.h"
11 #include "sandbox/win/src/interception_internal.h"
12 #include "sandbox/win/src/internal_types.h"
13 #include "sandbox/win/src/sandbox_utils.h"
14 #include "sandbox/win/src/service_resolver.h"
15
16 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
17 extern "C" IMAGE_DOS_HEADER __ImageBase;
18
19 namespace blacklist{
20
21 const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = {};
22 int g_troublesome_dlls_cur_index = 0;
23
24 const wchar_t kRegistryBeaconPath[] = L"SOFTWARE\\Google\\Chrome\\BLBeacon";
25
26 } // namespace blacklist
27
28 // Allocate storage for thunks in a RWX page of this module to save on doing
29 // an extra allocation at run time.
30 #if !defined(_WIN64)
31 // 64-bit images appear to not support writeable and executable pages.
32 // This would yield compile warning C4330.
33 // TODO(robertshield): Add 64 bit support.
34 #pragma section(".crthunk",read,write,execute)
35 __declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage;
36 #endif
37
38 namespace {
39
40 enum Version {
41 VERSION_PRE_XP_SP2 = 0, // Not supported.
42 VERSION_XP_SP2,
43 VERSION_SERVER_2003, // Also includes XP Pro x64 and Server 2003 R2.
44 VERSION_VISTA, // Also includes Windows Server 2008.
45 VERSION_WIN7, // Also includes Windows Server 2008 R2.
46 VERSION_WIN8, // Also includes Windows Server 2012.
47 VERSION_WIN8_1,
48 VERSION_WIN_LAST, // Indicates error condition.
49 };
50
51 // Whether a process is running under WOW64 (the wrapper that allows 32-bit
52 // processes to run on 64-bit versions of Windows). This will return
53 // WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit
54 // Chrome on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g.
55 // the process does not have sufficient access rights to determine this.
56 enum WOW64Status {
57 WOW64_DISABLED,
58 WOW64_ENABLED,
59 WOW64_UNKNOWN,
60 };
61
62 WOW64Status GetWOW64StatusForCurrentProcess() {
63 typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL);
64 IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
65 GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
66 if (!is_wow64_process)
67 return WOW64_DISABLED;
68 BOOL is_wow64 = FALSE;
69 if (!(*is_wow64_process)(GetCurrentProcess(), &is_wow64))
70 return WOW64_UNKNOWN;
71 return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
72 }
73
74 class OSInfo {
75 public:
76 struct VersionNumber {
77 int major;
78 int minor;
79 int build;
80 };
81
82 struct ServicePack {
83 int major;
84 int minor;
85 };
86
87 OSInfo() {
88 OSVERSIONINFOEX version_info = { sizeof(version_info) };
89 GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
90 version_number_.major = version_info.dwMajorVersion;
91 version_number_.minor = version_info.dwMinorVersion;
92 version_number_.build = version_info.dwBuildNumber;
93 if ((version_number_.major == 5) && (version_number_.minor > 0)) {
94 // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003.
95 version_ = (version_number_.minor == 1) ? VERSION_XP_SP2 :
96 VERSION_SERVER_2003;
97 if (version_ == VERSION_XP_SP2 && version_info.wServicePackMajor < 2)
98 version_ = VERSION_PRE_XP_SP2;
99 } else if (version_number_.major == 6) {
100 switch (version_number_.minor) {
101 case 0:
102 // Treat Windows Server 2008 the same as Windows Vista.
103 version_ = VERSION_VISTA;
104 break;
105 case 1:
106 // Treat Windows Server 2008 R2 the same as Windows 7.
107 version_ = VERSION_WIN7;
108 break;
109 case 2:
110 // Treat Windows Server 2012 the same as Windows 8.
111 version_ = VERSION_WIN8;
112 break;
113 default:
114 version_ = VERSION_WIN8_1;
115 break;
116 }
117 } else if (version_number_.major > 6) {
118 version_ = VERSION_WIN_LAST;
119 } else {
120 version_ = VERSION_PRE_XP_SP2;
121 }
122
123 service_pack_.major = version_info.wServicePackMajor;
124 service_pack_.minor = version_info.wServicePackMinor;
125 }
126
127 Version version() const { return version_; }
128 VersionNumber version_number() const { return version_number_; }
129 ServicePack service_pack() const { return service_pack_; }
130
131 private:
132 Version version_;
133 VersionNumber version_number_;
134 ServicePack service_pack_;
135
136 DISALLOW_COPY_AND_ASSIGN(OSInfo);
137 };
138
139 bool IsNonBrowserProcess() {
140 wchar_t* command_line = GetCommandLine();
141 return (command_line && wcsstr(command_line, L"--type"));
142 }
143
144 } // namespace
145
146 namespace blacklist {
147
148 bool CreateBeacon() {
149 HKEY beacon_key = NULL;
150 DWORD disposition = 0;
151 LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER,
152 kRegistryBeaconPath,
153 0,
154 NULL,
155 0,
156 KEY_WRITE,
157 NULL,
158 &beacon_key,
159 &disposition);
160 bool success = (result == ERROR_SUCCESS &&
161 disposition != REG_OPENED_EXISTING_KEY);
162 if (result == ERROR_SUCCESS)
163 ::RegCloseKey(beacon_key);
164 return success;
165 }
166
167 bool ClearBeacon() {
168 LONG result = ::RegDeleteKey(HKEY_CURRENT_USER, kRegistryBeaconPath);
169 return (result == ERROR_SUCCESS);
170 }
171
172 bool AddDllToBlacklist(const wchar_t* dll_name) {
173 if (g_troublesome_dlls_cur_index >= kTroublesomeDllsMaxCount)
174 return false;
175 for (int i = 0; i < g_troublesome_dlls_cur_index; ++i) {
176 if (!wcscmp(g_troublesome_dlls[i], dll_name))
177 return true;
178 }
179
180 // Copy string to blacklist.
181 wchar_t* str_buffer = new wchar_t[wcslen(dll_name) + 1];
182 wcscpy(str_buffer, dll_name);
183
184 g_troublesome_dlls[g_troublesome_dlls_cur_index] = str_buffer;
185 g_troublesome_dlls_cur_index++;
186 return true;
187 }
188
189 bool RemoveDllFromBlacklist(const wchar_t* dll_name) {
190 for (int i = 0; i < g_troublesome_dlls_cur_index; ++i) {
191 if (!wcscmp(g_troublesome_dlls[i], dll_name)) {
192 // Found the thing to remove. Delete it then replace it with the last
193 // element.
194 g_troublesome_dlls_cur_index--;
195 delete[] g_troublesome_dlls[i];
196 g_troublesome_dlls[i] = g_troublesome_dlls[g_troublesome_dlls_cur_index];
197 g_troublesome_dlls[g_troublesome_dlls_cur_index] = NULL;
198 return true;
199 }
200 }
201 return false;
202 }
203
204 bool Initialize(bool force) {
205 #if defined(_WIN64)
206 // TODO(robertshield): Implement 64-bit support by providing 64-bit
207 // interceptors.
208 return false;
209 #endif
210
211 // Check to see that we found the functions we need in ntdll.
212 if (!InitializeInterceptImports())
213 return false;
214
215 // Check to see if this is a non-browser process, abort if so.
216 if (IsNonBrowserProcess())
217 return false;
218
219 // Check to see if a beacon is present, abort if so.
220 if (!force && !CreateBeacon())
221 return false;
222
223 // Don't try blacklisting on unsupported OS versions.
224 OSInfo os_info;
225 if (os_info.version() <= VERSION_PRE_XP_SP2)
226 return false;
227
228 // Pseudo-handle, no need to close.
229 HANDLE current_process = ::GetCurrentProcess();
230
231 // Tells the resolver to patch already patched functions.
232 const bool kRelaxed = true;
233
234 // Create a thunk via the appropriate ServiceResolver instance.
235 sandbox::ServiceResolverThunk* thunk;
236 #if defined(_WIN64)
237 // TODO(robertshield): Use the appropriate thunk for 64-bit support
238 // when said support is implemented.
239 #else
240 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) {
241 if (os_info.version() >= VERSION_WIN8)
242 thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed);
243 else
244 thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed);
245 } else if (os_info.version() >= VERSION_WIN8) {
246 thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed);
247 } else {
248 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed);
249 }
250 #endif
251
252 #if defined(_WIN64)
253 BYTE* thunk_storage = new BYTE[sizeof(sandbox::ThunkData)];
254 #else
255 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage);
256 #endif
257
258 thunk->AllowLocalPatches();
259
260 // Get ntdll base, target name, interceptor address,
261 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName),
262 reinterpret_cast<void*>(&__ImageBase),
263 "NtMapViewOfSection",
264 NULL,
265 &blacklist::BlNtMapViewOfSection,
266 thunk_storage,
267 sizeof(sandbox::ThunkData),
268 NULL);
269
270 delete thunk;
271 return NT_SUCCESS(ret);
272 }
273
274 } // namespace blacklist
OLDNEW
« no previous file with comments | « chrome_elf/blacklist/blacklist.h ('k') | chrome_elf/blacklist/blacklist_interceptions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698