OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 <stddef.h> | |
6 | |
7 #include <map> | |
8 | |
9 #include "sandbox/win/src/policy_broker.h" | |
10 | |
11 #include "base/logging.h" | |
12 #include "base/win/pe_image.h" | |
13 #include "base/win/windows_version.h" | |
14 #include "sandbox/win/src/interception.h" | |
15 #include "sandbox/win/src/interceptors.h" | |
16 #include "sandbox/win/src/policy_target.h" | |
17 #include "sandbox/win/src/process_thread_interception.h" | |
18 #include "sandbox/win/src/sandbox.h" | |
19 #include "sandbox/win/src/sandbox_nt_types.h" | |
20 #include "sandbox/win/src/sandbox_types.h" | |
21 #include "sandbox/win/src/target_process.h" | |
22 | |
23 // This code executes on the broker side, as a callback from the policy on the | |
24 // target side (the child). | |
25 | |
26 namespace sandbox { | |
27 | |
28 // This is the list of all imported symbols from ntdll.dll. | |
29 SANDBOX_INTERCEPT NtExports g_nt; | |
30 | |
31 #define INIT_GLOBAL_NT(member) \ | |
32 g_nt.member = reinterpret_cast<Nt##member##Function>( \ | |
33 ntdll_image.GetProcAddress("Nt" #member)); \ | |
34 if (NULL == g_nt.member) \ | |
35 return false | |
36 | |
37 #define INIT_GLOBAL_RTL(member) \ | |
38 g_nt.member = reinterpret_cast<member##Function>( \ | |
39 ntdll_image.GetProcAddress(#member)); \ | |
40 if (NULL == g_nt.member) \ | |
41 return false | |
42 | |
43 bool InitGlobalNt() { | |
44 HMODULE ntdll = ::GetModuleHandle(kNtdllName); | |
45 base::win::PEImage ntdll_image(ntdll); | |
46 | |
47 // Bypass purify's interception. | |
48 wchar_t* loader_get = reinterpret_cast<wchar_t*>( | |
49 ntdll_image.GetProcAddress("LdrGetDllHandle")); | |
50 if (loader_get) { | |
51 GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | | |
52 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, | |
53 loader_get, &ntdll); | |
54 } | |
55 | |
56 INIT_GLOBAL_NT(AllocateVirtualMemory); | |
57 INIT_GLOBAL_NT(Close); | |
58 INIT_GLOBAL_NT(DuplicateObject); | |
59 INIT_GLOBAL_NT(FreeVirtualMemory); | |
60 INIT_GLOBAL_NT(MapViewOfSection); | |
61 INIT_GLOBAL_NT(ProtectVirtualMemory); | |
62 INIT_GLOBAL_NT(QueryInformationProcess); | |
63 INIT_GLOBAL_NT(QueryObject); | |
64 INIT_GLOBAL_NT(QuerySection); | |
65 INIT_GLOBAL_NT(QueryVirtualMemory); | |
66 INIT_GLOBAL_NT(UnmapViewOfSection); | |
67 | |
68 INIT_GLOBAL_RTL(RtlAllocateHeap); | |
69 INIT_GLOBAL_RTL(RtlAnsiStringToUnicodeString); | |
70 INIT_GLOBAL_RTL(RtlCompareUnicodeString); | |
71 INIT_GLOBAL_RTL(RtlCreateHeap); | |
72 INIT_GLOBAL_RTL(RtlCreateUserThread); | |
73 INIT_GLOBAL_RTL(RtlDestroyHeap); | |
74 INIT_GLOBAL_RTL(RtlFreeHeap); | |
75 INIT_GLOBAL_RTL(_strnicmp); | |
76 INIT_GLOBAL_RTL(strlen); | |
77 INIT_GLOBAL_RTL(wcslen); | |
78 INIT_GLOBAL_RTL(memcpy); | |
79 | |
80 return true; | |
81 } | |
82 | |
83 bool SetupNtdllImports(TargetProcess *child) { | |
84 if (!InitGlobalNt()) { | |
85 return false; | |
86 } | |
87 | |
88 #ifndef NDEBUG | |
89 // Verify that the structure is fully initialized. | |
90 for (size_t i = 0; i < sizeof(g_nt)/sizeof(void*); i++) | |
91 DCHECK(reinterpret_cast<char**>(&g_nt)[i]); | |
92 #endif | |
93 return (SBOX_ALL_OK == child->TransferVariable("g_nt", &g_nt, sizeof(g_nt))); | |
94 } | |
95 | |
96 #undef INIT_GLOBAL_NT | |
97 #undef INIT_GLOBAL_RTL | |
98 | |
99 bool SetupBasicInterceptions(InterceptionManager* manager, | |
100 bool is_csrss_connected) { | |
101 // Interceptions provided by process_thread_policy, without actual policy. | |
102 if (!INTERCEPT_NT(manager, NtOpenThread, OPEN_THREAD_ID, 20) || | |
103 !INTERCEPT_NT(manager, NtOpenProcess, OPEN_PROCESS_ID, 20) || | |
104 !INTERCEPT_NT(manager, NtOpenProcessToken, OPEN_PROCESS_TOKEN_ID, 16)) | |
105 return false; | |
106 | |
107 // Interceptions with neither policy nor IPC. | |
108 if (!INTERCEPT_NT(manager, NtSetInformationThread, SET_INFORMATION_THREAD_ID, | |
109 20) || | |
110 !INTERCEPT_NT(manager, NtOpenThreadToken, OPEN_THREAD_TOKEN_ID, 20)) | |
111 return false; | |
112 | |
113 // This one is also provided by process_thread_policy. | |
114 if (!INTERCEPT_NT(manager, NtOpenProcessTokenEx, OPEN_PROCESS_TOKEN_EX_ID, | |
115 20)) | |
116 return false; | |
117 | |
118 if (!INTERCEPT_NT(manager, NtOpenThreadTokenEx, OPEN_THREAD_TOKEN_EX_ID, | |
119 24)) | |
120 return false; | |
121 | |
122 if (!is_csrss_connected) { | |
123 if (!INTERCEPT_EAT(manager, kKerneldllName, CreateThread, CREATE_THREAD_ID, | |
124 28)) | |
125 return false; | |
126 } | |
127 | |
128 return true; | |
129 } | |
130 | |
131 } // namespace sandbox | |
OLD | NEW |