Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include <windows.h> | 5 #include <windows.h> |
| 6 #include <psapi.h> | |
| 6 | 7 |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/numerics/safe_conversions.h" | |
| 7 #include "base/win/scoped_handle.h" | 11 #include "base/win/scoped_handle.h" |
| 12 #include "base/win/scoped_process_information.h" | |
| 8 #include "sandbox/win/src/nt_internals.h" | 13 #include "sandbox/win/src/nt_internals.h" |
| 9 #include "sandbox/win/src/win_utils.h" | 14 #include "sandbox/win/src/win_utils.h" |
| 10 #include "sandbox/win/tests/common/test_utils.h" | 15 #include "sandbox/win/tests/common/test_utils.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 12 | 17 |
| 13 TEST(WinUtils, IsReparsePoint) { | 18 TEST(WinUtils, IsReparsePoint) { |
| 14 using sandbox::IsReparsePoint; | 19 using sandbox::IsReparsePoint; |
| 15 | 20 |
| 16 // Create a temp file because we need write access to it. | 21 // Create a temp file because we need write access to it. |
| 17 wchar_t temp_directory[MAX_PATH]; | 22 wchar_t temp_directory[MAX_PATH]; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 using sandbox::GetLastErrorFromNtStatus; | 120 using sandbox::GetLastErrorFromNtStatus; |
| 116 EXPECT_EQ(static_cast<DWORD>(ERROR_SUCCESS), | 121 EXPECT_EQ(static_cast<DWORD>(ERROR_SUCCESS), |
| 117 GetLastErrorFromNtStatus(STATUS_SUCCESS)); | 122 GetLastErrorFromNtStatus(STATUS_SUCCESS)); |
| 118 EXPECT_EQ(static_cast<DWORD>(ERROR_NOT_SUPPORTED), | 123 EXPECT_EQ(static_cast<DWORD>(ERROR_NOT_SUPPORTED), |
| 119 GetLastErrorFromNtStatus(STATUS_NOT_SUPPORTED)); | 124 GetLastErrorFromNtStatus(STATUS_NOT_SUPPORTED)); |
| 120 EXPECT_EQ(static_cast<DWORD>(ERROR_ALREADY_EXISTS), | 125 EXPECT_EQ(static_cast<DWORD>(ERROR_ALREADY_EXISTS), |
| 121 GetLastErrorFromNtStatus(STATUS_OBJECT_NAME_COLLISION)); | 126 GetLastErrorFromNtStatus(STATUS_OBJECT_NAME_COLLISION)); |
| 122 EXPECT_EQ(static_cast<DWORD>(ERROR_ACCESS_DENIED), | 127 EXPECT_EQ(static_cast<DWORD>(ERROR_ACCESS_DENIED), |
| 123 GetLastErrorFromNtStatus(STATUS_ACCESS_DENIED)); | 128 GetLastErrorFromNtStatus(STATUS_ACCESS_DENIED)); |
| 124 } | 129 } |
| 130 | |
| 131 class ScopedTerminateProcess { | |
|
Will Harris
2016/09/08 16:54:03
I wonder if this should be in the anonymous namesp
| |
| 132 public: | |
| 133 ScopedTerminateProcess(HANDLE process) : process_(process) {} | |
| 134 | |
| 135 ~ScopedTerminateProcess() { | |
| 136 ::TerminateProcess(process_, 0); | |
| 137 } | |
| 138 | |
| 139 private: | |
| 140 HANDLE process_; | |
| 141 }; | |
| 142 | |
| 143 static bool GetModuleList(HANDLE process, std::vector<HMODULE>* result) { | |
| 144 std::vector<HMODULE> modules(256); | |
| 145 DWORD size_needed = 0; | |
| 146 if (EnumProcessModules( | |
| 147 process, &modules[0], | |
| 148 base::checked_cast<DWORD>(modules.size() * sizeof(HMODULE)), | |
| 149 &size_needed)) { | |
| 150 result->assign(modules.begin(), | |
| 151 modules.begin() + (size_needed / sizeof(HMODULE))); | |
| 152 return true; | |
| 153 } | |
| 154 modules.resize(size_needed / sizeof(HMODULE)); | |
| 155 if (EnumProcessModules( | |
| 156 process, &modules[0], | |
| 157 base::checked_cast<DWORD>(modules.size() * sizeof(HMODULE)), | |
| 158 &size_needed)) { | |
| 159 result->assign(modules.begin(), | |
| 160 modules.begin() + (size_needed / sizeof(HMODULE))); | |
| 161 return true; | |
| 162 } | |
| 163 return false; | |
| 164 } | |
| 165 | |
| 166 TEST(WinUtils, GetProcessBaseAddress) { | |
| 167 using sandbox::GetProcessBaseAddress; | |
| 168 STARTUPINFO start_info = {}; | |
| 169 PROCESS_INFORMATION proc_info = {}; | |
| 170 WCHAR command_line[] = L"notepad"; | |
| 171 start_info.cb = sizeof(start_info); | |
| 172 start_info.dwFlags = STARTF_USESHOWWINDOW; | |
| 173 start_info.wShowWindow = SW_HIDE; | |
| 174 EXPECT_TRUE(::CreateProcessW(nullptr, command_line, nullptr, nullptr, FALSE, | |
| 175 CREATE_SUSPENDED, nullptr, nullptr, &start_info, | |
| 176 &proc_info)); | |
| 177 base::win::ScopedProcessInformation scoped_proc_info(proc_info); | |
| 178 ScopedTerminateProcess process_terminate(scoped_proc_info.process_handle()); | |
| 179 void* base_address = GetProcessBaseAddress(scoped_proc_info.process_handle()); | |
| 180 EXPECT_NE(nullptr, base_address); | |
| 181 EXPECT_NE(static_cast<DWORD>(-1), | |
| 182 ::ResumeThread(scoped_proc_info.thread_handle())); | |
| 183 ::WaitForInputIdle(scoped_proc_info.process_handle(), 1000); | |
| 184 EXPECT_NE(static_cast<DWORD>(-1), | |
| 185 ::SuspendThread(scoped_proc_info.thread_handle())); | |
| 186 // Check again, the process will have done some more memory initialization. | |
| 187 EXPECT_EQ(base_address, | |
| 188 GetProcessBaseAddress(scoped_proc_info.process_handle())); | |
| 189 | |
| 190 std::vector<HMODULE> modules; | |
| 191 // Compare against the loader's module list (which should now be initialized). | |
| 192 // GetModuleList could fail if the target process hasn't fully initialized. | |
| 193 // If so skip this check and log it as a warning. | |
| 194 if (GetModuleList(scoped_proc_info.process_handle(), &modules) && | |
| 195 modules.size() > 0) { | |
| 196 // First module should be the main executable. | |
| 197 EXPECT_EQ(base_address, modules[0]); | |
| 198 } else { | |
| 199 LOG(WARNING) << "Couldn't test base address against module list"; | |
| 200 } | |
| 201 // Fill in some of the virtual memory with 10MiB chunks and try again. | |
| 202 for (int count = 0; count < 100; ++count) { | |
| 203 EXPECT_NE(nullptr, | |
| 204 ::VirtualAllocEx(scoped_proc_info.process_handle(), nullptr, | |
| 205 10 * 1024 * 1024, MEM_RESERVE, PAGE_NOACCESS)); | |
| 206 } | |
| 207 EXPECT_EQ(base_address, | |
| 208 GetProcessBaseAddress(scoped_proc_info.process_handle())); | |
| 209 } | |
| OLD | NEW |