michael@0: // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "sandbox/win/src/target_interceptions.h" michael@0: michael@0: #include "sandbox/win/src/interception_agent.h" michael@0: #include "sandbox/win/src/sandbox_factory.h" michael@0: #include "sandbox/win/src/sandbox_nt_util.h" michael@0: #include "sandbox/win/src/target_services.h" michael@0: michael@0: namespace sandbox { michael@0: michael@0: SANDBOX_INTERCEPT NtExports g_nt; michael@0: michael@0: // Hooks NtMapViewOfSection to detect the load of DLLs. If hot patching is michael@0: // required for this dll, this functions patches it. michael@0: NTSTATUS WINAPI TargetNtMapViewOfSection( michael@0: NtMapViewOfSectionFunction orig_MapViewOfSection, HANDLE section, michael@0: HANDLE process, PVOID *base, ULONG_PTR zero_bits, SIZE_T commit_size, michael@0: PLARGE_INTEGER offset, PSIZE_T view_size, SECTION_INHERIT inherit, michael@0: ULONG allocation_type, ULONG protect) { michael@0: NTSTATUS ret = orig_MapViewOfSection(section, process, base, zero_bits, michael@0: commit_size, offset, view_size, inherit, michael@0: allocation_type, protect); michael@0: michael@0: static int s_load_count = 0; michael@0: if (1 == s_load_count) { michael@0: SandboxFactory::GetTargetServices()->GetState()->SetKernel32Loaded(); michael@0: s_load_count = 2; michael@0: } michael@0: michael@0: do { michael@0: if (!NT_SUCCESS(ret)) michael@0: break; michael@0: michael@0: if (!InitHeap()) michael@0: break; michael@0: michael@0: if (!IsSameProcess(process)) michael@0: break; michael@0: michael@0: if (!IsValidImageSection(section, base, offset, view_size)) michael@0: break; michael@0: michael@0: UINT image_flags; michael@0: UNICODE_STRING* module_name = michael@0: GetImageInfoFromModule(reinterpret_cast(*base), &image_flags); michael@0: UNICODE_STRING* file_name = GetBackingFilePath(*base); michael@0: michael@0: if ((!module_name) && (image_flags & MODULE_HAS_CODE)) { michael@0: // If the module has no exports we retrieve the module name from the michael@0: // full path of the mapped section. michael@0: module_name = ExtractModuleName(file_name); michael@0: } michael@0: michael@0: InterceptionAgent* agent = InterceptionAgent::GetInterceptionAgent(); michael@0: michael@0: if (agent) { michael@0: if (!agent->OnDllLoad(file_name, module_name, *base)) { michael@0: // Interception agent is demanding to un-map the module. michael@0: g_nt.UnmapViewOfSection(process, *base); michael@0: ret = STATUS_UNSUCCESSFUL; michael@0: } michael@0: } michael@0: michael@0: if (module_name) michael@0: operator delete(module_name, NT_ALLOC); michael@0: michael@0: if (file_name) michael@0: operator delete(file_name, NT_ALLOC); michael@0: michael@0: } while (false); michael@0: michael@0: if (!s_load_count) michael@0: s_load_count = 1; michael@0: michael@0: return ret; michael@0: } michael@0: michael@0: NTSTATUS WINAPI TargetNtUnmapViewOfSection( michael@0: NtUnmapViewOfSectionFunction orig_UnmapViewOfSection, HANDLE process, michael@0: PVOID base) { michael@0: NTSTATUS ret = orig_UnmapViewOfSection(process, base); michael@0: michael@0: if (!NT_SUCCESS(ret)) michael@0: return ret; michael@0: michael@0: if (!IsSameProcess(process)) michael@0: return ret; michael@0: michael@0: InterceptionAgent* agent = InterceptionAgent::GetInterceptionAgent(); michael@0: michael@0: if (agent) michael@0: agent->OnDllUnload(base); michael@0: michael@0: return ret; michael@0: } michael@0: michael@0: } // namespace sandbox