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 |
(...skipping 16 matching lines...) Expand all Loading... |
27 NtQuerySectionFunction g_nt_query_section_func = NULL; | 27 NtQuerySectionFunction g_nt_query_section_func = NULL; |
28 NtQueryVirtualMemoryFunction g_nt_query_virtual_memory_func = NULL; | 28 NtQueryVirtualMemoryFunction g_nt_query_virtual_memory_func = NULL; |
29 NtUnmapViewOfSectionFunction g_nt_unmap_view_of_section_func = NULL; | 29 NtUnmapViewOfSectionFunction g_nt_unmap_view_of_section_func = NULL; |
30 | 30 |
31 // TODO(robertshield): Merge with ntdll exports cache. | 31 // TODO(robertshield): Merge with ntdll exports cache. |
32 FARPROC GetNtDllExportByName(const char* export_name) { | 32 FARPROC GetNtDllExportByName(const char* export_name) { |
33 HMODULE ntdll = ::GetModuleHandle(sandbox::kNtdllName); | 33 HMODULE ntdll = ::GetModuleHandle(sandbox::kNtdllName); |
34 return ::GetProcAddress(ntdll, export_name); | 34 return ::GetProcAddress(ntdll, export_name); |
35 } | 35 } |
36 | 36 |
37 bool DllMatch(const string16& module_name) { | 37 bool DllMatch(const base::string16& module_name) { |
38 for (int i = 0; i < blacklist::g_troublesome_dlls_cur_index; ++i) { | 38 for (int i = 0; i < blacklist::g_troublesome_dlls_cur_index; ++i) { |
39 if (module_name == blacklist::g_troublesome_dlls[i]) | 39 if (module_name == blacklist::g_troublesome_dlls[i]) |
40 return true; | 40 return true; |
41 } | 41 } |
42 return false; | 42 return false; |
43 } | 43 } |
44 | 44 |
45 // TODO(robertshield): Some of the helper functions below overlap somewhat with | 45 // TODO(robertshield): Some of the helper functions below overlap somewhat with |
46 // code in sandbox_nt_util.cc. See if they can be unified. | 46 // code in sandbox_nt_util.cc. See if they can be unified. |
47 | 47 |
48 // Native reimplementation of PSAPIs GetMappedFileName. | 48 // Native reimplementation of PSAPIs GetMappedFileName. |
49 string16 GetBackingModuleFilePath(PVOID address) { | 49 base::string16 GetBackingModuleFilePath(PVOID address) { |
50 DCHECK_NT(g_nt_query_virtual_memory_func); | 50 DCHECK_NT(g_nt_query_virtual_memory_func); |
51 | 51 |
52 // We'll start with something close to max_path characters for the name. | 52 // We'll start with something close to max_path characters for the name. |
53 ULONG buffer_bytes = MAX_PATH * 2; | 53 ULONG buffer_bytes = MAX_PATH * 2; |
54 std::vector<BYTE> buffer_data(buffer_bytes); | 54 std::vector<BYTE> buffer_data(buffer_bytes); |
55 | 55 |
56 for (;;) { | 56 for (;;) { |
57 MEMORY_SECTION_NAME* section_name = | 57 MEMORY_SECTION_NAME* section_name = |
58 reinterpret_cast<MEMORY_SECTION_NAME*>(&buffer_data[0]); | 58 reinterpret_cast<MEMORY_SECTION_NAME*>(&buffer_data[0]); |
59 | 59 |
(...skipping 10 matching lines...) Expand all Loading... |
70 buffer_bytes = returned_bytes + 1; | 70 buffer_bytes = returned_bytes + 1; |
71 buffer_data.resize(buffer_bytes); | 71 buffer_data.resize(buffer_bytes); |
72 section_name = NULL; | 72 section_name = NULL; |
73 continue; | 73 continue; |
74 } | 74 } |
75 if (!NT_SUCCESS(ret)) | 75 if (!NT_SUCCESS(ret)) |
76 break; | 76 break; |
77 | 77 |
78 UNICODE_STRING* section_string = | 78 UNICODE_STRING* section_string = |
79 reinterpret_cast<UNICODE_STRING*>(section_name); | 79 reinterpret_cast<UNICODE_STRING*>(section_name); |
80 return string16(section_string->Buffer, | 80 return base::string16(section_string->Buffer, |
81 section_string->Length / sizeof(wchar_t)); | 81 section_string->Length / sizeof(wchar_t)); |
82 } | 82 } |
83 | 83 |
84 return string16(); | 84 return base::string16(); |
85 } | 85 } |
86 | 86 |
87 bool IsModuleValidImageSection(HANDLE section, | 87 bool IsModuleValidImageSection(HANDLE section, |
88 PVOID *base, | 88 PVOID *base, |
89 PLARGE_INTEGER offset, | 89 PLARGE_INTEGER offset, |
90 PSIZE_T view_size) { | 90 PSIZE_T view_size) { |
91 DCHECK_NT(g_nt_query_section_func); | 91 DCHECK_NT(g_nt_query_section_func); |
92 | 92 |
93 if (!section || !base || !view_size || offset) | 93 if (!section || !base || !view_size || offset) |
94 return false; | 94 return false; |
95 | 95 |
96 SECTION_BASIC_INFORMATION basic_info; | 96 SECTION_BASIC_INFORMATION basic_info; |
97 SIZE_T bytes_returned; | 97 SIZE_T bytes_returned; |
98 NTSTATUS ret = g_nt_query_section_func(section, SectionBasicInformation, | 98 NTSTATUS ret = g_nt_query_section_func(section, SectionBasicInformation, |
99 &basic_info, sizeof(basic_info), | 99 &basic_info, sizeof(basic_info), |
100 &bytes_returned); | 100 &bytes_returned); |
101 | 101 |
102 if (!NT_SUCCESS(ret) || sizeof(basic_info) != bytes_returned) | 102 if (!NT_SUCCESS(ret) || sizeof(basic_info) != bytes_returned) |
103 return false; | 103 return false; |
104 | 104 |
105 if (!(basic_info.Attributes & SEC_IMAGE)) | 105 if (!(basic_info.Attributes & SEC_IMAGE)) |
106 return false; | 106 return false; |
107 | 107 |
108 return true; | 108 return true; |
109 } | 109 } |
110 | 110 |
111 string16 ExtractLoadedModuleName(const string16& module_path) { | 111 base::string16 ExtractLoadedModuleName(const base::string16& module_path) { |
112 if (module_path.empty() || module_path[module_path.size() - 1] == L'\\') | 112 if (module_path.empty() || module_path[module_path.size() - 1] == L'\\') |
113 return string16(); | 113 return base::string16(); |
114 | 114 |
115 size_t sep = module_path.find_last_of(L'\\'); | 115 size_t sep = module_path.find_last_of(L'\\'); |
116 if (sep == string16::npos) | 116 if (sep == base::string16::npos) |
117 return module_path; | 117 return module_path; |
118 else | 118 else |
119 return module_path.substr(sep+1); | 119 return module_path.substr(sep+1); |
120 } | 120 } |
121 | 121 |
122 // Fills |out_name| with the image name from the given |pe| image and |flags| | 122 // Fills |out_name| with the image name from the given |pe| image and |flags| |
123 // with additional info about the image. | 123 // with additional info about the image. |
124 void SafeGetImageInfo(const base::win::PEImage& pe, | 124 void SafeGetImageInfo(const base::win::PEImage& pe, |
125 std::string* out_name, | 125 std::string* out_name, |
126 uint32* flags) { | 126 uint32* flags) { |
(...skipping 20 matching lines...) Expand all Loading... |
147 if (headers->OptionalHeader.SizeOfCode) | 147 if (headers->OptionalHeader.SizeOfCode) |
148 *flags |= sandbox::MODULE_HAS_CODE; | 148 *flags |= sandbox::MODULE_HAS_CODE; |
149 } | 149 } |
150 } | 150 } |
151 } __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? | 151 } __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? |
152 EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { | 152 EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { |
153 out_name->clear(); | 153 out_name->clear(); |
154 } | 154 } |
155 } | 155 } |
156 | 156 |
157 string16 GetImageInfoFromLoadedModule(HMODULE module, uint32* flags) { | 157 base::string16 GetImageInfoFromLoadedModule(HMODULE module, uint32* flags) { |
158 std::string out_name; | 158 std::string out_name; |
159 base::win::PEImage pe(module); | 159 base::win::PEImage pe(module); |
160 SafeGetImageInfo(pe, &out_name, flags); | 160 SafeGetImageInfo(pe, &out_name, flags); |
161 return string16(out_name.begin(), out_name.end()); | 161 return base::string16(out_name.begin(), out_name.end()); |
162 } | 162 } |
163 | 163 |
164 } // namespace | 164 } // namespace |
165 | 165 |
166 namespace blacklist { | 166 namespace blacklist { |
167 | 167 |
168 bool InitializeInterceptImports() { | 168 bool InitializeInterceptImports() { |
169 g_nt_query_section_func = reinterpret_cast<NtQuerySectionFunction>( | 169 g_nt_query_section_func = reinterpret_cast<NtQuerySectionFunction>( |
170 GetNtDllExportByName("NtQuerySection")); | 170 GetNtDllExportByName("NtQuerySection")); |
171 g_nt_query_virtual_memory_func = | 171 g_nt_query_virtual_memory_func = |
(...skipping 25 matching lines...) Expand all Loading... |
197 | 197 |
198 if (!NT_SUCCESS(ret) || !sandbox::IsSameProcess(process) || | 198 if (!NT_SUCCESS(ret) || !sandbox::IsSameProcess(process) || |
199 !IsModuleValidImageSection(section, base, offset, view_size)) { | 199 !IsModuleValidImageSection(section, base, offset, view_size)) { |
200 return ret; | 200 return ret; |
201 } | 201 } |
202 | 202 |
203 HMODULE module = reinterpret_cast<HMODULE>(*base); | 203 HMODULE module = reinterpret_cast<HMODULE>(*base); |
204 if (module) { | 204 if (module) { |
205 UINT image_flags; | 205 UINT image_flags; |
206 | 206 |
207 string16 module_name(GetImageInfoFromLoadedModule( | 207 base::string16 module_name(GetImageInfoFromLoadedModule( |
208 reinterpret_cast<HMODULE>(*base), &image_flags)); | 208 reinterpret_cast<HMODULE>(*base), &image_flags)); |
209 string16 file_name(GetBackingModuleFilePath(*base)); | 209 base::string16 file_name(GetBackingModuleFilePath(*base)); |
210 | 210 |
211 if (module_name.empty() && (image_flags & sandbox::MODULE_HAS_CODE)) { | 211 if (module_name.empty() && (image_flags & sandbox::MODULE_HAS_CODE)) { |
212 // If the module has no exports we retrieve the module name from the | 212 // If the module has no exports we retrieve the module name from the |
213 // full path of the mapped section. | 213 // full path of the mapped section. |
214 module_name = ExtractLoadedModuleName(file_name); | 214 module_name = ExtractLoadedModuleName(file_name); |
215 } | 215 } |
216 | 216 |
217 if (!module_name.empty() && DllMatch(module_name)) { | 217 if (!module_name.empty() && DllMatch(module_name)) { |
218 DCHECK_NT(g_nt_unmap_view_of_section_func); | 218 DCHECK_NT(g_nt_unmap_view_of_section_func); |
219 g_nt_unmap_view_of_section_func(process, *base); | 219 g_nt_unmap_view_of_section_func(process, *base); |
220 ret = STATUS_UNSUCCESSFUL; | 220 ret = STATUS_UNSUCCESSFUL; |
221 } | 221 } |
222 | 222 |
223 } | 223 } |
224 return ret; | 224 return ret; |
225 } | 225 } |
226 | 226 |
227 } // namespace blacklist | 227 } // namespace blacklist |
OLD | NEW |