Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(683)

Unified Diff: sandbox/win/src/win_utils_unittest.cc

Issue 2323443003: Implement new method to get process base address in Windows sandbox. (Closed)
Patch Set: Remove redundant close handle call Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sandbox/win/src/win_utils_unittest.cc
diff --git a/sandbox/win/src/win_utils_unittest.cc b/sandbox/win/src/win_utils_unittest.cc
index 7500798102a8c76fbb2b7e1bcc8a478880abc825..9ecca28bbb52e6a6aa81c72c1f2a5060ccebe95d 100644
--- a/sandbox/win/src/win_utils_unittest.cc
+++ b/sandbox/win/src/win_utils_unittest.cc
@@ -3,8 +3,13 @@
// found in the LICENSE file.
#include <windows.h>
+#include <psapi.h>
+#include <vector>
+
+#include "base/numerics/safe_conversions.h"
#include "base/win/scoped_handle.h"
+#include "base/win/scoped_process_information.h"
#include "sandbox/win/src/nt_internals.h"
#include "sandbox/win/src/win_utils.h"
#include "sandbox/win/tests/common/test_utils.h"
@@ -122,3 +127,83 @@ TEST(WinUtils, NtStatusToWin32Error) {
EXPECT_EQ(static_cast<DWORD>(ERROR_ACCESS_DENIED),
GetLastErrorFromNtStatus(STATUS_ACCESS_DENIED));
}
+
+class ScopedTerminateProcess {
Will Harris 2016/09/08 16:54:03 I wonder if this should be in the anonymous namesp
+ public:
+ ScopedTerminateProcess(HANDLE process) : process_(process) {}
+
+ ~ScopedTerminateProcess() {
+ ::TerminateProcess(process_, 0);
+ }
+
+ private:
+ HANDLE process_;
+};
+
+static bool GetModuleList(HANDLE process, std::vector<HMODULE>* result) {
+ std::vector<HMODULE> modules(256);
+ DWORD size_needed = 0;
+ if (EnumProcessModules(
+ process, &modules[0],
+ base::checked_cast<DWORD>(modules.size() * sizeof(HMODULE)),
+ &size_needed)) {
+ result->assign(modules.begin(),
+ modules.begin() + (size_needed / sizeof(HMODULE)));
+ return true;
+ }
+ modules.resize(size_needed / sizeof(HMODULE));
+ if (EnumProcessModules(
+ process, &modules[0],
+ base::checked_cast<DWORD>(modules.size() * sizeof(HMODULE)),
+ &size_needed)) {
+ result->assign(modules.begin(),
+ modules.begin() + (size_needed / sizeof(HMODULE)));
+ return true;
+ }
+ return false;
+}
+
+TEST(WinUtils, GetProcessBaseAddress) {
+ using sandbox::GetProcessBaseAddress;
+ STARTUPINFO start_info = {};
+ PROCESS_INFORMATION proc_info = {};
+ WCHAR command_line[] = L"notepad";
+ start_info.cb = sizeof(start_info);
+ start_info.dwFlags = STARTF_USESHOWWINDOW;
+ start_info.wShowWindow = SW_HIDE;
+ EXPECT_TRUE(::CreateProcessW(nullptr, command_line, nullptr, nullptr, FALSE,
+ CREATE_SUSPENDED, nullptr, nullptr, &start_info,
+ &proc_info));
+ base::win::ScopedProcessInformation scoped_proc_info(proc_info);
+ ScopedTerminateProcess process_terminate(scoped_proc_info.process_handle());
+ void* base_address = GetProcessBaseAddress(scoped_proc_info.process_handle());
+ EXPECT_NE(nullptr, base_address);
+ EXPECT_NE(static_cast<DWORD>(-1),
+ ::ResumeThread(scoped_proc_info.thread_handle()));
+ ::WaitForInputIdle(scoped_proc_info.process_handle(), 1000);
+ EXPECT_NE(static_cast<DWORD>(-1),
+ ::SuspendThread(scoped_proc_info.thread_handle()));
+ // Check again, the process will have done some more memory initialization.
+ EXPECT_EQ(base_address,
+ GetProcessBaseAddress(scoped_proc_info.process_handle()));
+
+ std::vector<HMODULE> modules;
+ // Compare against the loader's module list (which should now be initialized).
+ // GetModuleList could fail if the target process hasn't fully initialized.
+ // If so skip this check and log it as a warning.
+ if (GetModuleList(scoped_proc_info.process_handle(), &modules) &&
+ modules.size() > 0) {
+ // First module should be the main executable.
+ EXPECT_EQ(base_address, modules[0]);
+ } else {
+ LOG(WARNING) << "Couldn't test base address against module list";
+ }
+ // Fill in some of the virtual memory with 10MiB chunks and try again.
+ for (int count = 0; count < 100; ++count) {
+ EXPECT_NE(nullptr,
+ ::VirtualAllocEx(scoped_proc_info.process_handle(), nullptr,
+ 10 * 1024 * 1024, MEM_RESERVE, PAGE_NOACCESS));
+ }
+ EXPECT_EQ(base_address,
+ GetProcessBaseAddress(scoped_proc_info.process_handle()));
+}

Powered by Google App Engine
This is Rietveld 408576698