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" |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 delete[] g_troublesome_dlls[i]; | 259 delete[] g_troublesome_dlls[i]; |
260 g_troublesome_dlls[i] = g_troublesome_dlls[g_troublesome_dlls_cur_index]; | 260 g_troublesome_dlls[i] = g_troublesome_dlls[g_troublesome_dlls_cur_index]; |
261 g_troublesome_dlls[g_troublesome_dlls_cur_index] = NULL; | 261 g_troublesome_dlls[g_troublesome_dlls_cur_index] = NULL; |
262 return true; | 262 return true; |
263 } | 263 } |
264 } | 264 } |
265 return false; | 265 return false; |
266 } | 266 } |
267 | 267 |
268 bool Initialize(bool force) { | 268 bool Initialize(bool force) { |
269 #if defined(_WIN64) | |
270 // TODO(robertshield): Implement 64-bit support by providing 64-bit | |
271 // interceptors. | |
272 return false; | |
273 #endif | |
274 | |
275 // Check to see that we found the functions we need in ntdll. | 269 // Check to see that we found the functions we need in ntdll. |
276 if (!InitializeInterceptImports()) | 270 if (!InitializeInterceptImports()) |
277 return false; | 271 return false; |
278 | 272 |
279 // Check to see if this is a non-browser process, abort if so. | 273 // Check to see if this is a non-browser process, abort if so. |
280 if (IsNonBrowserProcess()) | 274 if (IsNonBrowserProcess()) |
281 return false; | 275 return false; |
282 | 276 |
283 // Check to see if a beacon is present, abort if so. | 277 // Check to see if a beacon is present, abort if so. |
284 if (!force && !LeaveSetupBeacon()) | 278 if (!force && !LeaveSetupBeacon()) |
285 return false; | 279 return false; |
286 | 280 |
287 // Don't try blacklisting on unsupported OS versions. | 281 // Don't try blacklisting on unsupported OS versions. |
288 OSInfo os_info; | 282 OSInfo os_info; |
289 if (os_info.version() <= VERSION_PRE_XP_SP2) | 283 if (os_info.version() <= VERSION_PRE_XP_SP2) |
290 return false; | 284 return false; |
291 | 285 |
292 // Pseudo-handle, no need to close. | 286 // Pseudo-handle, no need to close. |
293 HANDLE current_process = ::GetCurrentProcess(); | 287 HANDLE current_process = ::GetCurrentProcess(); |
294 | 288 |
295 // Tells the resolver to patch already patched functions. | 289 // Tells the resolver to patch already patched functions. |
296 const bool kRelaxed = true; | 290 const bool kRelaxed = true; |
297 | 291 |
298 // Create a thunk via the appropriate ServiceResolver instance. | 292 // Create a thunk via the appropriate ServiceResolver instance. |
299 sandbox::ServiceResolverThunk* thunk; | 293 sandbox::ServiceResolverThunk* thunk = NULL; |
300 #if defined(_WIN64) | 294 #if defined(_WIN64) |
301 // TODO(robertshield): Use the appropriate thunk for 64-bit support | 295 // Because Windows 8 and 8.1 have different stubs in 64-bit, |
302 // when said support is implemented. | 296 // ServiceResolverThunk can handle all the formata in 64-bit (instead only |
rvargas (doing something else)
2014/01/27 19:15:32
nit: formata?
csharp
2014/02/03 16:23:09
Done.
| |
297 // handling 1 like it does in 32-bit versions). | |
298 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); | |
303 #else | 299 #else |
304 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { | 300 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { |
305 if (os_info.version() >= VERSION_WIN8) | 301 if (os_info.version() >= VERSION_WIN8) |
306 thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed); | 302 thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed); |
307 else | 303 else |
308 thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed); | 304 thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed); |
309 } else if (os_info.version() >= VERSION_WIN8) { | 305 } else if (os_info.version() >= VERSION_WIN8) { |
310 thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed); | 306 thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed); |
311 } else { | 307 } else { |
312 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); | 308 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); |
313 } | 309 } |
314 #endif | 310 #endif |
315 | 311 |
316 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); | 312 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); |
317 | 313 |
318 // Mark the thunk storage as readable and writeable, since we | 314 // Mark the thunk storage as readable and writeable, since we |
319 // ready to write to it. | 315 // ready to write to it. |
320 DWORD old_protect = 0; | 316 DWORD old_protect = 0; |
321 if (!VirtualProtect(&g_thunk_storage, | 317 if (!VirtualProtect(&g_thunk_storage, |
322 sizeof(g_thunk_storage), | 318 sizeof(g_thunk_storage), |
323 PAGE_EXECUTE_READWRITE, | 319 PAGE_EXECUTE_READWRITE, |
324 &old_protect)) | 320 &old_protect)) |
325 return false; | 321 return false; |
326 | 322 |
327 thunk->AllowLocalPatches(); | 323 thunk->AllowLocalPatches(); |
328 | 324 |
329 // Get ntdll base, target name, interceptor address, | 325 // We declare this early so it can be used in the 64-bit block below and |
326 // still work on 32-bit build when referenced at the end of the function. | |
327 BOOL page_executable; | |
328 | |
329 // Replace the default NtMapViewOfSection with our patched version. | |
330 #if defined(_WIN64) | |
331 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), | |
332 reinterpret_cast<void*>(&__ImageBase), | |
333 "NtMapViewOfSection", | |
334 NULL, | |
335 &blacklist::BlNtMapViewOfSection64, | |
336 thunk_storage, | |
337 sizeof(sandbox::ThunkData), | |
338 NULL); | |
339 | |
340 // Keep a pointer to the original code, we don't have enough space to | |
341 // add it directly to the call. | |
342 g_nt_map_view_of_section_func = reinterpret_cast<NtMapViewOfSectionFunction>( | |
343 thunk_storage); | |
344 | |
345 // Ensure that the pointer to the old function can't be changed. | |
346 page_executable = VirtualProtect(&g_nt_map_view_of_section_func, | |
rvargas (doing something else)
2014/01/27 19:15:32
the return value is never checked.
csharp
2014/02/03 16:23:09
Fixed the code further down to do an AND with this
| |
347 sizeof(g_nt_map_view_of_section_func), | |
348 PAGE_EXECUTE_READ, | |
349 &old_protect); | |
350 #else | |
330 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), | 351 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), |
331 reinterpret_cast<void*>(&__ImageBase), | 352 reinterpret_cast<void*>(&__ImageBase), |
332 "NtMapViewOfSection", | 353 "NtMapViewOfSection", |
333 NULL, | 354 NULL, |
334 &blacklist::BlNtMapViewOfSection, | 355 &blacklist::BlNtMapViewOfSection, |
335 thunk_storage, | 356 thunk_storage, |
336 sizeof(sandbox::ThunkData), | 357 sizeof(sandbox::ThunkData), |
337 NULL); | 358 NULL); |
338 | 359 #endif |
339 delete thunk; | 360 delete thunk; |
340 | 361 |
341 // Mark the thunk storage as executable and prevent any future writes to it. | 362 // Mark the thunk storage as executable and prevent any future writes to it. |
342 BOOL page_executable = VirtualProtect(&g_thunk_storage, | 363 page_executable = VirtualProtect(&g_thunk_storage, |
343 sizeof(g_thunk_storage), | 364 sizeof(g_thunk_storage), |
344 PAGE_EXECUTE_READ, | 365 PAGE_EXECUTE_READ, |
345 &old_protect); | 366 &old_protect); |
346 | 367 |
347 return NT_SUCCESS(ret) && page_executable; | 368 return NT_SUCCESS(ret) && page_executable; |
348 } | 369 } |
349 | 370 |
350 } // namespace blacklist | 371 } // namespace blacklist |
OLD | NEW |