diff options
Diffstat (limited to 'sandbox/win/src/interception_agent.cc')
-rw-r--r-- | sandbox/win/src/interception_agent.cc | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/sandbox/win/src/interception_agent.cc b/sandbox/win/src/interception_agent.cc deleted file mode 100644 index b2a66c471f..0000000000 --- a/sandbox/win/src/interception_agent.cc +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// For information about interceptions as a whole see -// http://dev.chromium.org/developers/design-documents/sandbox . - -#include "sandbox/win/src/interception_agent.h" - -#include "sandbox/win/src/interception_internal.h" -#include "sandbox/win/src/interceptors.h" -#include "sandbox/win/src/eat_resolver.h" -#include "sandbox/win/src/sidestep_resolver.h" -#include "sandbox/win/src/sandbox_nt_util.h" - -namespace { - -// Returns true if target lies between base and base + range. -bool IsWithinRange(const void* base, size_t range, const void* target) { - const char* end = reinterpret_cast<const char*>(base) + range; - return reinterpret_cast<const char*>(target) < end; -} - -} // namespace - -namespace sandbox { - -// This is the list of all imported symbols from ntdll.dll. -SANDBOX_INTERCEPT NtExports g_nt; - -// The list of intercepted functions back-pointers. -SANDBOX_INTERCEPT OriginalFunctions g_originals; - -// Memory buffer mapped from the parent, with the list of interceptions. -SANDBOX_INTERCEPT SharedMemory* g_interceptions = NULL; - -InterceptionAgent* InterceptionAgent::GetInterceptionAgent() { - static InterceptionAgent* s_singleton = NULL; - if (!s_singleton) { - if (!g_interceptions) - return NULL; - - size_t array_bytes = g_interceptions->num_intercepted_dlls * sizeof(void*); - s_singleton = reinterpret_cast<InterceptionAgent*>( - new(NT_ALLOC) char[array_bytes + sizeof(InterceptionAgent)]); - - bool success = s_singleton->Init(g_interceptions); - if (!success) { - operator delete(s_singleton, NT_ALLOC); - s_singleton = NULL; - } - } - return s_singleton; -} - -bool InterceptionAgent::Init(SharedMemory* shared_memory) { - interceptions_ = shared_memory; - for (int i = 0 ; i < shared_memory->num_intercepted_dlls; i++) - dlls_[i] = NULL; - return true; -} - -bool InterceptionAgent::DllMatch(const UNICODE_STRING* full_path, - const UNICODE_STRING* name, - const DllPatchInfo* dll_info) { - UNICODE_STRING current_name; - current_name.Length = static_cast<USHORT>(g_nt.wcslen(dll_info->dll_name) * - sizeof(wchar_t)); - current_name.MaximumLength = current_name.Length; - current_name.Buffer = const_cast<wchar_t*>(dll_info->dll_name); - - BOOLEAN case_insensitive = TRUE; - if (full_path && - !g_nt.RtlCompareUnicodeString(¤t_name, full_path, case_insensitive)) - return true; - - if (name && - !g_nt.RtlCompareUnicodeString(¤t_name, name, case_insensitive)) - return true; - - return false; -} - -bool InterceptionAgent::OnDllLoad(const UNICODE_STRING* full_path, - const UNICODE_STRING* name, - void* base_address) { - DllPatchInfo* dll_info = interceptions_->dll_list; - int i = 0; - for (; i < interceptions_->num_intercepted_dlls; i++) { - if (DllMatch(full_path, name, dll_info)) - break; - - dll_info = reinterpret_cast<DllPatchInfo*>( - reinterpret_cast<char*>(dll_info) + dll_info->record_bytes); - } - - // Return now if the dll is not in our list of interest. - if (i == interceptions_->num_intercepted_dlls) - return true; - - // The dll must be unloaded. - if (dll_info->unload_module) - return false; - - // Purify causes this condition to trigger. - if (dlls_[i]) - return true; - - size_t buffer_bytes = offsetof(DllInterceptionData, thunks) + - dll_info->num_functions * sizeof(ThunkData); - dlls_[i] = reinterpret_cast<DllInterceptionData*>( - new(NT_PAGE, base_address) char[buffer_bytes]); - - DCHECK_NT(dlls_[i]); - if (!dlls_[i]) - return true; - - dlls_[i]->data_bytes = buffer_bytes; - dlls_[i]->num_thunks = 0; - dlls_[i]->base = base_address; - dlls_[i]->used_bytes = offsetof(DllInterceptionData, thunks); - - VERIFY(PatchDll(dll_info, dlls_[i])); - - ULONG old_protect; - SIZE_T real_size = buffer_bytes; - void* to_protect = dlls_[i]; - VERIFY_SUCCESS(g_nt.ProtectVirtualMemory(NtCurrentProcess, &to_protect, - &real_size, PAGE_EXECUTE_READ, - &old_protect)); - return true; -} - -void InterceptionAgent::OnDllUnload(void* base_address) { - for (int i = 0; i < interceptions_->num_intercepted_dlls; i++) { - if (dlls_[i] && dlls_[i]->base == base_address) { - operator delete(dlls_[i], NT_PAGE); - dlls_[i] = NULL; - break; - } - } -} - -// TODO(rvargas): We have to deal with prebinded dlls. I see two options: change -// the timestamp of the patched dll, or modify the info on the prebinded dll. -// the first approach messes matching of debug symbols, the second one is more -// complicated. -bool InterceptionAgent::PatchDll(const DllPatchInfo* dll_info, - DllInterceptionData* thunks) { - DCHECK_NT(NULL != thunks); - DCHECK_NT(NULL != dll_info); - - const FunctionInfo* function = reinterpret_cast<const FunctionInfo*>( - reinterpret_cast<const char*>(dll_info) + dll_info->offset_to_functions); - - for (int i = 0; i < dll_info->num_functions; i++) { - if (!IsWithinRange(dll_info, dll_info->record_bytes, function->function)) { - NOTREACHED_NT(); - return false; - } - - ResolverThunk* resolver = GetResolver(function->type); - if (!resolver) - return false; - - const char* interceptor = function->function + - g_nt.strlen(function->function) + 1; - - if (!IsWithinRange(function, function->record_bytes, interceptor) || - !IsWithinRange(dll_info, dll_info->record_bytes, interceptor)) { - NOTREACHED_NT(); - return false; - } - - NTSTATUS ret = resolver->Setup(thunks->base, - interceptions_->interceptor_base, - function->function, - interceptor, - function->interceptor_address, - &thunks->thunks[i], - sizeof(ThunkData), - NULL); - if (!NT_SUCCESS(ret)) { - NOTREACHED_NT(); - return false; - } - - DCHECK_NT(!g_originals[function->id]); - g_originals[function->id] = &thunks->thunks[i]; - - thunks->num_thunks++; - thunks->used_bytes += sizeof(ThunkData); - - function = reinterpret_cast<const FunctionInfo*>( - reinterpret_cast<const char*>(function) + function->record_bytes); - } - - return true; -} - -// This method is called from within the loader lock -ResolverThunk* InterceptionAgent::GetResolver(InterceptionType type) { - static EatResolverThunk* eat_resolver = NULL; - static SidestepResolverThunk* sidestep_resolver = NULL; - static SmartSidestepResolverThunk* smart_sidestep_resolver = NULL; - - if (!eat_resolver) - eat_resolver = new(NT_ALLOC) EatResolverThunk; - -#if !defined(_WIN64) - // Sidestep is not supported for x64. - if (!sidestep_resolver) - sidestep_resolver = new(NT_ALLOC) SidestepResolverThunk; - - if (!smart_sidestep_resolver) - smart_sidestep_resolver = new(NT_ALLOC) SmartSidestepResolverThunk; -#endif - - switch (type) { - case INTERCEPTION_EAT: - return eat_resolver; - case INTERCEPTION_SIDESTEP: - return sidestep_resolver; - case INTERCEPTION_SMART_SIDESTEP: - return smart_sidestep_resolver; - default: - NOTREACHED_NT(); - } - - return NULL; -} - -} // namespace sandbox |