| 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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 delete[] g_troublesome_dlls[i]; | 190 delete[] g_troublesome_dlls[i]; |
| 191 g_troublesome_dlls[i] = g_troublesome_dlls[g_troublesome_dlls_cur_index]; | 191 g_troublesome_dlls[i] = g_troublesome_dlls[g_troublesome_dlls_cur_index]; |
| 192 g_troublesome_dlls[g_troublesome_dlls_cur_index] = NULL; | 192 g_troublesome_dlls[g_troublesome_dlls_cur_index] = NULL; |
| 193 return true; | 193 return true; |
| 194 } | 194 } |
| 195 } | 195 } |
| 196 return false; | 196 return false; |
| 197 } | 197 } |
| 198 | 198 |
| 199 bool Initialize(bool force) { | 199 bool Initialize(bool force) { |
| 200 #if defined(_WIN64) | |
| 201 // TODO(robertshield): Implement 64-bit support by providing 64-bit | |
| 202 // interceptors. | |
| 203 return false; | |
| 204 #endif | |
| 205 | |
| 206 // Check to see that we found the functions we need in ntdll. | 200 // Check to see that we found the functions we need in ntdll. |
| 207 if (!InitializeInterceptImports()) | 201 if (!InitializeInterceptImports()) |
| 208 return false; | 202 return false; |
| 209 | 203 |
| 210 // Check to see if this is a non-browser process, abort if so. | 204 // Check to see if this is a non-browser process, abort if so. |
| 211 if (IsNonBrowserProcess()) | 205 if (IsNonBrowserProcess()) |
| 212 return false; | 206 return false; |
| 213 | 207 |
| 214 // Check to see if a beacon is present, abort if so. | 208 // Check to see if a beacon is present, abort if so. |
| 215 if (!force && !CreateBeacon()) | 209 if (!force && !CreateBeacon()) |
| 216 return false; | 210 return false; |
| 217 | 211 |
| 218 // Don't try blacklisting on unsupported OS versions. | 212 // Don't try blacklisting on unsupported OS versions. |
| 219 OSInfo os_info; | 213 OSInfo os_info; |
| 220 if (os_info.version() <= VERSION_PRE_XP_SP2) | 214 if (os_info.version() <= VERSION_PRE_XP_SP2) |
| 221 return false; | 215 return false; |
| 222 | 216 |
| 223 // Pseudo-handle, no need to close. | 217 // Pseudo-handle, no need to close. |
| 224 HANDLE current_process = ::GetCurrentProcess(); | 218 HANDLE current_process = ::GetCurrentProcess(); |
| 225 | 219 |
| 226 // Tells the resolver to patch already patched functions. | 220 // Tells the resolver to patch already patched functions. |
| 227 const bool kRelaxed = true; | 221 const bool kRelaxed = true; |
| 228 | 222 |
| 229 // Create a thunk via the appropriate ServiceResolver instance. | 223 // Create a thunk via the appropriate ServiceResolver instance. |
| 230 sandbox::ServiceResolverThunk* thunk; | 224 sandbox::ServiceResolverThunk* thunk = NULL; |
| 231 #if defined(_WIN64) | 225 #if !defined(_WIN64) |
| 232 // TODO(robertshield): Use the appropriate thunk for 64-bit support | |
| 233 // when said support is implemented. | |
| 234 #else | |
| 235 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { | 226 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { |
| 236 if (os_info.version() >= VERSION_WIN8) | 227 if (os_info.version() >= VERSION_WIN8) |
| 237 thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed); | 228 thunk = new sandbox::Wow64W8ResolverThunk(current_process, kRelaxed); |
| 238 else | 229 else |
| 239 thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed); | 230 thunk = new sandbox::Wow64ResolverThunk(current_process, kRelaxed); |
| 240 } else if (os_info.version() >= VERSION_WIN8) { | |
| 241 thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed); | |
| 242 } else { | |
| 243 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); | |
| 244 } | 231 } |
| 245 #endif | 232 #endif |
| 246 | 233 |
| 234 if (!thunk) { |
| 235 if (os_info.version() >= VERSION_WIN8) { |
| 236 thunk = new sandbox::Win8ResolverThunk(current_process, kRelaxed); |
| 237 } else { |
| 238 thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); |
| 239 } |
| 240 } |
| 241 |
| 247 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); | 242 BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage); |
| 248 | 243 |
| 249 // Mark the thunk storage as readable and writeable, since we | 244 // Mark the thunk storage as readable and writeable, since we |
| 250 // ready to write to it. | 245 // ready to write to it. |
| 251 DWORD old_protect = 0; | 246 DWORD old_protect = 0; |
| 252 if (!VirtualProtect(&g_thunk_storage, | 247 if (!VirtualProtect(&g_thunk_storage, |
| 253 sizeof(g_thunk_storage), | 248 sizeof(g_thunk_storage), |
| 254 PAGE_EXECUTE_READWRITE, | 249 PAGE_EXECUTE_READWRITE, |
| 255 &old_protect)) | 250 &old_protect)) |
| 256 return false; | 251 return false; |
| 257 | 252 |
| 258 thunk->AllowLocalPatches(); | 253 thunk->AllowLocalPatches(); |
| 259 | 254 |
| 260 // Get ntdll base, target name, interceptor address, | 255 // We declare this early so it can be used in the 64-bit block below and |
| 256 // still works on 32-bit build when referenced at the end of the function. |
| 257 BOOL page_executable; |
| 258 |
| 259 // Replace the default NtMapViewOfSection with our patched version. |
| 260 #if defined(_WIN64) |
| 261 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), | 261 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), |
| 262 reinterpret_cast<void*>(&__ImageBase), | 262 reinterpret_cast<void*>(&__ImageBase), |
| 263 "NtMapViewOfSection", | 263 "NtMapViewOfSection", |
| 264 NULL, |
| 265 &blacklist::BlNtMapViewOfSection64, |
| 266 thunk_storage, |
| 267 sizeof(sandbox::ThunkData), |
| 268 NULL); |
| 269 |
| 270 // Keep a pointer to the original code, we don't have enough space to |
| 271 // add it directly to the call. |
| 272 g_nt_map_view_of_section_func = reinterpret_cast<NtMapViewOfSectionFunction>( |
| 273 thunk_storage); |
| 274 |
| 275 // Ensure that the pointer to the old function can't be changed. |
| 276 page_executable = VirtualProtect(&g_nt_map_view_of_section_func, |
| 277 sizeof(g_nt_map_view_of_section_func), |
| 278 PAGE_EXECUTE_READ, |
| 279 &old_protect); |
| 280 #else |
| 281 NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), |
| 282 reinterpret_cast<void*>(&__ImageBase), |
| 283 "NtMapViewOfSection", |
| 264 NULL, | 284 NULL, |
| 265 &blacklist::BlNtMapViewOfSection, | 285 &blacklist::BlNtMapViewOfSection, |
| 266 thunk_storage, | 286 thunk_storage, |
| 267 sizeof(sandbox::ThunkData), | 287 sizeof(sandbox::ThunkData), |
| 268 NULL); | 288 NULL); |
| 269 | 289 #endif |
| 270 delete thunk; | 290 delete thunk; |
| 271 | 291 |
| 272 // Mark the thunk storage as executable and prevent any future writes to it. | 292 // Mark the thunk storage as executable and prevent any future writes to it. |
| 273 BOOL page_executable = VirtualProtect(&g_thunk_storage, | 293 page_executable = VirtualProtect(&g_thunk_storage, |
| 274 sizeof(g_thunk_storage), | 294 sizeof(g_thunk_storage), |
| 275 PAGE_EXECUTE_READ, | 295 PAGE_EXECUTE_READ, |
| 276 &old_protect); | 296 &old_protect); |
| 277 | 297 |
| 278 return NT_SUCCESS(ret) && page_executable; | 298 return NT_SUCCESS(ret) && page_executable; |
| 279 } | 299 } |
| 280 | 300 |
| 281 } // namespace blacklist | 301 } // namespace blacklist |
| OLD | NEW |