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[module_path.size() - 1] == L'\\') | 117 if (module_path.empty() || module_path[module_path.size() - 1] == 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 else | 123 else |
125 return module_path.substr(sep+1); | 124 return module_path.substr(sep+1); |
126 } | 125 } |
127 | 126 |
128 // Fills |out_name| with the image name from the given |pe| image and |flags| | 127 // Fills |out_name| with the image name from the given |pe| image and |flags| |
129 // with additional info about the image. | 128 // with additional info about the image. |
130 void SafeGetImageInfo(const base::win::PEImage& pe, | 129 void SafeGetImageInfo(const base::win::PEImage& pe, |
131 std::string* out_name, | 130 std::string* out_name, |
132 uint32_t* flags) { | 131 uint32_t* flags) { |
(...skipping 22 matching lines...) Expand all Loading... |
155 } | 154 } |
156 } | 155 } |
157 } __except((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION || | 156 } __except((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION || |
158 GetExceptionCode() == EXCEPTION_GUARD_PAGE || | 157 GetExceptionCode() == EXCEPTION_GUARD_PAGE || |
159 GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR) ? | 158 GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR) ? |
160 EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { | 159 EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { |
161 out_name->clear(); | 160 out_name->clear(); |
162 } | 161 } |
163 } | 162 } |
164 | 163 |
165 base::string16 GetImageInfoFromLoadedModule(HMODULE module, uint32_t* flags) { | 164 std::wstring GetImageInfoFromLoadedModule(HMODULE module, uint32_t* flags) { |
166 std::string out_name; | 165 std::string out_name; |
167 base::win::PEImage pe(module); | 166 base::win::PEImage pe(module); |
168 SafeGetImageInfo(pe, &out_name, flags); | 167 SafeGetImageInfo(pe, &out_name, flags); |
169 return base::string16(out_name.begin(), out_name.end()); | 168 return std::wstring(out_name.begin(), out_name.end()); |
170 } | 169 } |
171 | 170 |
172 bool IsSameAsCurrentProcess(HANDLE process) { | 171 bool IsSameAsCurrentProcess(HANDLE process) { |
173 return (NtCurrentProcess == process) || | 172 return (NtCurrentProcess == process) || |
174 (::GetProcessId(process) == ::GetCurrentProcessId()); | 173 (::GetProcessId(process) == ::GetCurrentProcessId()); |
175 } | 174 } |
176 | 175 |
177 NTSTATUS BlNtMapViewOfSectionImpl( | 176 NTSTATUS BlNtMapViewOfSectionImpl( |
178 NtMapViewOfSectionFunction orig_MapViewOfSection, | 177 NtMapViewOfSectionFunction orig_MapViewOfSection, |
179 HANDLE section, | 178 HANDLE section, |
(...skipping 12 matching lines...) Expand all Loading... |
192 | 191 |
193 if (!NT_SUCCESS(ret) || !IsSameAsCurrentProcess(process) || | 192 if (!NT_SUCCESS(ret) || !IsSameAsCurrentProcess(process) || |
194 !IsModuleValidImageSection(section, base, offset, view_size)) { | 193 !IsModuleValidImageSection(section, base, offset, view_size)) { |
195 return ret; | 194 return ret; |
196 } | 195 } |
197 | 196 |
198 HMODULE module = reinterpret_cast<HMODULE>(*base); | 197 HMODULE module = reinterpret_cast<HMODULE>(*base); |
199 if (module) { | 198 if (module) { |
200 UINT image_flags; | 199 UINT image_flags; |
201 | 200 |
202 base::string16 module_name_from_image(GetImageInfoFromLoadedModule( | 201 std::wstring module_name_from_image(GetImageInfoFromLoadedModule( |
203 reinterpret_cast<HMODULE>(*base), &image_flags)); | 202 reinterpret_cast<HMODULE>(*base), &image_flags)); |
204 | 203 |
205 int blocked_index = DllMatch(module_name_from_image); | 204 int blocked_index = DllMatch(module_name_from_image); |
206 | 205 |
207 // If the module name isn't blacklisted, see if the file name is different | 206 // If the module name isn't blacklisted, see if the file name is different |
208 // and blacklisted. | 207 // and blacklisted. |
209 if (blocked_index == -1) { | 208 if (blocked_index == -1) { |
210 base::string16 file_name(GetBackingModuleFilePath(*base)); | 209 std::wstring file_name(GetBackingModuleFilePath(*base)); |
211 base::string16 module_name_from_file = ExtractLoadedModuleName(file_name); | 210 std::wstring module_name_from_file = ExtractLoadedModuleName(file_name); |
212 | 211 |
213 if (module_name_from_image != module_name_from_file) | 212 if (module_name_from_image != module_name_from_file) |
214 blocked_index = DllMatch(module_name_from_file); | 213 blocked_index = DllMatch(module_name_from_file); |
215 } | 214 } |
216 | 215 |
217 if (blocked_index != -1) { | 216 if (blocked_index != -1) { |
218 DCHECK_NT(g_nt_unmap_view_of_section_func); | 217 DCHECK_NT(g_nt_unmap_view_of_section_func); |
219 g_nt_unmap_view_of_section_func(process, *base); | 218 g_nt_unmap_view_of_section_func(process, *base); |
220 ret = STATUS_UNSUCCESSFUL; | 219 ret = STATUS_UNSUCCESSFUL; |
221 | 220 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 NTSTATUS WINAPI BlNtMapViewOfSection64( | 273 NTSTATUS WINAPI BlNtMapViewOfSection64( |
275 HANDLE section, HANDLE process, PVOID *base, ULONG_PTR zero_bits, | 274 HANDLE section, HANDLE process, PVOID *base, ULONG_PTR zero_bits, |
276 SIZE_T commit_size, PLARGE_INTEGER offset, PSIZE_T view_size, | 275 SIZE_T commit_size, PLARGE_INTEGER offset, PSIZE_T view_size, |
277 SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect) { | 276 SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect) { |
278 return BlNtMapViewOfSection(g_nt_map_view_of_section_func, section, process, | 277 return BlNtMapViewOfSection(g_nt_map_view_of_section_func, section, process, |
279 base, zero_bits, commit_size, offset, view_size, | 278 base, zero_bits, commit_size, offset, view_size, |
280 inherit, allocation_type, protect); | 279 inherit, allocation_type, protect); |
281 } | 280 } |
282 #endif | 281 #endif |
283 } // namespace blacklist | 282 } // namespace blacklist |
OLD | NEW |