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 // Implementation of NtMapViewOfSection intercept for 32 bit builds. | 5 // Implementation of NtMapViewOfSection intercept for 32 bit builds. |
6 // | 6 // |
7 // TODO(robertshield): Implement the 64 bit intercept. | 7 // TODO(robertshield): Implement the 64 bit intercept. |
8 | 8 |
9 #include "chrome_elf/blacklist/blacklist_interceptions.h" | 9 #include "chrome_elf/blacklist/blacklist_interceptions.h" |
10 | 10 |
11 #include <stddef.h> | 11 #include <stddef.h> |
12 #include <stdint.h> | 12 #include <stdint.h> |
13 | 13 |
14 #include <string> | 14 #include <string> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 // Note that only #includes from base that are either header-only or built into | 17 // Note that only #includes from base that are either header-only or built into |
18 // base_static (see base/base.gyp) are allowed here. | 18 // base_static (see base/base.gyp) are allowed here. |
19 #include "base/strings/string16.h" | |
20 #include "base/win/pe_image.h" | 19 #include "base/win/pe_image.h" |
21 #include "chrome_elf/blacklist/blacklist.h" | 20 #include "chrome_elf/blacklist/blacklist.h" |
22 #include "chrome_elf/breakpad.h" | 21 #include "chrome_elf/breakpad/breakpad.h" |
23 #include "sandbox/win/src/internal_types.h" | 22 #include "sandbox/win/src/internal_types.h" |
24 #include "sandbox/win/src/nt_internals.h" | 23 #include "sandbox/win/src/nt_internals.h" |
25 #include "sandbox/win/src/sandbox_nt_util.h" | 24 #include "sandbox/win/src/sandbox_nt_util.h" |
26 #include "sandbox/win/src/sandbox_types.h" | 25 #include "sandbox/win/src/sandbox_types.h" |
27 | 26 |
28 namespace { | 27 namespace { |
29 | 28 |
30 NtQuerySectionFunction g_nt_query_section_func = NULL; | 29 NtQuerySectionFunction g_nt_query_section_func = NULL; |
31 NtQueryVirtualMemoryFunction g_nt_query_virtual_memory_func = NULL; | 30 NtQueryVirtualMemoryFunction g_nt_query_virtual_memory_func = NULL; |
32 NtUnmapViewOfSectionFunction g_nt_unmap_view_of_section_func = NULL; | 31 NtUnmapViewOfSectionFunction g_nt_unmap_view_of_section_func = NULL; |
33 | 32 |
34 // TODO(robertshield): Merge with ntdll exports cache. | 33 // TODO(robertshield): Merge with ntdll exports cache. |
35 FARPROC GetNtDllExportByName(const char* export_name) { | 34 FARPROC GetNtDllExportByName(const char* export_name) { |
36 HMODULE ntdll = ::GetModuleHandle(sandbox::kNtdllName); | 35 HMODULE ntdll = ::GetModuleHandle(sandbox::kNtdllName); |
37 return ::GetProcAddress(ntdll, export_name); | 36 return ::GetProcAddress(ntdll, export_name); |
38 } | 37 } |
39 | 38 |
40 int DllMatch(const base::string16& module_name) { | 39 int DllMatch(const std::wstring& module_name) { |
41 if (module_name.empty()) | 40 if (module_name.empty()) |
42 return -1; | 41 return -1; |
43 | 42 |
44 for (int i = 0; blacklist::g_troublesome_dlls[i] != NULL; ++i) { | 43 for (int i = 0; blacklist::g_troublesome_dlls[i] != NULL; ++i) { |
45 if (_wcsicmp(module_name.c_str(), blacklist::g_troublesome_dlls[i]) == 0) | 44 if (_wcsicmp(module_name.c_str(), blacklist::g_troublesome_dlls[i]) == 0) |
46 return i; | 45 return i; |
47 } | 46 } |
48 return -1; | 47 return -1; |
49 } | 48 } |
50 | 49 |
51 // TODO(robertshield): Some of the helper functions below overlap somewhat with | 50 // TODO(robertshield): Some of the helper functions below overlap somewhat with |
52 // code in sandbox_nt_util.cc. See if they can be unified. | 51 // code in sandbox_nt_util.cc. See if they can be unified. |
53 | 52 |
54 // Native reimplementation of PSAPIs GetMappedFileName. | 53 // Native reimplementation of PSAPIs GetMappedFileName. |
55 base::string16 GetBackingModuleFilePath(PVOID address) { | 54 std::wstring GetBackingModuleFilePath(PVOID address) { |
56 DCHECK_NT(g_nt_query_virtual_memory_func); | 55 DCHECK_NT(g_nt_query_virtual_memory_func); |
57 | 56 |
58 // We'll start with something close to max_path characters for the name. | 57 // We'll start with something close to max_path characters for the name. |
59 SIZE_T buffer_bytes = MAX_PATH * 2; | 58 SIZE_T buffer_bytes = MAX_PATH * 2; |
60 std::vector<BYTE> buffer_data(buffer_bytes); | 59 std::vector<BYTE> buffer_data(buffer_bytes); |
61 | 60 |
62 for (;;) { | 61 for (;;) { |
63 MEMORY_SECTION_NAME* section_name = | 62 MEMORY_SECTION_NAME* section_name = |
64 reinterpret_cast<MEMORY_SECTION_NAME*>(&buffer_data[0]); | 63 reinterpret_cast<MEMORY_SECTION_NAME*>(&buffer_data[0]); |
65 | 64 |
(...skipping 10 matching lines...) Expand all Loading... |
76 buffer_bytes = returned_bytes + 1; | 75 buffer_bytes = returned_bytes + 1; |
77 buffer_data.resize(buffer_bytes); | 76 buffer_data.resize(buffer_bytes); |
78 section_name = NULL; | 77 section_name = NULL; |
79 continue; | 78 continue; |
80 } | 79 } |
81 if (!NT_SUCCESS(ret)) | 80 if (!NT_SUCCESS(ret)) |
82 break; | 81 break; |
83 | 82 |
84 UNICODE_STRING* section_string = | 83 UNICODE_STRING* section_string = |
85 reinterpret_cast<UNICODE_STRING*>(section_name); | 84 reinterpret_cast<UNICODE_STRING*>(section_name); |
86 return base::string16(section_string->Buffer, | 85 return std::wstring(section_string->Buffer, |
87 section_string->Length / sizeof(wchar_t)); | 86 section_string->Length / sizeof(wchar_t)); |
88 } | 87 } |
89 | 88 |
90 return base::string16(); | 89 return std::wstring(); |
91 } | 90 } |
92 | 91 |
93 bool IsModuleValidImageSection(HANDLE section, | 92 bool IsModuleValidImageSection(HANDLE section, |
94 PVOID* base, | 93 PVOID* base, |
95 PLARGE_INTEGER offset, | 94 PLARGE_INTEGER offset, |
96 PSIZE_T view_size) { | 95 PSIZE_T view_size) { |
97 DCHECK_NT(g_nt_query_section_func); | 96 DCHECK_NT(g_nt_query_section_func); |
98 | 97 |
99 if (!section || !base || !view_size || offset) | 98 if (!section || !base || !view_size || offset) |
100 return false; | 99 return false; |
101 | 100 |
102 SECTION_BASIC_INFORMATION basic_info; | 101 SECTION_BASIC_INFORMATION basic_info; |
103 SIZE_T bytes_returned; | 102 SIZE_T bytes_returned; |
104 NTSTATUS ret = g_nt_query_section_func(section, SectionBasicInformation, | 103 NTSTATUS ret = g_nt_query_section_func(section, SectionBasicInformation, |
105 &basic_info, sizeof(basic_info), | 104 &basic_info, sizeof(basic_info), |
106 &bytes_returned); | 105 &bytes_returned); |
107 | 106 |
108 if (!NT_SUCCESS(ret) || sizeof(basic_info) != bytes_returned) | 107 if (!NT_SUCCESS(ret) || sizeof(basic_info) != bytes_returned) |
109 return false; | 108 return false; |
110 | 109 |
111 if (!(basic_info.Attributes & SEC_IMAGE)) | 110 if (!(basic_info.Attributes & SEC_IMAGE)) |
112 return false; | 111 return false; |
113 | 112 |
114 return true; | 113 return true; |
115 } | 114 } |
116 | 115 |
117 base::string16 ExtractLoadedModuleName(const base::string16& module_path) { | 116 std::wstring ExtractLoadedModuleName(const std::wstring& module_path) { |
118 if (module_path.empty() || module_path.back() == L'\\') | 117 if (module_path.empty() || module_path.back() == L'\\') |
119 return base::string16(); | 118 return std::wstring(); |
120 | 119 |
121 size_t sep = module_path.find_last_of(L'\\'); | 120 size_t sep = module_path.find_last_of(L'\\'); |
122 if (sep == base::string16::npos) | 121 if (sep == std::wstring::npos) |
123 return module_path; | 122 return module_path; |
124 return module_path.substr(sep + 1); | 123 return module_path.substr(sep + 1); |
125 } | 124 } |
126 | 125 |
127 // Fills |out_name| with the image name from the given |pe| image and |flags| | 126 // Fills |out_name| with the image name from the given |pe| image and |flags| |
128 // with additional info about the image. | 127 // with additional info about the image. |
129 void SafeGetImageInfo(const base::win::PEImage& pe, | 128 void SafeGetImageInfo(const base::win::PEImage& pe, |
130 std::string* out_name, | 129 std::string* out_name, |
131 uint32_t* flags) { | 130 uint32_t* flags) { |
132 out_name->clear(); | 131 out_name->clear(); |
(...skipping 21 matching lines...) Expand all Loading... |
154 } | 153 } |
155 } | 154 } |
156 } __except((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION || | 155 } __except((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION || |
157 GetExceptionCode() == EXCEPTION_GUARD_PAGE || | 156 GetExceptionCode() == EXCEPTION_GUARD_PAGE || |
158 GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR) ? | 157 GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR) ? |
159 EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { | 158 EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { |
160 out_name->clear(); | 159 out_name->clear(); |
161 } | 160 } |
162 } | 161 } |
163 | 162 |
164 base::string16 GetImageInfoFromLoadedModule(HMODULE module, uint32_t* flags) { | 163 std::wstring GetImageInfoFromLoadedModule(HMODULE module, uint32_t* flags) { |
165 std::string out_name; | 164 std::string out_name; |
166 base::win::PEImage pe(module); | 165 base::win::PEImage pe(module); |
167 SafeGetImageInfo(pe, &out_name, flags); | 166 SafeGetImageInfo(pe, &out_name, flags); |
168 return base::string16(out_name.begin(), out_name.end()); | 167 return std::wstring(out_name.begin(), out_name.end()); |
169 } | 168 } |
170 | 169 |
171 bool IsSameAsCurrentProcess(HANDLE process) { | 170 bool IsSameAsCurrentProcess(HANDLE process) { |
172 return (NtCurrentProcess == process) || | 171 return (NtCurrentProcess == process) || |
173 (::GetProcessId(process) == ::GetCurrentProcessId()); | 172 (::GetProcessId(process) == ::GetCurrentProcessId()); |
174 } | 173 } |
175 | 174 |
176 NTSTATUS BlNtMapViewOfSectionImpl( | 175 NTSTATUS BlNtMapViewOfSectionImpl( |
177 NtMapViewOfSectionFunction orig_MapViewOfSection, | 176 NtMapViewOfSectionFunction orig_MapViewOfSection, |
178 HANDLE section, | 177 HANDLE section, |
(...skipping 12 matching lines...) Expand all Loading... |
191 | 190 |
192 if (!NT_SUCCESS(ret) || !IsSameAsCurrentProcess(process) || | 191 if (!NT_SUCCESS(ret) || !IsSameAsCurrentProcess(process) || |
193 !IsModuleValidImageSection(section, base, offset, view_size)) { | 192 !IsModuleValidImageSection(section, base, offset, view_size)) { |
194 return ret; | 193 return ret; |
195 } | 194 } |
196 | 195 |
197 HMODULE module = reinterpret_cast<HMODULE>(*base); | 196 HMODULE module = reinterpret_cast<HMODULE>(*base); |
198 if (module) { | 197 if (module) { |
199 UINT image_flags; | 198 UINT image_flags; |
200 | 199 |
201 base::string16 module_name_from_image(GetImageInfoFromLoadedModule( | 200 std::wstring module_name_from_image(GetImageInfoFromLoadedModule( |
202 reinterpret_cast<HMODULE>(*base), &image_flags)); | 201 reinterpret_cast<HMODULE>(*base), &image_flags)); |
203 | 202 |
204 int blocked_index = DllMatch(module_name_from_image); | 203 int blocked_index = DllMatch(module_name_from_image); |
205 | 204 |
206 // If the module name isn't blacklisted, see if the file name is different | 205 // If the module name isn't blacklisted, see if the file name is different |
207 // and blacklisted. | 206 // and blacklisted. |
208 if (blocked_index == -1) { | 207 if (blocked_index == -1) { |
209 base::string16 file_name(GetBackingModuleFilePath(*base)); | 208 std::wstring file_name(GetBackingModuleFilePath(*base)); |
210 base::string16 module_name_from_file = ExtractLoadedModuleName(file_name); | 209 std::wstring module_name_from_file = ExtractLoadedModuleName(file_name); |
211 | 210 |
212 if (module_name_from_image != module_name_from_file) | 211 if (module_name_from_image != module_name_from_file) |
213 blocked_index = DllMatch(module_name_from_file); | 212 blocked_index = DllMatch(module_name_from_file); |
214 } | 213 } |
215 | 214 |
216 if (blocked_index != -1) { | 215 if (blocked_index != -1) { |
217 DCHECK_NT(g_nt_unmap_view_of_section_func); | 216 DCHECK_NT(g_nt_unmap_view_of_section_func); |
218 g_nt_unmap_view_of_section_func(process, *base); | 217 g_nt_unmap_view_of_section_func(process, *base); |
219 ret = STATUS_UNSUCCESSFUL; | 218 ret = STATUS_UNSUCCESSFUL; |
220 | 219 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 NTSTATUS WINAPI BlNtMapViewOfSection64( | 272 NTSTATUS WINAPI BlNtMapViewOfSection64( |
274 HANDLE section, HANDLE process, PVOID *base, ULONG_PTR zero_bits, | 273 HANDLE section, HANDLE process, PVOID *base, ULONG_PTR zero_bits, |
275 SIZE_T commit_size, PLARGE_INTEGER offset, PSIZE_T view_size, | 274 SIZE_T commit_size, PLARGE_INTEGER offset, PSIZE_T view_size, |
276 SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect) { | 275 SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect) { |
277 return BlNtMapViewOfSection(g_nt_map_view_of_section_func, section, process, | 276 return BlNtMapViewOfSection(g_nt_map_view_of_section_func, section, process, |
278 base, zero_bits, commit_size, offset, view_size, | 277 base, zero_bits, commit_size, offset, view_size, |
279 inherit, allocation_type, protect); | 278 inherit, allocation_type, protect); |
280 } | 279 } |
281 #endif | 280 #endif |
282 } // namespace blacklist | 281 } // namespace blacklist |
OLD | NEW |