| 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 |