|
1 // Copyright (c) 2006-2008 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 "sandbox/win/src/target_interceptions.h" |
|
6 |
|
7 #include "sandbox/win/src/interception_agent.h" |
|
8 #include "sandbox/win/src/sandbox_factory.h" |
|
9 #include "sandbox/win/src/sandbox_nt_util.h" |
|
10 #include "sandbox/win/src/target_services.h" |
|
11 |
|
12 namespace sandbox { |
|
13 |
|
14 SANDBOX_INTERCEPT NtExports g_nt; |
|
15 |
|
16 // Hooks NtMapViewOfSection to detect the load of DLLs. If hot patching is |
|
17 // required for this dll, this functions patches it. |
|
18 NTSTATUS WINAPI TargetNtMapViewOfSection( |
|
19 NtMapViewOfSectionFunction orig_MapViewOfSection, HANDLE section, |
|
20 HANDLE process, PVOID *base, ULONG_PTR zero_bits, SIZE_T commit_size, |
|
21 PLARGE_INTEGER offset, PSIZE_T view_size, SECTION_INHERIT inherit, |
|
22 ULONG allocation_type, ULONG protect) { |
|
23 NTSTATUS ret = orig_MapViewOfSection(section, process, base, zero_bits, |
|
24 commit_size, offset, view_size, inherit, |
|
25 allocation_type, protect); |
|
26 |
|
27 static int s_load_count = 0; |
|
28 if (1 == s_load_count) { |
|
29 SandboxFactory::GetTargetServices()->GetState()->SetKernel32Loaded(); |
|
30 s_load_count = 2; |
|
31 } |
|
32 |
|
33 do { |
|
34 if (!NT_SUCCESS(ret)) |
|
35 break; |
|
36 |
|
37 if (!InitHeap()) |
|
38 break; |
|
39 |
|
40 if (!IsSameProcess(process)) |
|
41 break; |
|
42 |
|
43 if (!IsValidImageSection(section, base, offset, view_size)) |
|
44 break; |
|
45 |
|
46 UINT image_flags; |
|
47 UNICODE_STRING* module_name = |
|
48 GetImageInfoFromModule(reinterpret_cast<HMODULE>(*base), &image_flags); |
|
49 UNICODE_STRING* file_name = GetBackingFilePath(*base); |
|
50 |
|
51 if ((!module_name) && (image_flags & MODULE_HAS_CODE)) { |
|
52 // If the module has no exports we retrieve the module name from the |
|
53 // full path of the mapped section. |
|
54 module_name = ExtractModuleName(file_name); |
|
55 } |
|
56 |
|
57 InterceptionAgent* agent = InterceptionAgent::GetInterceptionAgent(); |
|
58 |
|
59 if (agent) { |
|
60 if (!agent->OnDllLoad(file_name, module_name, *base)) { |
|
61 // Interception agent is demanding to un-map the module. |
|
62 g_nt.UnmapViewOfSection(process, *base); |
|
63 ret = STATUS_UNSUCCESSFUL; |
|
64 } |
|
65 } |
|
66 |
|
67 if (module_name) |
|
68 operator delete(module_name, NT_ALLOC); |
|
69 |
|
70 if (file_name) |
|
71 operator delete(file_name, NT_ALLOC); |
|
72 |
|
73 } while (false); |
|
74 |
|
75 if (!s_load_count) |
|
76 s_load_count = 1; |
|
77 |
|
78 return ret; |
|
79 } |
|
80 |
|
81 NTSTATUS WINAPI TargetNtUnmapViewOfSection( |
|
82 NtUnmapViewOfSectionFunction orig_UnmapViewOfSection, HANDLE process, |
|
83 PVOID base) { |
|
84 NTSTATUS ret = orig_UnmapViewOfSection(process, base); |
|
85 |
|
86 if (!NT_SUCCESS(ret)) |
|
87 return ret; |
|
88 |
|
89 if (!IsSameProcess(process)) |
|
90 return ret; |
|
91 |
|
92 InterceptionAgent* agent = InterceptionAgent::GetInterceptionAgent(); |
|
93 |
|
94 if (agent) |
|
95 agent->OnDllUnload(base); |
|
96 |
|
97 return ret; |
|
98 } |
|
99 |
|
100 } // namespace sandbox |