summaryrefslogtreecommitdiffstats
path: root/sandbox/win/src
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-13 20:49:23 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-13 20:49:23 +0000
commite628fde3462899ba06af2fbc5285563c456ed5c4 (patch)
treee3ed3eb98c0044b055606bdf8628191b9b99c17c /sandbox/win/src
parent23d6315575647756c4be985b895ec2c447e2f088 (diff)
downloadchromium_src-e628fde3462899ba06af2fbc5285563c456ed5c4.zip
chromium_src-e628fde3462899ba06af2fbc5285563c456ed5c4.tar.gz
chromium_src-e628fde3462899ba06af2fbc5285563c456ed5c4.tar.bz2
Emergency revert; rietveld broke; tree broke
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146646 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/win/src')
-rw-r--r--sandbox/win/src/Wow64.cc219
-rw-r--r--sandbox/win/src/Wow64.h50
-rw-r--r--sandbox/win/src/Wow64_64.cc18
-rw-r--r--sandbox/win/src/acl.cc122
-rw-r--r--sandbox/win/src/acl.h41
-rw-r--r--sandbox/win/src/broker_services.cc405
-rw-r--r--sandbox/win/src/broker_services.h113
-rw-r--r--sandbox/win/src/crosscall_client.h483
-rw-r--r--sandbox/win/src/crosscall_params.h293
-rw-r--r--sandbox/win/src/crosscall_server.cc283
-rw-r--r--sandbox/win/src/crosscall_server.h224
-rw-r--r--sandbox/win/src/dep.cc89
-rw-r--r--sandbox/win/src/dep.h25
-rw-r--r--sandbox/win/src/dep_test.cc158
-rw-r--r--sandbox/win/src/eat_resolver.cc89
-rw-r--r--sandbox/win/src/eat_resolver.h48
-rw-r--r--sandbox/win/src/file_policy_test.cc598
-rw-r--r--sandbox/win/src/filesystem_dispatcher.cc297
-rw-r--r--sandbox/win/src/filesystem_dispatcher.h57
-rw-r--r--sandbox/win/src/filesystem_interception.cc351
-rw-r--r--sandbox/win/src/filesystem_interception.h53
-rw-r--r--sandbox/win/src/filesystem_policy.cc387
-rw-r--r--sandbox/win/src/filesystem_policy.h107
-rw-r--r--sandbox/win/src/handle_closer.cc201
-rw-r--r--sandbox/win/src/handle_closer.h75
-rw-r--r--sandbox/win/src/handle_closer_agent.cc145
-rw-r--r--sandbox/win/src/handle_closer_agent.h37
-rw-r--r--sandbox/win/src/handle_closer_test.cc194
-rw-r--r--sandbox/win/src/handle_dispatcher.cc90
-rw-r--r--sandbox/win/src/handle_dispatcher.h37
-rw-r--r--sandbox/win/src/handle_interception.cc45
-rw-r--r--sandbox/win/src/handle_interception.h24
-rw-r--r--sandbox/win/src/handle_policy.cc94
-rw-r--r--sandbox/win/src/handle_policy.h41
-rw-r--r--sandbox/win/src/handle_policy_test.cc114
-rw-r--r--sandbox/win/src/handle_table.cc181
-rw-r--r--sandbox/win/src/handle_table.h159
-rw-r--r--sandbox/win/src/integrity_level_test.cc90
-rw-r--r--sandbox/win/src/interception.cc551
-rw-r--r--sandbox/win/src/interception.h272
-rw-r--r--sandbox/win/src/interception_agent.cc233
-rw-r--r--sandbox/win/src/interception_agent.h87
-rw-r--r--sandbox/win/src/interception_internal.h76
-rw-r--r--sandbox/win/src/interception_unittest.cc212
-rw-r--r--sandbox/win/src/interceptors.h54
-rw-r--r--sandbox/win/src/interceptors_64.cc268
-rw-r--r--sandbox/win/src/interceptors_64.h169
-rw-r--r--sandbox/win/src/internal_types.h75
-rw-r--r--sandbox/win/src/ipc_ping_test.cc58
-rw-r--r--sandbox/win/src/ipc_tags.h37
-rw-r--r--sandbox/win/src/ipc_unittest.cc641
-rw-r--r--sandbox/win/src/job.cc116
-rw-r--r--sandbox/win/src/job.h62
-rw-r--r--sandbox/win/src/job_unittest.cc189
-rw-r--r--sandbox/win/src/named_pipe_dispatcher.cc66
-rw-r--r--sandbox/win/src/named_pipe_dispatcher.h37
-rw-r--r--sandbox/win/src/named_pipe_interception.cc72
-rw-r--r--sandbox/win/src/named_pipe_interception.h36
-rw-r--r--sandbox/win/src/named_pipe_policy.cc86
-rw-r--r--sandbox/win/src/named_pipe_policy.h45
-rw-r--r--sandbox/win/src/named_pipe_policy_test.cc78
-rw-r--r--sandbox/win/src/nt_internals.h611
-rw-r--r--sandbox/win/src/policy_broker.cc118
-rw-r--r--sandbox/win/src/policy_broker.h23
-rw-r--r--sandbox/win/src/policy_engine_opcodes.cc454
-rw-r--r--sandbox/win/src/policy_engine_opcodes.h380
-rw-r--r--sandbox/win/src/policy_engine_params.h202
-rw-r--r--sandbox/win/src/policy_engine_processor.cc107
-rw-r--r--sandbox/win/src/policy_engine_processor.h145
-rw-r--r--sandbox/win/src/policy_engine_unittest.cc102
-rw-r--r--sandbox/win/src/policy_low_level.cc348
-rw-r--r--sandbox/win/src/policy_low_level.h182
-rw-r--r--sandbox/win/src/policy_low_level_unittest.cc575
-rw-r--r--sandbox/win/src/policy_opcodes_unittest.cc344
-rw-r--r--sandbox/win/src/policy_params.h64
-rw-r--r--sandbox/win/src/policy_target.cc127
-rw-r--r--sandbox/win/src/policy_target.h45
-rw-r--r--sandbox/win/src/policy_target_test.cc337
-rw-r--r--sandbox/win/src/process_policy_test.cc295
-rw-r--r--sandbox/win/src/process_thread_dispatcher.cc245
-rw-r--r--sandbox/win/src/process_thread_dispatcher.h47
-rw-r--r--sandbox/win/src/process_thread_interception.cc447
-rw-r--r--sandbox/win/src/process_thread_interception.h101
-rw-r--r--sandbox/win/src/process_thread_policy.cc242
-rw-r--r--sandbox/win/src/process_thread_policy.h82
-rw-r--r--sandbox/win/src/registry_dispatcher.cc161
-rw-r--r--sandbox/win/src/registry_dispatcher.h39
-rw-r--r--sandbox/win/src/registry_interception.cc176
-rw-r--r--sandbox/win/src/registry_interception.h38
-rw-r--r--sandbox/win/src/registry_policy.cc227
-rw-r--r--sandbox/win/src/registry_policy.h57
-rw-r--r--sandbox/win/src/registry_policy_test.cc289
-rw-r--r--sandbox/win/src/resolver.cc62
-rw-r--r--sandbox/win/src/resolver.h105
-rw-r--r--sandbox/win/src/resolver_32.cc88
-rw-r--r--sandbox/win/src/resolver_64.cc69
-rw-r--r--sandbox/win/src/restricted_token.cc466
-rw-r--r--sandbox/win/src/restricted_token.h198
-rw-r--r--sandbox/win/src/restricted_token_unittest.cc530
-rw-r--r--sandbox/win/src/restricted_token_utils.cc344
-rw-r--r--sandbox/win/src/restricted_token_utils.h83
-rw-r--r--sandbox/win/src/sandbox.cc51
-rw-r--r--sandbox/win/src/sandbox.h156
-rw-r--r--sandbox/win/src/sandbox.vcproj658
-rw-r--r--sandbox/win/src/sandbox_factory.h50
-rw-r--r--sandbox/win/src/sandbox_nt_types.h46
-rw-r--r--sandbox/win/src/sandbox_nt_util.cc599
-rw-r--r--sandbox/win/src/sandbox_nt_util.h173
-rw-r--r--sandbox/win/src/sandbox_policy.h190
-rw-r--r--sandbox/win/src/sandbox_policy_base.cc542
-rw-r--r--sandbox/win/src/sandbox_policy_base.h139
-rw-r--r--sandbox/win/src/sandbox_types.h81
-rw-r--r--sandbox/win/src/sandbox_utils.cc79
-rw-r--r--sandbox/win/src/sandbox_utils.h38
-rw-r--r--sandbox/win/src/security_level.h127
-rw-r--r--sandbox/win/src/service_resolver.cc42
-rw-r--r--sandbox/win/src/service_resolver.h148
-rw-r--r--sandbox/win/src/service_resolver_32.cc424
-rw-r--r--sandbox/win/src/service_resolver_64.cc193
-rw-r--r--sandbox/win/src/service_resolver_unittest.cc227
-rw-r--r--sandbox/win/src/shared_handles.cc67
-rw-r--r--sandbox/win/src/shared_handles.h108
-rw-r--r--sandbox/win/src/sharedmem_ipc_client.cc152
-rw-r--r--sandbox/win/src/sharedmem_ipc_client.h136
-rw-r--r--sandbox/win/src/sharedmem_ipc_server.cc410
-rw-r--r--sandbox/win/src/sharedmem_ipc_server.h127
-rw-r--r--sandbox/win/src/sid.cc26
-rw-r--r--sandbox/win/src/sid.h29
-rw-r--r--sandbox/win/src/sid_unittest.cc71
-rw-r--r--sandbox/win/src/sidestep/ia32_modrm_map.cpp92
-rw-r--r--sandbox/win/src/sidestep/ia32_opcode_map.cpp1159
-rw-r--r--sandbox/win/src/sidestep/mini_disassembler.cpp395
-rw-r--r--sandbox/win/src/sidestep/mini_disassembler.h156
-rw-r--r--sandbox/win/src/sidestep/mini_disassembler_types.h197
-rw-r--r--sandbox/win/src/sidestep/preamble_patcher.h109
-rw-r--r--sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp179
-rw-r--r--sandbox/win/src/sidestep_resolver.cc200
-rw-r--r--sandbox/win/src/sidestep_resolver.h73
-rw-r--r--sandbox/win/src/sync_dispatcher.cc86
-rw-r--r--sandbox/win/src/sync_dispatcher.h38
-rw-r--r--sandbox/win/src/sync_interception.cc107
-rw-r--r--sandbox/win/src/sync_interception.h41
-rw-r--r--sandbox/win/src/sync_policy.cc114
-rw-r--r--sandbox/win/src/sync_policy.h51
-rw-r--r--sandbox/win/src/sync_policy_test.cc145
-rw-r--r--sandbox/win/src/target_interceptions.cc100
-rw-r--r--sandbox/win/src/target_interceptions.h35
-rw-r--r--sandbox/win/src/target_process.cc355
-rw-r--r--sandbox/win/src/target_process.h122
-rw-r--r--sandbox/win/src/target_services.cc188
-rw-r--r--sandbox/win/src/target_services.h71
-rw-r--r--sandbox/win/src/threadpool_unittest.cc94
-rw-r--r--sandbox/win/src/unload_dll_test.cc96
-rw-r--r--sandbox/win/src/win2k_threadpool.cc60
-rw-r--r--sandbox/win/src/win2k_threadpool.h58
-rw-r--r--sandbox/win/src/win_utils.cc323
-rw-r--r--sandbox/win/src/win_utils.h110
-rw-r--r--sandbox/win/src/win_utils_unittest.cc82
-rw-r--r--sandbox/win/src/window.cc142
-rw-r--r--sandbox/win/src/window.h39
160 files changed, 0 insertions, 28218 deletions
diff --git a/sandbox/win/src/Wow64.cc b/sandbox/win/src/Wow64.cc
deleted file mode 100644
index 39108e5..0000000
--- a/sandbox/win/src/Wow64.cc
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/wow64.h"
-
-#include <sstream>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/win/scoped_process_information.h"
-#include "base/win/windows_version.h"
-#include "sandbox/win/src/target_process.h"
-
-namespace {
-
-// Holds the information needed for the interception of NtMapViewOfSection on
-// 64 bits.
-// Warning: do not modify this definition without changing also the code on the
-// 64 bit helper process.
-struct PatchInfo32 {
- HANDLE dll_load; // Event to signal the broker.
- ULONG pad1;
- HANDLE continue_load; // Event to wait for the broker.
- ULONG pad2;
- HANDLE section; // First argument of the call.
- ULONG pad3;
- void* orig_MapViewOfSection;
- ULONG original_high;
- void* signal_and_wait;
- ULONG pad4;
- void* patch_location;
- ULONG patch_high;
-};
-
-// Size of the 64 bit service entry.
-const SIZE_T kServiceEntry64Size = 0x10;
-
-// Removes the interception of ntdll64.
-bool Restore64Code(HANDLE child, PatchInfo32* patch_info) {
- PatchInfo32 local_patch_info;
- SIZE_T actual;
- if (!::ReadProcessMemory(child, patch_info, &local_patch_info,
- sizeof(local_patch_info), &actual))
- return false;
- if (sizeof(local_patch_info) != actual)
- return false;
-
- if (local_patch_info.original_high)
- return false;
- if (local_patch_info.patch_high)
- return false;
-
- char buffer[kServiceEntry64Size];
-
- if (!::ReadProcessMemory(child, local_patch_info.orig_MapViewOfSection,
- &buffer, kServiceEntry64Size, &actual))
- return false;
- if (kServiceEntry64Size != actual)
- return false;
-
- if (!::WriteProcessMemory(child, local_patch_info.patch_location, &buffer,
- kServiceEntry64Size, &actual))
- return false;
- if (kServiceEntry64Size != actual)
- return false;
- return true;
-}
-
-typedef BOOL (WINAPI* IsWow64ProcessFunction)(HANDLE process, BOOL* wow64);
-
-} // namespace
-
-namespace sandbox {
-
-Wow64::~Wow64() {
- if (dll_load_)
- ::CloseHandle(dll_load_);
-
- if (continue_load_)
- ::CloseHandle(continue_load_);
-}
-
-// The basic idea is to allocate one page of memory on the child, and initialize
-// the first part of it with our version of PatchInfo32. Then launch the helper
-// process passing it that address on the child. The helper process will patch
-// the 64 bit version of NtMapViewOfFile, and the interception will signal the
-// first event on the buffer. We'll be waiting on that event and after the 32
-// bit version of ntdll is loaded, we'll remove the interception and return to
-// our caller.
-bool Wow64::WaitForNtdll() {
- if (base::win::OSInfo::GetInstance()->wow64_status() !=
- base::win::OSInfo::WOW64_ENABLED)
- return true;
-
- const size_t page_size = 4096;
-
- // Create some default manual reset un-named events, not signaled.
- dll_load_ = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- continue_load_ = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- HANDLE current_process = ::GetCurrentProcess();
- HANDLE remote_load, remote_continue;
- DWORD access = EVENT_MODIFY_STATE | SYNCHRONIZE;
- if (!::DuplicateHandle(current_process, dll_load_, child_->Process(),
- &remote_load, access, FALSE, 0))
- return false;
- if (!::DuplicateHandle(current_process, continue_load_, child_->Process(),
- &remote_continue, access, FALSE, 0))
- return false;
-
- void* buffer = ::VirtualAllocEx(child_->Process(), NULL, page_size,
- MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- DCHECK(buffer);
- if (!buffer)
- return false;
-
- PatchInfo32* patch_info = reinterpret_cast<PatchInfo32*>(buffer);
- PatchInfo32 local_patch_info = {0};
- local_patch_info.dll_load = remote_load;
- local_patch_info.continue_load = remote_continue;
- SIZE_T written;
- if (!::WriteProcessMemory(child_->Process(), patch_info, &local_patch_info,
- offsetof(PatchInfo32, section), &written))
- return false;
- if (offsetof(PatchInfo32, section) != written)
- return false;
-
- if (!RunWowHelper(buffer))
- return false;
-
- // The child is intercepted on 64 bit, go on and wait for our event.
- if (!DllMapped())
- return false;
-
- // The 32 bit version is available, cleanup the child.
- return Restore64Code(child_->Process(), patch_info);
-}
-
-bool Wow64::RunWowHelper(void* buffer) {
- COMPILE_ASSERT(sizeof(buffer) <= sizeof(DWORD), unsupported_64_bits);
-
- // Get the path to the helper (beside the exe).
- wchar_t prog_name[MAX_PATH];
- GetModuleFileNameW(NULL, prog_name, MAX_PATH);
- std::wstring path(prog_name);
- size_t name_pos = path.find_last_of(L"\\");
- if (std::wstring::npos == name_pos)
- return false;
- path.resize(name_pos + 1);
-
- std::wstringstream command;
- command << std::hex << std::showbase << L"\"" << path <<
- L"wow_helper.exe\" " << child_->ProcessId() << " " <<
- bit_cast<ULONG>(buffer);
-
- scoped_ptr_malloc<wchar_t> writable_command(_wcsdup(command.str().c_str()));
-
- STARTUPINFO startup_info = {0};
- startup_info.cb = sizeof(startup_info);
- base::win::ScopedProcessInformation process_info;
- if (!::CreateProcess(NULL, writable_command.get(), NULL, NULL, FALSE, 0, NULL,
- NULL, &startup_info, process_info.Receive()))
- return false;
-
- DWORD reason = ::WaitForSingleObject(process_info.process_handle(), INFINITE);
-
- DWORD code;
- bool ok =
- ::GetExitCodeProcess(process_info.process_handle(), &code) ? true : false;
-
- if (WAIT_TIMEOUT == reason)
- return false;
-
- return ok && (0 == code);
-}
-
-// First we must wake up the child, then wait for dll loads on the child until
-// the one we care is loaded; at that point we must suspend the child again.
-bool Wow64::DllMapped() {
- if (1 != ::ResumeThread(child_->MainThread())) {
- NOTREACHED();
- return false;
- }
-
- for (;;) {
- DWORD reason = ::WaitForSingleObject(dll_load_, INFINITE);
- if (WAIT_TIMEOUT == reason || WAIT_ABANDONED == reason)
- return false;
-
- if (!::ResetEvent(dll_load_))
- return false;
-
- bool found = NtdllPresent();
- if (found) {
- if (::SuspendThread(child_->MainThread()))
- return false;
- }
-
- if (!::SetEvent(continue_load_))
- return false;
-
- if (found)
- return true;
- }
-}
-
-bool Wow64::NtdllPresent() {
- const size_t kBufferSize = 512;
- char buffer[kBufferSize];
- SIZE_T read;
- if (!::ReadProcessMemory(child_->Process(), ntdll_, &buffer, kBufferSize,
- &read))
- return false;
- if (kBufferSize != read)
- return false;
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/Wow64.h b/sandbox/win/src/Wow64.h
deleted file mode 100644
index e9bbd53..0000000
--- a/sandbox/win/src/Wow64.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_WOW64_H__
-#define SANDBOX_SRC_WOW64_H__
-
-#include <windows.h>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-namespace sandbox {
-
-class TargetProcess;
-
-// This class wraps the code needed to interact with the Windows On Windows
-// subsystem on 64 bit OSes, from the point of view of interceptions.
-class Wow64 {
- public:
- Wow64(TargetProcess* child, HMODULE ntdll)
- : child_(child), ntdll_(ntdll), dll_load_(NULL), continue_load_(NULL) {}
- ~Wow64();
-
- // Waits for the 32 bit DLL to get loaded on the child process. This function
- // will return immediately if not running under WOW, or launch the helper
- // process and wait until ntdll is ready.
- bool WaitForNtdll();
-
- private:
- // Runs the WOW helper process, passing the address of a buffer allocated on
- // the child (one page).
- bool RunWowHelper(void* buffer);
-
- // This method receives "notifications" whenever a DLL is mapped on the child.
- bool DllMapped();
-
- // Returns true if ntdll.dll is mapped on the child.
- bool NtdllPresent();
-
- TargetProcess* child_; // Child process.
- HMODULE ntdll_; // ntdll on the parent.
- HANDLE dll_load_; // Event that is signaled on dll load.
- HANDLE continue_load_; // Event to signal to continue execution on the child.
- DISALLOW_IMPLICIT_CONSTRUCTORS(Wow64);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_WOW64_H__
diff --git a/sandbox/win/src/Wow64_64.cc b/sandbox/win/src/Wow64_64.cc
deleted file mode 100644
index f03831b..0000000
--- a/sandbox/win/src/Wow64_64.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Wow64 implementation for native 64-bit Windows (in other words, never WOW).
-
-#include "sandbox/win/src/wow64.h"
-
-namespace sandbox {
-
-Wow64::~Wow64() {
-}
-
-bool Wow64::WaitForNtdll() {
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/acl.cc b/sandbox/win/src/acl.cc
deleted file mode 100644
index 70d2a8d..0000000
--- a/sandbox/win/src/acl.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/acl.h"
-
-#include <aclapi.h>
-#include <sddl.h>
-
-#include "base/logging.h"
-
-namespace sandbox {
-
-bool GetDefaultDacl(HANDLE token,
- scoped_ptr_malloc<TOKEN_DEFAULT_DACL>* default_dacl) {
- if (token == NULL)
- return false;
-
- DCHECK(default_dacl != NULL);
-
- unsigned long length = 0;
- ::GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &length);
- if (length == 0) {
- NOTREACHED();
- return false;
- }
-
- TOKEN_DEFAULT_DACL* acl =
- reinterpret_cast<TOKEN_DEFAULT_DACL*>(malloc(length));
- default_dacl->reset(acl);
-
- if (!::GetTokenInformation(token, TokenDefaultDacl, default_dacl->get(),
- length, &length))
- return false;
-
- return true;
-}
-
-bool AddSidToDacl(const Sid& sid, ACL* old_dacl, ACCESS_MASK access,
- ACL** new_dacl) {
- EXPLICIT_ACCESS new_access = {0};
- new_access.grfAccessMode = GRANT_ACCESS;
- new_access.grfAccessPermissions = access;
- new_access.grfInheritance = NO_INHERITANCE;
-
- new_access.Trustee.pMultipleTrustee = NULL;
- new_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
- new_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
- new_access.Trustee.ptstrName = reinterpret_cast<LPWSTR>(
- const_cast<SID*>(sid.GetPSID()));
-
- if (ERROR_SUCCESS != ::SetEntriesInAcl(1, &new_access, old_dacl, new_dacl))
- return false;
-
- return true;
-}
-
-bool AddSidToDefaultDacl(HANDLE token, const Sid& sid, ACCESS_MASK access) {
- if (token == NULL)
- return false;
-
- scoped_ptr_malloc<TOKEN_DEFAULT_DACL> default_dacl;
- if (!GetDefaultDacl(token, &default_dacl))
- return false;
-
- ACL* new_dacl = NULL;
- if (!AddSidToDacl(sid, default_dacl->DefaultDacl, access, &new_dacl))
- return false;
-
- TOKEN_DEFAULT_DACL new_token_dacl = {0};
- new_token_dacl.DefaultDacl = new_dacl;
-
- BOOL ret = ::SetTokenInformation(token, TokenDefaultDacl, &new_token_dacl,
- sizeof(new_token_dacl));
- ::LocalFree(new_dacl);
- return (TRUE == ret);
-}
-
-bool AddUserSidToDefaultDacl(HANDLE token, ACCESS_MASK access) {
- DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
- TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(malloc(size));
-
- scoped_ptr_malloc<TOKEN_USER> token_user_ptr(token_user);
-
- if (!::GetTokenInformation(token, TokenUser, token_user, size, &size))
- return false;
-
- return AddSidToDefaultDacl(token,
- reinterpret_cast<SID*>(token_user->User.Sid),
- access);
-}
-
-bool AddKnownSidToKernelObject(HANDLE object, const Sid& sid,
- ACCESS_MASK access) {
- PSECURITY_DESCRIPTOR descriptor = NULL;
- PACL old_dacl = NULL;
- PACL new_dacl = NULL;
-
- if (ERROR_SUCCESS != ::GetSecurityInfo(object, SE_KERNEL_OBJECT,
- DACL_SECURITY_INFORMATION, NULL, NULL,
- &old_dacl, NULL, &descriptor))
- return false;
-
- if (!AddSidToDacl(sid.GetPSID(), old_dacl, access, &new_dacl)) {
- ::LocalFree(descriptor);
- return false;
- }
-
- DWORD result = ::SetSecurityInfo(object, SE_KERNEL_OBJECT,
- DACL_SECURITY_INFORMATION, NULL, NULL,
- new_dacl, NULL);
-
- ::LocalFree(new_dacl);
- ::LocalFree(descriptor);
-
- if (ERROR_SUCCESS != result)
- return false;
-
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/acl.h b/sandbox/win/src/acl.h
deleted file mode 100644
index 25d5cdb..0000000
--- a/sandbox/win/src/acl.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_ACL_H_
-#define SANDBOX_SRC_ACL_H_
-
-#include <windows.h>
-
-#include "base/memory/scoped_ptr.h"
-#include "sandbox/win/src/sid.h"
-
-namespace sandbox {
-
-// Returns the default dacl from the token passed in.
-bool GetDefaultDacl(HANDLE token,
- scoped_ptr_malloc<TOKEN_DEFAULT_DACL>* default_dacl);
-
-// Appends an ACE represented by |sid| and |access| to |old_dacl|. If the
-// function succeeds, new_dacl contains the new dacl and must be freed using
-// LocalFree.
-bool AddSidToDacl(const Sid& sid, ACL* old_dacl, ACCESS_MASK access,
- ACL** new_dacl);
-
-// Adds and ACE represented by |sid| and |access| to the default dacl present
-// in the token.
-bool AddSidToDefaultDacl(HANDLE token, const Sid& sid, ACCESS_MASK access);
-
-// Adds an ACE represented by the user sid and |access| to the default dacl
-// present in the token.
-bool AddUserSidToDefaultDacl(HANDLE token, ACCESS_MASK access);
-
-// Adds an ACE represented by |known_sid| and |access| to the dacl of the kernel
-// object referenced by |object|.
-bool AddKnownSidToKernelObject(HANDLE object, const Sid& sid,
- ACCESS_MASK access);
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_ACL_H_
diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc
deleted file mode 100644
index 80837b3..0000000
--- a/sandbox/win/src/broker_services.cc
+++ /dev/null
@@ -1,405 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/broker_services.h"
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/threading/platform_thread.h"
-#include "base/win/scoped_handle.h"
-#include "base/win/scoped_process_information.h"
-#include "sandbox/win/src/sandbox_policy_base.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/target_process.h"
-#include "sandbox/win/src/win2k_threadpool.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace {
-
-// Utility function to associate a completion port to a job object.
-bool AssociateCompletionPort(HANDLE job, HANDLE port, void* key) {
- JOBOBJECT_ASSOCIATE_COMPLETION_PORT job_acp = { key, port };
- return ::SetInformationJobObject(job,
- JobObjectAssociateCompletionPortInformation,
- &job_acp, sizeof(job_acp))? true : false;
-}
-
-// Utility function to do the cleanup necessary when something goes wrong
-// while in SpawnTarget and we must terminate the target process.
-sandbox::ResultCode SpawnCleanup(sandbox::TargetProcess* target, DWORD error) {
- if (0 == error)
- error = ::GetLastError();
-
- target->Terminate();
- delete target;
- ::SetLastError(error);
- return sandbox::SBOX_ERROR_GENERIC;
-}
-
-// the different commands that you can send to the worker thread that
-// executes TargetEventsThread().
-enum {
- THREAD_CTRL_NONE,
- THREAD_CTRL_REMOVE_PEER,
- THREAD_CTRL_QUIT,
- THREAD_CTRL_LAST,
-};
-
-// Helper structure that allows the Broker to associate a job notification
-// with a job object and with a policy.
-struct JobTracker {
- HANDLE job;
- sandbox::PolicyBase* policy;
- JobTracker(HANDLE cjob, sandbox::PolicyBase* cpolicy)
- : job(cjob), policy(cpolicy) {
- }
-};
-
-// Helper structure that allows the broker to track peer processes
-struct PeerTracker {
- HANDLE wait_object;
- base::win::ScopedHandle process;
- DWORD id;
- HANDLE job_port;
- PeerTracker(DWORD process_id, HANDLE broker_job_port)
- : wait_object(NULL), id(process_id), job_port(broker_job_port) {
- }
-};
-
-void DeregisterPeerTracker(PeerTracker* peer) {
- // Deregistration shouldn't fail, but we leak rather than crash if it does.
- if (::UnregisterWaitEx(peer->wait_object, INVALID_HANDLE_VALUE)) {
- delete peer;
- } else {
- NOTREACHED();
- }
-}
-
-} // namespace
-
-namespace sandbox {
-
-BrokerServicesBase::BrokerServicesBase()
- : thread_pool_(NULL), job_port_(NULL), no_targets_(NULL),
- job_thread_(NULL) {
-}
-
-// The broker uses a dedicated worker thread that services the job completion
-// port to perform policy notifications and associated cleanup tasks.
-ResultCode BrokerServicesBase::Init() {
- if ((NULL != job_port_) || (NULL != thread_pool_))
- return SBOX_ERROR_UNEXPECTED_CALL;
-
- ::InitializeCriticalSection(&lock_);
-
- job_port_ = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
- if (NULL == job_port_)
- return SBOX_ERROR_GENERIC;
-
- no_targets_ = ::CreateEventW(NULL, TRUE, FALSE, NULL);
-
- job_thread_ = ::CreateThread(NULL, 0, // Default security and stack.
- TargetEventsThread, this, NULL, NULL);
- if (NULL == job_thread_)
- return SBOX_ERROR_GENERIC;
-
- return SBOX_ALL_OK;
-}
-
-// The destructor should only be called when the Broker process is terminating.
-// Since BrokerServicesBase is a singleton, this is called from the CRT
-// termination handlers, if this code lives on a DLL it is called during
-// DLL_PROCESS_DETACH in other words, holding the loader lock, so we cannot
-// wait for threads here.
-BrokerServicesBase::~BrokerServicesBase() {
- // If there is no port Init() was never called successfully.
- if (!job_port_)
- return;
-
- // Closing the port causes, that no more Job notifications are delivered to
- // the worker thread and also causes the thread to exit. This is what we
- // want to do since we are going to close all outstanding Jobs and notifying
- // the policy objects ourselves.
- ::PostQueuedCompletionStatus(job_port_, 0, THREAD_CTRL_QUIT, FALSE);
- ::CloseHandle(job_port_);
-
- if (WAIT_TIMEOUT == ::WaitForSingleObject(job_thread_, 1000)) {
- // Cannot clean broker services.
- NOTREACHED();
- return;
- }
-
- JobTrackerList::iterator it;
- for (it = tracker_list_.begin(); it != tracker_list_.end(); ++it) {
- JobTracker* tracker = (*it);
- FreeResources(tracker);
- delete tracker;
- }
- ::CloseHandle(job_thread_);
- delete thread_pool_;
- ::CloseHandle(no_targets_);
-
- // Cancel the wait events and delete remaining peer trackers.
- for (PeerTrackerMap::iterator it = peer_map_.begin();
- it != peer_map_.end(); ++it) {
- DeregisterPeerTracker(it->second);
- }
-
- // If job_port_ isn't NULL, assumes that the lock has been initialized.
- if (job_port_)
- ::DeleteCriticalSection(&lock_);
-}
-
-TargetPolicy* BrokerServicesBase::CreatePolicy() {
- // If you change the type of the object being created here you must also
- // change the downcast to it in SpawnTarget().
- return new PolicyBase;
-}
-
-void BrokerServicesBase::FreeResources(JobTracker* tracker) {
- if (NULL != tracker->policy) {
- BOOL res = ::TerminateJobObject(tracker->job, SBOX_ALL_OK);
- DCHECK(res);
- // Closing the job causes the target process to be destroyed so this
- // needs to happen before calling OnJobEmpty().
- res = ::CloseHandle(tracker->job);
- DCHECK(res);
- // In OnJobEmpty() we don't actually use the job handle directly.
- tracker->policy->OnJobEmpty(tracker->job);
- tracker->policy->Release();
- tracker->policy = NULL;
- }
-}
-
-// The worker thread stays in a loop waiting for asynchronous notifications
-// from the job objects. Right now we only care about knowing when the last
-// process on a job terminates, but in general this is the place to tell
-// the policy about events.
-DWORD WINAPI BrokerServicesBase::TargetEventsThread(PVOID param) {
- if (NULL == param)
- return 1;
-
- base::PlatformThread::SetName("BrokerEvent");
-
- BrokerServicesBase* broker = reinterpret_cast<BrokerServicesBase*>(param);
- HANDLE port = broker->job_port_;
- HANDLE no_targets = broker->no_targets_;
-
- int target_counter = 0;
- ::ResetEvent(no_targets);
-
- while (true) {
- DWORD events = 0;
- ULONG_PTR key = 0;
- LPOVERLAPPED ovl = NULL;
-
- if (!::GetQueuedCompletionStatus(port, &events, &key, &ovl, INFINITE))
- // this call fails if the port has been closed before we have a
- // chance to service the last packet which is 'exit' anyway so
- // this is not an error.
- return 1;
-
- if (key > THREAD_CTRL_LAST) {
- // The notification comes from a job object. There are nine notifications
- // that jobs can send and some of them depend on the job attributes set.
- JobTracker* tracker = reinterpret_cast<JobTracker*>(key);
-
- switch (events) {
- case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: {
- // The job object has signaled that the last process associated
- // with it has terminated. Assuming there is no way for a process
- // to appear out of thin air in this job, it safe to assume that
- // we can tell the policy to destroy the target object, and for
- // us to release our reference to the policy object.
- FreeResources(tracker);
- break;
- }
-
- case JOB_OBJECT_MSG_NEW_PROCESS: {
- ++target_counter;
- if (1 == target_counter) {
- ::ResetEvent(no_targets);
- }
- break;
- }
-
- case JOB_OBJECT_MSG_EXIT_PROCESS:
- case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: {
- {
- AutoLock lock(&broker->lock_);
- broker->child_process_ids_.erase(reinterpret_cast<DWORD>(ovl));
- }
- --target_counter;
- if (0 == target_counter)
- ::SetEvent(no_targets);
-
- DCHECK(target_counter >= 0);
- break;
- }
-
- case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT: {
- break;
- }
-
- default: {
- NOTREACHED();
- break;
- }
- }
- } else if (THREAD_CTRL_REMOVE_PEER == key) {
- // Remove a process from our list of peers.
- AutoLock lock(&broker->lock_);
- PeerTrackerMap::iterator it =
- broker->peer_map_.find(reinterpret_cast<DWORD>(ovl));
- DeregisterPeerTracker(it->second);
- broker->peer_map_.erase(it);
- } else if (THREAD_CTRL_QUIT == key) {
- // The broker object is being destroyed so the thread needs to exit.
- return 0;
- } else {
- // We have not implemented more commands.
- NOTREACHED();
- }
- }
-
- NOTREACHED();
- return 0;
-}
-
-// SpawnTarget does all the interesting sandbox setup and creates the target
-// process inside the sandbox.
-ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path,
- const wchar_t* command_line,
- TargetPolicy* policy,
- PROCESS_INFORMATION* target_info) {
- if (!exe_path)
- return SBOX_ERROR_BAD_PARAMS;
-
- if (!policy)
- return SBOX_ERROR_BAD_PARAMS;
-
- // Even though the resources touched by SpawnTarget can be accessed in
- // multiple threads, the method itself cannot be called from more than
- // 1 thread. This is to protect the global variables used while setting up
- // the child process.
- static DWORD thread_id = ::GetCurrentThreadId();
- DCHECK(thread_id == ::GetCurrentThreadId());
-
- AutoLock lock(&lock_);
-
- // This downcast is safe as long as we control CreatePolicy()
- PolicyBase* policy_base = static_cast<PolicyBase*>(policy);
-
- // Construct the tokens and the job object that we are going to associate
- // with the soon to be created target process.
- HANDLE initial_token_temp;
- HANDLE lockdown_token_temp;
- DWORD win_result = policy_base->MakeTokens(&initial_token_temp,
- &lockdown_token_temp);
- base::win::ScopedHandle initial_token(initial_token_temp);
- base::win::ScopedHandle lockdown_token(lockdown_token_temp);
-
- if (ERROR_SUCCESS != win_result)
- return SBOX_ERROR_GENERIC;
-
- HANDLE job_temp;
- win_result = policy_base->MakeJobObject(&job_temp);
- base::win::ScopedHandle job(job_temp);
- if (ERROR_SUCCESS != win_result)
- return SBOX_ERROR_GENERIC;
-
- if (ERROR_ALREADY_EXISTS == ::GetLastError())
- return SBOX_ERROR_GENERIC;
-
- // Construct the thread pool here in case it is expensive.
- // The thread pool is shared by all the targets
- if (NULL == thread_pool_)
- thread_pool_ = new Win2kThreadPool();
-
- // Create the TargetProces object and spawn the target suspended. Note that
- // Brokerservices does not own the target object. It is owned by the Policy.
- base::win::ScopedProcessInformation process_info;
- TargetProcess* target = new TargetProcess(initial_token.Take(),
- lockdown_token.Take(),
- job,
- thread_pool_);
-
- std::wstring desktop = policy_base->GetAlternateDesktop();
-
- win_result = target->Create(exe_path, command_line,
- desktop.empty() ? NULL : desktop.c_str(),
- &process_info);
- if (ERROR_SUCCESS != win_result)
- return SpawnCleanup(target, win_result);
-
- // Now the policy is the owner of the target.
- if (!policy_base->AddTarget(target)) {
- return SpawnCleanup(target, 0);
- }
-
- // We are going to keep a pointer to the policy because we'll call it when
- // the job object generates notifications using the completion port.
- policy_base->AddRef();
- scoped_ptr<JobTracker> tracker(new JobTracker(job.Take(), policy_base));
- if (!AssociateCompletionPort(tracker->job, job_port_, tracker.get()))
- return SpawnCleanup(target, 0);
- // Save the tracker because in cleanup we might need to force closing
- // the Jobs.
- tracker_list_.push_back(tracker.release());
- child_process_ids_.insert(process_info.process_id());
-
- *target_info = process_info.Take();
- return SBOX_ALL_OK;
-}
-
-
-ResultCode BrokerServicesBase::WaitForAllTargets() {
- ::WaitForSingleObject(no_targets_, INFINITE);
- return SBOX_ALL_OK;
-}
-
-bool BrokerServicesBase::IsActiveTarget(DWORD process_id) {
- AutoLock lock(&lock_);
- return child_process_ids_.find(process_id) != child_process_ids_.end() ||
- peer_map_.find(process_id) != peer_map_.end();
-}
-
-VOID CALLBACK BrokerServicesBase::RemovePeer(PVOID parameter, BOOLEAN timeout) {
- PeerTracker* peer = reinterpret_cast<PeerTracker*>(parameter);
- // Don't check the return code because we this may fail (safely) at shutdown.
- ::PostQueuedCompletionStatus(peer->job_port, 0, THREAD_CTRL_REMOVE_PEER,
- reinterpret_cast<LPOVERLAPPED>(peer->id));
-}
-
-ResultCode BrokerServicesBase::AddTargetPeer(HANDLE peer_process) {
- scoped_ptr<PeerTracker> peer(new PeerTracker(::GetProcessId(peer_process),
- job_port_));
- if (!peer->id)
- return SBOX_ERROR_GENERIC;
-
- HANDLE process_handle;
- if (!::DuplicateHandle(::GetCurrentProcess(), peer_process,
- ::GetCurrentProcess(), &process_handle,
- SYNCHRONIZE, FALSE, 0)) {
- return SBOX_ERROR_GENERIC;
- }
- peer->process.Set(process_handle);
-
- AutoLock lock(&lock_);
- if (!peer_map_.insert(std::make_pair(peer->id, peer.get())).second)
- return SBOX_ERROR_BAD_PARAMS;
-
- if (!::RegisterWaitForSingleObject(
- &peer->wait_object, peer->process, RemovePeer, peer.get(), INFINITE,
- WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD)) {
- peer_map_.erase(peer->id);
- return SBOX_ERROR_GENERIC;
- }
-
- // Release the pointer since it will be cleaned up by the callback.
- peer.release();
- return SBOX_ALL_OK;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/broker_services.h b/sandbox/win/src/broker_services.h
deleted file mode 100644
index 0455dca..0000000
--- a/sandbox/win/src/broker_services.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_BROKER_SERVICES_H__
-#define SANDBOX_SRC_BROKER_SERVICES_H__
-
-#include <list>
-#include <map>
-#include <set>
-#include "base/basictypes.h"
-#include "base/win/scoped_handle.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/job.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sharedmem_ipc_server.h"
-#include "sandbox/win/src/win2k_threadpool.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace {
-
-struct JobTracker;
-struct PeerTracker;
-
-} // namespace
-
-namespace sandbox {
-
-class PolicyBase;
-
-// BrokerServicesBase ---------------------------------------------------------
-// Broker implementation version 0
-//
-// This is an implementation of the interface BrokerServices and
-// of the associated TargetProcess interface. In this implementation
-// TargetProcess is a friend of BrokerServices where the later manages a
-// collection of the former.
-class BrokerServicesBase : public BrokerServices,
- public SingletonBase<BrokerServicesBase> {
- public:
- BrokerServicesBase();
-
- ~BrokerServicesBase();
-
- // The next five methods are the BrokerServices interface
- virtual ResultCode Init();
-
- virtual TargetPolicy* CreatePolicy();
-
- virtual ResultCode SpawnTarget(const wchar_t* exe_path,
- const wchar_t* command_line,
- TargetPolicy* policy,
- PROCESS_INFORMATION* target);
-
- virtual ResultCode WaitForAllTargets();
-
- virtual ResultCode AddTargetPeer(HANDLE peer_process);
-
- // Checks if the supplied process ID matches one of the broker's active
- // target processes
- // Returns:
- // true if there is an active target process for this ID, otherwise false.
- bool IsActiveTarget(DWORD process_id);
-
- private:
- // Releases the Job and notifies the associated Policy object to its
- // resources as well.
- static void FreeResources(JobTracker* tracker);
-
- // The routine that the worker thread executes. It is in charge of
- // notifications and cleanup-related tasks.
- static DWORD WINAPI TargetEventsThread(PVOID param);
-
- // Removes a target peer from the process list if it expires.
- static VOID CALLBACK RemovePeer(PVOID parameter, BOOLEAN timeout);
-
- // The completion port used by the job objects to communicate events to
- // the worker thread.
- HANDLE job_port_;
-
- // Handle to a manual-reset event that is signaled when the total target
- // process count reaches zero.
- HANDLE no_targets_;
-
- // Handle to the worker thread that reacts to job notifications.
- HANDLE job_thread_;
-
- // Lock used to protect the list of targets from being modified by 2
- // threads at the same time.
- CRITICAL_SECTION lock_;
-
- // provides a pool of threads that are used to wait on the IPC calls.
- ThreadProvider* thread_pool_;
-
- // List of the trackers for closing and cleanup purposes.
- typedef std::list<JobTracker*> JobTrackerList;
- JobTrackerList tracker_list_;
-
- // Maps peer process IDs to the saved handle and wait event.
- // Prevents peer callbacks from accessing the broker after destruction.
- typedef std::map<DWORD, PeerTracker*> PeerTrackerMap;
- PeerTrackerMap peer_map_;
-
- // Provides a fast lookup to identify sandboxed processes.
- std::set<DWORD> child_process_ids_;
-
- DISALLOW_COPY_AND_ASSIGN(BrokerServicesBase);
-};
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_BROKER_SERVICES_H__
diff --git a/sandbox/win/src/crosscall_client.h b/sandbox/win/src/crosscall_client.h
deleted file mode 100644
index 2715f96..0000000
--- a/sandbox/win/src/crosscall_client.h
+++ /dev/null
@@ -1,483 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_CROSSCALL_CLIENT_H_
-#define SANDBOX_SRC_CROSSCALL_CLIENT_H_
-
-#include "sandbox/win/src/crosscall_params.h"
-#include "sandbox/win/src/sandbox.h"
-
-// This header defines the CrossCall(..) family of templated functions
-// Their purpose is to simulate the syntax of regular call but to generate
-// and IPC from the client-side.
-//
-// The basic pattern is to
-// 1) use template argument deduction to compute the size of each
-// parameter and the appropriate copy method
-// 2) pack the parameters in the appropriate ActualCallParams< > object
-// 3) call the IPC interface IPCProvider::DoCall( )
-//
-// The general interface of CrossCall is:
-// ResultCode CrossCall(IPCProvider& ipc_provider,
-// uint32 tag,
-// const Par1& p1, const Par2& p2,...pn
-// CrossCallReturn* answer)
-//
-// where:
-// ipc_provider: is a specific implementation of the ipc transport see
-// sharedmem_ipc_server.h for an example.
-// tag : is the unique id for this IPC call. Is used to route the call to
-// the appropriate service.
-// p1, p2,.. pn : The input parameters of the IPC. Use only simple types
-// and wide strings (can add support for others).
-// answer : If the IPC was successful. The server-side answer is here. The
-// interpretation of the answer is private to client and server.
-//
-// The return value is ALL_OK if the IPC was delivered to the server, other
-// return codes indicate that the IPC transport failed to deliver it.
-namespace sandbox {
-
-// this is the assumed channel size. This can be overridden in a given
-// IPC implementation.
-const uint32 kIPCChannelSize = 1024;
-
-// The copy helper uses templates to deduce the appropriate copy function to
-// copy the input parameters in the buffer that is going to be send across the
-// IPC. These template facility can be made more sophisticated as need arises.
-
-// The default copy helper. It catches the general case where no other
-// specialized template matches better. We set the type to ULONG_TYPE, so this
-// only works with objects whose size is 32 bits.
-template<typename T>
-class CopyHelper {
- public:
- CopyHelper(const T& t) : t_(t) {}
-
- // Returns the pointer to the start of the input.
- const void* GetStart() const {
- return &t_;
- }
-
- // Update the stored value with the value in the buffer. This is not
- // supported for this type.
- bool Update(void* buffer) {
- // Not supported;
- return true;
- }
-
- // Returns the size of the input in bytes.
- uint32 GetSize() const {
- return sizeof(T);
- }
-
- // Returns true if the current type is used as an In or InOut parameter.
- bool IsInOut() {
- return false;
- }
-
- // Returns this object's type.
- ArgType GetType() {
- COMPILE_ASSERT(sizeof(T) == sizeof(uint32), need_specialization);
- return ULONG_TYPE;
- }
-
- private:
- const T& t_;
-};
-
-// This copy helper template specialization if for the void pointer
-// case both 32 and 64 bit.
-template<>
-class CopyHelper<void*> {
- public:
- CopyHelper(void* t) : t_(t) {}
-
- // Returns the pointer to the start of the input.
- const void* GetStart() const {
- return &t_;
- }
-
- // Update the stored value with the value in the buffer. This is not
- // supported for this type.
- bool Update(void* buffer) {
- // Not supported;
- return true;
- }
-
- // Returns the size of the input in bytes.
- uint32 GetSize() const {
- return sizeof(t_);
- }
-
- // Returns true if the current type is used as an In or InOut parameter.
- bool IsInOut() {
- return false;
- }
-
- // Returns this object's type.
- ArgType GetType() {
- return VOIDPTR_TYPE;
- }
-
- private:
- const void* t_;
-};
-
-// This copy helper template specialization catches the cases where the
-// parameter is a pointer to a string.
-template<>
-class CopyHelper<const wchar_t*> {
- public:
- CopyHelper(const wchar_t* t)
- : t_(t) {
- }
-
- // Returns the pointer to the start of the string.
- const void* GetStart() const {
- return t_;
- }
-
- // Update the stored value with the value in the buffer. This is not
- // supported for this type.
- bool Update(void* buffer) {
- // Not supported;
- return true;
- }
-
- // Returns the size of the string in bytes. We define a NULL string to
- // be of zero length.
- uint32 GetSize() const {
- __try {
- return (!t_) ? 0 : static_cast<uint32>(StringLength(t_) * sizeof(t_[0]));
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {
- return kuint32max;
- }
- }
-
- // Returns true if the current type is used as an In or InOut parameter.
- bool IsInOut() {
- return false;
- }
-
- ArgType GetType() {
- return WCHAR_TYPE;
- }
-
- private:
- // We provide our not very optimized version of wcslen(), since we don't
- // want to risk having the linker use the version in the CRT since the CRT
- // might not be present when we do an early IPC call.
- static size_t __cdecl StringLength(const wchar_t* wcs) {
- const wchar_t *eos = wcs;
- while (*eos++);
- return static_cast<size_t>(eos - wcs - 1);
- }
-
- const wchar_t* t_;
-};
-
-// Specialization for non-const strings. We just reuse the implementation of the
-// const string specialization.
-template<>
-class CopyHelper<wchar_t*> : public CopyHelper<const wchar_t*> {
- public:
- typedef CopyHelper<const wchar_t*> Base;
- CopyHelper(wchar_t* t) : Base(t) {}
-
- const void* GetStart() const {
- return Base::GetStart();
- }
-
- bool Update(void* buffer) {
- return Base::Update(buffer);
- }
-
- uint32 GetSize() const {
- return Base::GetSize();
- }
-
- bool IsInOut() {
- return Base::IsInOut();
- }
-
- ArgType GetType() {
- return Base::GetType();
- }
-};
-
-// Specialization for wchar_t arrays strings. We just reuse the implementation
-// of the const string specialization.
-template<size_t n>
-class CopyHelper<const wchar_t[n]> : public CopyHelper<const wchar_t*> {
- public:
- typedef const wchar_t array[n];
- typedef CopyHelper<const wchar_t*> Base;
- CopyHelper(array t) : Base(t) {}
-
- const void* GetStart() const {
- return Base::GetStart();
- }
-
- bool Update(void* buffer) {
- return Base::Update(buffer);
- }
-
- uint32 GetSize() const {
- return Base::GetSize();
- }
-
- bool IsInOut() {
- return Base::IsInOut();
- }
-
- ArgType GetType() {
- return Base::GetType();
- }
-};
-
-// Generic encapsulation class containing a pointer to a buffer and the
-// size of the buffer. It is used by the IPC to be able to pass in/out
-// parameters.
-class InOutCountedBuffer : public CountedBuffer {
- public:
- InOutCountedBuffer(void* buffer, uint32 size) : CountedBuffer(buffer, size) {}
-};
-
-// This copy helper template specialization catches the cases where the
-// parameter is a an input/output buffer.
-template<>
-class CopyHelper<InOutCountedBuffer> {
- public:
- CopyHelper(const InOutCountedBuffer t) : t_(t) {}
-
- // Returns the pointer to the start of the string.
- const void* GetStart() const {
- return t_.Buffer();
- }
-
- // Updates the buffer with the value from the new buffer in parameter.
- bool Update(void* buffer) {
- // We are touching user memory, this has to be done from inside a try
- // except.
- __try {
- memcpy(t_.Buffer(), buffer, t_.Size());
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {
- return false;
- }
- return true;
- }
-
- // Returns the size of the string in bytes. We define a NULL string to
- // be of zero length.
- uint32 GetSize() const {
- return t_.Size();
- }
-
- // Returns true if the current type is used as an In or InOut parameter.
- bool IsInOut() {
- return true;
- }
-
- ArgType GetType() {
- return INOUTPTR_TYPE;
- }
-
- private:
- const InOutCountedBuffer t_;
-};
-
-// The following two macros make it less error prone the generation
-// of CrossCall functions with ever more input parameters.
-
-#define XCALL_GEN_PARAMS_OBJ(num, params) \
- typedef ActualCallParams<num, kIPCChannelSize> ActualParams; \
- void* raw_mem = ipc_provider.GetBuffer(); \
- if (NULL == raw_mem) \
- return SBOX_ERROR_NO_SPACE; \
- ActualParams* params = new(raw_mem) ActualParams(tag);
-
-#define XCALL_GEN_COPY_PARAM(num, params) \
- COMPILE_ASSERT(kMaxIpcParams >= num, too_many_parameters); \
- CopyHelper<Par##num> ch##num(p##num); \
- if (!params->CopyParamIn(num - 1, ch##num.GetStart(), ch##num.GetSize(), \
- ch##num.IsInOut(), ch##num.GetType())) \
- return SBOX_ERROR_NO_SPACE;
-
-#define XCALL_GEN_UPDATE_PARAM(num, params) \
- if (!ch##num.Update(params->GetParamPtr(num-1))) {\
- ipc_provider.FreeBuffer(raw_mem); \
- return SBOX_ERROR_BAD_PARAMS; \
- }
-
-#define XCALL_GEN_FREE_CHANNEL() \
- ipc_provider.FreeBuffer(raw_mem);
-
-// CrossCall template with one input parameter
-template <typename IPCProvider, typename Par1>
-ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
- CrossCallReturn* answer) {
- XCALL_GEN_PARAMS_OBJ(1, call_params);
- XCALL_GEN_COPY_PARAM(1, call_params);
-
- ResultCode result = ipc_provider.DoCall(call_params, answer);
-
- if (SBOX_ERROR_CHANNEL_ERROR != result) {
- XCALL_GEN_UPDATE_PARAM(1, call_params);
- XCALL_GEN_FREE_CHANNEL();
- }
-
- return result;
-}
-
-// CrossCall template with two input parameters.
-template <typename IPCProvider, typename Par1, typename Par2>
-ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
- const Par2& p2, CrossCallReturn* answer) {
- XCALL_GEN_PARAMS_OBJ(2, call_params);
- XCALL_GEN_COPY_PARAM(1, call_params);
- XCALL_GEN_COPY_PARAM(2, call_params);
-
- ResultCode result = ipc_provider.DoCall(call_params, answer);
-
- if (SBOX_ERROR_CHANNEL_ERROR != result) {
- XCALL_GEN_UPDATE_PARAM(1, call_params);
- XCALL_GEN_UPDATE_PARAM(2, call_params);
- XCALL_GEN_FREE_CHANNEL();
- }
- return result;
-}
-
-// CrossCall template with three input parameters.
-template <typename IPCProvider, typename Par1, typename Par2, typename Par3>
-ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
- const Par2& p2, const Par3& p3, CrossCallReturn* answer) {
- XCALL_GEN_PARAMS_OBJ(3, call_params);
- XCALL_GEN_COPY_PARAM(1, call_params);
- XCALL_GEN_COPY_PARAM(2, call_params);
- XCALL_GEN_COPY_PARAM(3, call_params);
-
- ResultCode result = ipc_provider.DoCall(call_params, answer);
-
- if (SBOX_ERROR_CHANNEL_ERROR != result) {
- XCALL_GEN_UPDATE_PARAM(1, call_params);
- XCALL_GEN_UPDATE_PARAM(2, call_params);
- XCALL_GEN_UPDATE_PARAM(3, call_params);
- XCALL_GEN_FREE_CHANNEL();
- }
- return result;
-}
-
-// CrossCall template with four input parameters.
-template <typename IPCProvider, typename Par1, typename Par2, typename Par3,
- typename Par4>
-ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
- const Par2& p2, const Par3& p3, const Par4& p4,
- CrossCallReturn* answer) {
- XCALL_GEN_PARAMS_OBJ(4, call_params);
- XCALL_GEN_COPY_PARAM(1, call_params);
- XCALL_GEN_COPY_PARAM(2, call_params);
- XCALL_GEN_COPY_PARAM(3, call_params);
- XCALL_GEN_COPY_PARAM(4, call_params);
-
- ResultCode result = ipc_provider.DoCall(call_params, answer);
-
- if (SBOX_ERROR_CHANNEL_ERROR != result) {
- XCALL_GEN_UPDATE_PARAM(1, call_params);
- XCALL_GEN_UPDATE_PARAM(2, call_params);
- XCALL_GEN_UPDATE_PARAM(3, call_params);
- XCALL_GEN_UPDATE_PARAM(4, call_params);
- XCALL_GEN_FREE_CHANNEL();
- }
- return result;
-}
-
-// CrossCall template with five input parameters.
-template <typename IPCProvider, typename Par1, typename Par2, typename Par3,
- typename Par4, typename Par5>
-ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
- const Par2& p2, const Par3& p3, const Par4& p4,
- const Par5& p5, CrossCallReturn* answer) {
- XCALL_GEN_PARAMS_OBJ(5, call_params);
- XCALL_GEN_COPY_PARAM(1, call_params);
- XCALL_GEN_COPY_PARAM(2, call_params);
- XCALL_GEN_COPY_PARAM(3, call_params);
- XCALL_GEN_COPY_PARAM(4, call_params);
- XCALL_GEN_COPY_PARAM(5, call_params);
-
- ResultCode result = ipc_provider.DoCall(call_params, answer);
-
- if (SBOX_ERROR_CHANNEL_ERROR != result) {
- XCALL_GEN_UPDATE_PARAM(1, call_params);
- XCALL_GEN_UPDATE_PARAM(2, call_params);
- XCALL_GEN_UPDATE_PARAM(3, call_params);
- XCALL_GEN_UPDATE_PARAM(4, call_params);
- XCALL_GEN_UPDATE_PARAM(5, call_params);
- XCALL_GEN_FREE_CHANNEL();
- }
- return result;
-}
-
-// CrossCall template with six input parameters.
-template <typename IPCProvider, typename Par1, typename Par2, typename Par3,
- typename Par4, typename Par5, typename Par6>
-ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
- const Par2& p2, const Par3& p3, const Par4& p4,
- const Par5& p5, const Par6& p6, CrossCallReturn* answer) {
- XCALL_GEN_PARAMS_OBJ(6, call_params);
- XCALL_GEN_COPY_PARAM(1, call_params);
- XCALL_GEN_COPY_PARAM(2, call_params);
- XCALL_GEN_COPY_PARAM(3, call_params);
- XCALL_GEN_COPY_PARAM(4, call_params);
- XCALL_GEN_COPY_PARAM(5, call_params);
- XCALL_GEN_COPY_PARAM(6, call_params);
-
- ResultCode result = ipc_provider.DoCall(call_params, answer);
-
- if (SBOX_ERROR_CHANNEL_ERROR != result) {
- XCALL_GEN_UPDATE_PARAM(1, call_params);
- XCALL_GEN_UPDATE_PARAM(2, call_params);
- XCALL_GEN_UPDATE_PARAM(3, call_params);
- XCALL_GEN_UPDATE_PARAM(4, call_params);
- XCALL_GEN_UPDATE_PARAM(5, call_params);
- XCALL_GEN_UPDATE_PARAM(6, call_params);
- XCALL_GEN_FREE_CHANNEL();
- }
- return result;
-}
-
-// CrossCall template with seven input parameters.
-template <typename IPCProvider, typename Par1, typename Par2, typename Par3,
- typename Par4, typename Par5, typename Par6, typename Par7>
-ResultCode CrossCall(IPCProvider& ipc_provider, uint32 tag, const Par1& p1,
- const Par2& p2, const Par3& p3, const Par4& p4,
- const Par5& p5, const Par6& p6, const Par7& p7,
- CrossCallReturn* answer) {
- XCALL_GEN_PARAMS_OBJ(7, call_params);
- XCALL_GEN_COPY_PARAM(1, call_params);
- XCALL_GEN_COPY_PARAM(2, call_params);
- XCALL_GEN_COPY_PARAM(3, call_params);
- XCALL_GEN_COPY_PARAM(4, call_params);
- XCALL_GEN_COPY_PARAM(5, call_params);
- XCALL_GEN_COPY_PARAM(6, call_params);
- XCALL_GEN_COPY_PARAM(7, call_params);
-
- ResultCode result = ipc_provider.DoCall(call_params, answer);
-
- if (SBOX_ERROR_CHANNEL_ERROR != result) {
- XCALL_GEN_UPDATE_PARAM(1, call_params);
- XCALL_GEN_UPDATE_PARAM(2, call_params);
- XCALL_GEN_UPDATE_PARAM(3, call_params);
- XCALL_GEN_UPDATE_PARAM(4, call_params);
- XCALL_GEN_UPDATE_PARAM(5, call_params);
- XCALL_GEN_UPDATE_PARAM(6, call_params);
- XCALL_GEN_UPDATE_PARAM(7, call_params);
- XCALL_GEN_FREE_CHANNEL();
- }
- return result;
-}
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_CROSSCALL_CLIENT_H__
diff --git a/sandbox/win/src/crosscall_params.h b/sandbox/win/src/crosscall_params.h
deleted file mode 100644
index c5298ba..0000000
--- a/sandbox/win/src/crosscall_params.h
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_CROSSCALL_PARAMS_H__
-#define SANDBOX_SRC_CROSSCALL_PARAMS_H__
-
-#include <windows.h>
-#include <lmaccess.h>
-
-#include <memory>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/internal_types.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-namespace {
-
-// Increases |value| until there is no need for padding given an int64
-// alignment. Returns the increased value.
-uint32 Align(uint32 value) {
- uint32 alignment = sizeof(int64);
- return ((value + alignment - 1) / alignment) * alignment;
-}
-
-}
-// This header is part of CrossCall: the sandbox inter-process communication.
-// This header defines the basic types used both in the client IPC and in the
-// server IPC code. CrossCallParams and ActualCallParams model the input
-// parameters of an IPC call and CrossCallReturn models the output params and
-// the return value.
-//
-// An IPC call is defined by its 'tag' which is a (uint32) unique identifier
-// that is used to route the IPC call to the proper server. Every tag implies
-// a complete call signature including the order and type of each parameter.
-//
-// Like most IPC systems. CrossCall is designed to take as inputs 'simple'
-// types such as integers and strings. Classes, generic arrays or pointers to
-// them are not supported.
-//
-// Another limitation of CrossCall is that the return value and output
-// parameters can only be uint32 integers. Returning complex structures or
-// strings is not supported.
-
-namespace sandbox {
-
-// max number of extended return parameters. See CrossCallReturn
-const size_t kExtendedReturnCount = 8;
-
-// Union of multiple types to be used as extended results
-// in the CrossCallReturn.
-union MultiType {
- uint32 unsigned_int;
- void* pointer;
- HANDLE handle;
- ULONG_PTR ulong_ptr;
-};
-
-// Maximum number of IPC parameters currently supported.
-// To increase this value, we have to:
-// - Add another Callback typedef to Dispatcher.
-// - Add another case to the switch on SharedMemIPCServer::InvokeCallback.
-// - Add another case to the switch in GetActualAndMaxBufferSize
-const int kMaxIpcParams = 9;
-
-// Contains the information about a parameter in the ipc buffer.
-struct ParamInfo {
- ArgType type_;
- uint32 offset_;
- uint32 size_;
-};
-
-// Models the return value and the return parameters of an IPC call
-// currently limited to one status code and eight generic return values
-// which cannot be pointers to other data. For x64 ports this structure
-// might have to use other integer types.
-struct CrossCallReturn {
- // the IPC tag. It should match the original IPC tag.
- uint32 tag;
- // The result of the IPC operation itself.
- ResultCode call_outcome;
- // the result of the IPC call as executed in the server. The interpretation
- // of this value depends on the specific service.
- union {
- NTSTATUS nt_status;
- DWORD win32_result;
- };
- // Number of extended return values.
- uint32 extended_count;
- // for calls that should return a windows handle. It is found here.
- HANDLE handle;
- // The array of extended values.
- MultiType extended[kExtendedReturnCount];
-};
-
-// CrossCallParams base class that models the input params all packed in a
-// single compact memory blob. The representation can vary but in general a
-// given child of this class is meant to represent all input parameters
-// necessary to make a IPC call.
-//
-// This class cannot have virtual members because its assumed the IPC
-// parameters start from the 'this' pointer to the end, which is defined by
-// one of the subclasses
-//
-// Objects of this class cannot be constructed directly. Only derived
-// classes have the proper knowledge to construct it.
-class CrossCallParams {
- public:
- // Returns the tag (ipc unique id) associated with this IPC.
- uint32 GetTag() const {
- return tag_;
- }
-
- // Returns the beggining of the buffer where the IPC params can be stored.
- // prior to an IPC call
- const void* GetBuffer() const {
- return this;
- }
-
- // Returns how many parameter this IPC call should have.
- const uint32 GetParamsCount() const {
- return params_count_;
- }
-
- // Returns a pointer to the CrossCallReturn structure.
- CrossCallReturn* GetCallReturn() {
- return &call_return;
- }
-
- // Returns TRUE if this call contains InOut parameters.
- const bool IsInOut() const {
- return (1 == is_in_out_);
- }
-
- // Tells the CrossCall object if it contains InOut parameters.
- void SetIsInOut(bool value) {
- if (value)
- is_in_out_ = 1;
- else
- is_in_out_ = 0;
- }
-
- protected:
- // constructs the IPC call params. Called only from the derived classes
- CrossCallParams(uint32 tag, uint32 params_count)
- : tag_(tag),
- params_count_(params_count),
- is_in_out_(0) {
- }
-
- private:
- uint32 tag_;
- uint32 is_in_out_;
- CrossCallReturn call_return;
- const uint32 params_count_;
- DISALLOW_COPY_AND_ASSIGN(CrossCallParams);
-};
-
-// ActualCallParams models an specific IPC call parameters with respect to the
-// storage allocation that the packed parameters should need.
-// NUMBER_PARAMS: the number of parameters, valid from 1 to N
-// BLOCK_SIZE: the total storage that the NUMBER_PARAMS parameters can take,
-// typically the block size is defined by the channel size of the underlying
-// ipc mechanism.
-// In practice this class is used to levergage C++ capacity to properly
-// calculate sizes and displacements given the possibility of the packed params
-// blob to be complex.
-//
-// As is, this class assumes that the layout of the blob is as follows. Assume
-// that NUMBER_PARAMS = 2 and a 32-bit build:
-//
-// [ tag 4 bytes]
-// [ IsOnOut 4 bytes]
-// [ call return 52 bytes]
-// [ params count 4 bytes]
-// [ parameter 0 type 4 bytes]
-// [ parameter 0 offset 4 bytes] ---delta to ---\
-// [ parameter 0 size 4 bytes] |
-// [ parameter 1 type 4 bytes] |
-// [ parameter 1 offset 4 bytes] ---------------|--\
-// [ parameter 1 size 4 bytes] | |
-// [ parameter 2 type 4 bytes] | |
-// [ parameter 2 offset 4 bytes] ----------------------\
-// [ parameter 2 size 4 bytes] | | |
-// |---------------------------| | | |
-// | value 0 (x bytes) | <--------------/ | |
-// | value 1 (y bytes) | <-----------------/ |
-// | | |
-// | end of buffer | <---------------------/
-// |---------------------------|
-//
-// Note that the actual number of params is NUMBER_PARAMS + 1
-// so that the size of each actual param can be computed from the difference
-// between one parameter and the next down. The offset of the last param
-// points to the end of the buffer and the type and size are undefined.
-//
-template <size_t NUMBER_PARAMS, size_t BLOCK_SIZE>
-class ActualCallParams : public CrossCallParams {
- public:
- // constructor. Pass the ipc unique tag as input
- explicit ActualCallParams(uint32 tag)
- : CrossCallParams(tag, NUMBER_PARAMS) {
- param_info_[0].offset_ = parameters_ - reinterpret_cast<char*>(this);
- }
-
- // Testing-only constructor. Allows setting the |number_params| to a
- // wrong value.
- ActualCallParams(uint32 tag, uint32 number_params)
- : CrossCallParams(tag, number_params) {
- param_info_[0].offset_ = parameters_ - reinterpret_cast<char*>(this);
- }
-
- // Testing-only method. Allows setting the apparent size to a wrong value.
- // returns the previous size.
- uint32 OverrideSize(uint32 new_size) {
- uint32 previous_size = param_info_[NUMBER_PARAMS].offset_;
- param_info_[NUMBER_PARAMS].offset_ = new_size;
- return previous_size;
- }
-
- // Copies each paramter into the internal buffer. For each you must supply:
- // index: 0 for the first param, 1 for the next an so on
- bool CopyParamIn(uint32 index, const void* parameter_address, uint32 size,
- bool is_in_out, ArgType type) {
- if (index >= NUMBER_PARAMS) {
- return false;
- }
-
- if (kuint32max == size) {
- // Memory error while getting the size.
- return false;
- }
-
- if (size && !parameter_address) {
- return false;
- }
-
- if (param_info_[index].offset_ > sizeof(*this)) {
- // It does not fit, abort copy.
- return false;
- }
-
- char* dest = reinterpret_cast<char*>(this) + param_info_[index].offset_;
-
- // We might be touching user memory, this has to be done from inside a try
- // except.
- __try {
- memcpy(dest, parameter_address, size);
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {
- return false;
- }
-
- // Set the flag to tell the broker to update the buffer once the call is
- // made.
- if (is_in_out)
- SetIsInOut(true);
-
- param_info_[index + 1].offset_ = Align(param_info_[index].offset_ +
- size);
- param_info_[index].size_ = size;
- param_info_[index].type_ = type;
- return true;
- }
-
- // Returns a pointer to a parameter in the memory section.
- void* GetParamPtr(size_t index) {
- return reinterpret_cast<char*>(this) + param_info_[index].offset_;
- }
-
- // Returns the total size of the buffer. Only valid once all the paramters
- // have been copied in with CopyParamIn.
- uint32 GetSize() const {
- return param_info_[NUMBER_PARAMS].offset_;
- }
-
- protected:
- ActualCallParams() : CrossCallParams(0, NUMBER_PARAMS) { }
-
- private:
- ParamInfo param_info_[NUMBER_PARAMS + 1];
- char parameters_[BLOCK_SIZE - sizeof(CrossCallParams)
- - sizeof(ParamInfo) * (NUMBER_PARAMS + 1)];
- DISALLOW_COPY_AND_ASSIGN(ActualCallParams);
-};
-
-COMPILE_ASSERT(sizeof(ActualCallParams<1, 1024>) == 1024, bad_size_buffer);
-COMPILE_ASSERT(sizeof(ActualCallParams<2, 1024>) == 1024, bad_size_buffer);
-COMPILE_ASSERT(sizeof(ActualCallParams<3, 1024>) == 1024, bad_size_buffer);
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_CROSSCALL_PARAMS_H__
diff --git a/sandbox/win/src/crosscall_server.cc b/sandbox/win/src/crosscall_server.cc
deleted file mode 100644
index 0140580..0000000
--- a/sandbox/win/src/crosscall_server.cc
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-#include <vector>
-
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/crosscall_params.h"
-#include "sandbox/win/src/crosscall_client.h"
-#include "base/logging.h"
-
-// This code performs the ipc message validation. Potential security flaws
-// on the ipc are likelier to be found in this code than in the rest of
-// the ipc code.
-
-namespace {
-
-// The buffer for a message must match the max channel size.
-const size_t kMaxBufferSize = sandbox::kIPCChannelSize;
-
-}
-
-namespace sandbox {
-
-// Returns the actual size for the parameters in an IPC buffer. Returns
-// zero if the |param_count| is zero or too big.
-uint32 GetActualBufferSize(uint32 param_count, void* buffer_base) {
- // The template types are used to calculate the maximum expected size.
- typedef ActualCallParams<1, kMaxBufferSize> ActualCP1;
- typedef ActualCallParams<2, kMaxBufferSize> ActualCP2;
- typedef ActualCallParams<3, kMaxBufferSize> ActualCP3;
- typedef ActualCallParams<4, kMaxBufferSize> ActualCP4;
- typedef ActualCallParams<5, kMaxBufferSize> ActualCP5;
- typedef ActualCallParams<6, kMaxBufferSize> ActualCP6;
- typedef ActualCallParams<7, kMaxBufferSize> ActualCP7;
- typedef ActualCallParams<8, kMaxBufferSize> ActualCP8;
- typedef ActualCallParams<9, kMaxBufferSize> ActualCP9;
-
- // Retrieve the actual size and the maximum size of the params buffer.
- switch (param_count) {
- case 0:
- return 0;
- case 1:
- return reinterpret_cast<ActualCP1*>(buffer_base)->GetSize();
- case 2:
- return reinterpret_cast<ActualCP2*>(buffer_base)->GetSize();
- case 3:
- return reinterpret_cast<ActualCP3*>(buffer_base)->GetSize();
- case 4:
- return reinterpret_cast<ActualCP4*>(buffer_base)->GetSize();
- case 5:
- return reinterpret_cast<ActualCP5*>(buffer_base)->GetSize();
- case 6:
- return reinterpret_cast<ActualCP6*>(buffer_base)->GetSize();
- case 7:
- return reinterpret_cast<ActualCP7*>(buffer_base)->GetSize();
- case 8:
- return reinterpret_cast<ActualCP8*>(buffer_base)->GetSize();
- case 9:
- return reinterpret_cast<ActualCP9*>(buffer_base)->GetSize();
- default:
- NOTREACHED();
- return 0;
- }
-}
-
-CrossCallParamsEx::CrossCallParamsEx()
- :CrossCallParams(0, 0) {
-}
-
-// We override the delete operator because the object's backing memory
-// is hand allocated in CreateFromBuffer. We don't override the new operator
-// because the constructors are private so there is no way to mismatch
-// new & delete.
-void CrossCallParamsEx::operator delete(void* raw_memory) throw() {
- if (NULL == raw_memory) {
- // C++ standard allows 'delete 0' behavior.
- return;
- }
- delete[] reinterpret_cast<char*>(raw_memory);
-}
-
-// This function uses a SEH try block so cannot use C++ objects that
-// have destructors or else you get Compiler Error C2712. So no DCHECKs
-// inside this function.
-CrossCallParamsEx* CrossCallParamsEx::CreateFromBuffer(void* buffer_base,
- uint32 buffer_size,
- uint32* output_size) {
- // IMPORTANT: Everything inside buffer_base and derived from it such
- // as param_count and declared_size is untrusted.
- if (NULL == buffer_base) {
- return NULL;
- }
- if (buffer_size < sizeof(CrossCallParams)) {
- return NULL;
- }
- if (buffer_size > kMaxBufferSize) {
- return NULL;
- }
-
- char* backing_mem = NULL;
- uint32 param_count = 0;
- uint32 declared_size;
- uint32 min_declared_size;
- CrossCallParamsEx* copied_params = NULL;
-
- // Touching the untrusted buffer is done under a SEH try block. This
- // will catch memory access violations so we don't crash.
- __try {
- CrossCallParams* call_params =
- reinterpret_cast<CrossCallParams*>(buffer_base);
-
- // Check against the minimum size given the number of stated params
- // if too small we bail out.
- param_count = call_params->GetParamsCount();
- min_declared_size = sizeof(CrossCallParams) +
- ((param_count + 1) * sizeof(ParamInfo));
-
- if ((buffer_size < min_declared_size) ||
- (sizeof(CrossCallParamsEx) > min_declared_size)) {
- // Minimal computed size bigger than existing buffer or param_count
- // integer overflow.
- return NULL;
- }
-
- // Retrieve the declared size which if it fails returns 0.
- declared_size = GetActualBufferSize(param_count, buffer_base);
-
- if ((declared_size > buffer_size) ||
- (declared_size < min_declared_size)) {
- // Declared size is bigger than buffer or smaller than computed size
- // or param_count 0 or bigger than 9.
- return NULL;
- }
-
- // Now we copy the actual amount of the message.
- *output_size = declared_size;
- backing_mem = new char[declared_size];
- copied_params = reinterpret_cast<CrossCallParamsEx*>(backing_mem);
- memcpy(backing_mem, call_params, declared_size);
-
- // Check params count in case it got changed right before the memcpy.
- if (copied_params->GetParamsCount() != param_count) {
- delete [] backing_mem;
- return NULL;
- }
-
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- // In case of a windows exception we know it occurred while touching the
- // untrusted buffer so we bail out as is.
- delete [] backing_mem;
- return NULL;
- }
-
- const char* last_byte = &backing_mem[declared_size];
- const char* first_byte = &backing_mem[min_declared_size];
-
- // Verify here that all and each parameters make sense. This is done in the
- // local copy.
- for (uint32 ix =0; ix != param_count; ++ix) {
- uint32 size = 0;
- ArgType type;
- char* address = reinterpret_cast<char*>(
- copied_params->GetRawParameter(ix, &size, &type));
- if ((NULL == address) || // No null params.
- (INVALID_TYPE >= type) || (LAST_TYPE <= type) || // Unknown type.
- (address < backing_mem) || // Start cannot point before buffer.
- (address < first_byte) || // Start cannot point too low.
- (address > last_byte) || // Start cannot point past buffer.
- ((address + size) < address) || // Invalid size.
- ((address + size) > last_byte)) { // End cannot point past buffer.
- // Malformed.
- delete[] backing_mem;
- return NULL;
- }
- }
- // The parameter buffer looks good.
- return copied_params;
-}
-
-// Accessors to the parameters in the raw buffer.
-void* CrossCallParamsEx::GetRawParameter(uint32 index, uint32* size,
- ArgType* type) {
- if (index >= GetParamsCount()) {
- return NULL;
- }
- // The size is always computed from the parameter minus the next
- // parameter, this works because the message has an extra parameter slot
- *size = param_info_[index].size_;
- *type = param_info_[index].type_;
-
- return param_info_[index].offset_ + reinterpret_cast<char*>(this);
-}
-
-// Covers common case for 32 bit integers.
-bool CrossCallParamsEx::GetParameter32(uint32 index, uint32* param) {
- uint32 size = 0;
- ArgType type;
- void* start = GetRawParameter(index, &size, &type);
- if ((NULL == start) || (4 != size) || (ULONG_TYPE != type)) {
- return false;
- }
- // Copy the 4 bytes.
- *(reinterpret_cast<uint32*>(param)) = *(reinterpret_cast<uint32*>(start));
- return true;
-}
-
-bool CrossCallParamsEx::GetParameterVoidPtr(uint32 index, void** param) {
- uint32 size = 0;
- ArgType type;
- void* start = GetRawParameter(index, &size, &type);
- if ((NULL == start) || (sizeof(void*) != size) || (VOIDPTR_TYPE != type)) {
- return false;
- }
- *param = *(reinterpret_cast<void**>(start));
- return true;
-}
-
-// Covers the common case of reading a string. Note that the string is not
-// scanned for invalid characters.
-bool CrossCallParamsEx::GetParameterStr(uint32 index, std::wstring* string) {
- uint32 size = 0;
- ArgType type;
- void* start = GetRawParameter(index, &size, &type);
- if (WCHAR_TYPE != type) {
- return false;
- }
-
- // Check if this is an empty string.
- if (size == 0) {
- *string = L"";
- return true;
- }
-
- if ((NULL == start) || ((size % sizeof(wchar_t)) != 0)) {
- return false;
- }
- string->append(reinterpret_cast<wchar_t*>(start), size/(sizeof(wchar_t)));
- return true;
-}
-
-bool CrossCallParamsEx::GetParameterPtr(uint32 index, uint32 expected_size,
- void** pointer) {
- uint32 size = 0;
- ArgType type;
- void* start = GetRawParameter(index, &size, &type);
-
- if ((size != expected_size) || (INOUTPTR_TYPE != type)) {
- return false;
- }
-
- if (NULL == start) {
- return false;
- }
-
- *pointer = start;
- return true;
-}
-
-void SetCallError(ResultCode error, CrossCallReturn* call_return) {
- call_return->call_outcome = error;
- call_return->extended_count = 0;
-}
-
-void SetCallSuccess(CrossCallReturn* call_return) {
- call_return->call_outcome = SBOX_ALL_OK;
-}
-
-Dispatcher* Dispatcher::OnMessageReady(IPCParams* ipc,
- CallbackGeneric* callback) {
- DCHECK(callback);
- std::vector<IPCCall>::iterator it = ipc_calls_.begin();
- for (; it != ipc_calls_.end(); ++it) {
- if (it->params.Matches(ipc)) {
- *callback = it->callback;
- return this;
- }
- }
- return NULL;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/crosscall_server.h b/sandbox/win/src/crosscall_server.h
deleted file mode 100644
index 2a39507..0000000
--- a/sandbox/win/src/crosscall_server.h
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_CROSSCALL_SERVER_H_
-#define SANDBOX_SRC_CROSSCALL_SERVER_H_
-
-#include <string>
-#include <vector>
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "sandbox/win/src/crosscall_params.h"
-
-// This is the IPC server interface for CrossCall: The IPC for the Sandbox
-// On the server, CrossCall needs two things:
-// 1) threads: Or better said, someone to provide them, that is what the
-// ThreadProvider interface is defined for. These thread(s) are
-// the ones that will actually execute the IPC data retrieval.
-//
-// 2) a dispatcher: This interface represents the way to route and process
-// an IPC call given the IPC tag.
-//
-// The other class included here CrossCallParamsEx is the server side version
-// of the CrossCallParams class of /sandbox/crosscall_params.h The difference
-// is that the sever version is paranoid about the correctness of the IPC
-// message and will do all sorts of verifications.
-//
-// A general diagram of the interaction is as follows:
-//
-// ------------
-// | |
-// ThreadProvider <--(1)Register--| IPC |
-// | | Implemen |
-// | | -tation |
-// (2) | | OnMessage
-// IPC fired --callback ------>| |--(3)---> Dispatcher
-// | |
-// ------------
-//
-// The IPC implementation sits as a middleman between the handling of the
-// specifics of scheduling a thread to service the IPC and the multiple
-// entities that can potentially serve each particular IPC.
-namespace sandbox {
-
-class InterceptionManager;
-
-// This function signature is required as the callback when an IPC call fires.
-// context: a user-defined pointer that was set using ThreadProvider
-// reason: 0 if the callback was fired because of a timeout.
-// 1 if the callback was fired because of an event.
-typedef void (__stdcall * CrossCallIPCCallback)(void* context,
- unsigned char reason);
-
-// ThreadProvider models a thread factory. The idea is to decouple thread
-// creation and lifetime from the inner guts of the IPC. The contract is
-// simple:
-// - the IPC implementation calls RegisterWait with a waitable object that
-// becomes signaled when an IPC arrives and needs to be serviced.
-// - when the waitable object becomes signaled, the thread provider conjures
-// a thread that calls the callback (CrossCallIPCCallback) function
-// - the callback function tries its best not to block and return quickly
-// and should not assume that the next callback will use the same thread
-// - when the callback returns the ThreadProvider owns again the thread
-// and can destroy it or keep it around.
-class ThreadProvider {
- public:
- // Registers a waitable object with the thread provider.
- // client: A number to associate with all the RegisterWait calls, typically
- // this is the address of the caller object. This parameter cannot
- // be zero.
- // waitable_object : a kernel object that can be waited on
- // callback: a function pointer which is the function that will be called
- // when the waitable object fires
- // context: a user-provider pointer that is passed back to the callback
- // when its called
- virtual bool RegisterWait(const void* client, HANDLE waitable_object,
- CrossCallIPCCallback callback,
- void* context) = 0;
-
- // Removes all the registrations done with the same cookie parameter.
- // This frees internal thread pool resources.
- virtual bool UnRegisterWaits(void* cookie) = 0;
- virtual ~ThreadProvider() {}
-};
-
-// Models the server-side of the original input parameters.
-// Provides IPC buffer validation and it is capable of reading the parameters
-// out of the IPC buffer.
-class CrossCallParamsEx : public CrossCallParams {
- public:
- // Factory constructor. Pass an IPCbuffer (and buffer size) that contains a
- // pending IPCcall. This constructor will:
- // 1) validate the IPC buffer. returns NULL is the IPCbuffer is malformed.
- // 2) make a copy of the IPCbuffer (parameter capture)
- static CrossCallParamsEx* CreateFromBuffer(void* buffer_base,
- uint32 buffer_size,
- uint32* output_size);
-
- // Provides IPCinput parameter raw access:
- // index : the parameter to read; 0 is the first parameter
- // returns NULL if the parameter is non-existent. If it exists it also
- // returns the size in *size
- void* GetRawParameter(uint32 index, uint32* size, ArgType* type);
-
- // Gets a parameter that is four bytes in size.
- // Returns false if the parameter does not exist or is not 32 bits wide.
- bool GetParameter32(uint32 index, uint32* param);
-
- // Gets a parameter that is void pointer in size.
- // Returns false if the parameter does not exist or is not void pointer sized.
- bool GetParameterVoidPtr(uint32 index, void** param);
-
- // Gets a parameter that is a string. Returns false if the parameter does not
- // exist.
- bool GetParameterStr(uint32 index, std::wstring* string);
-
- // Gets a parameter that is an in/out buffer. Returns false is the parameter
- // does not exist or if the size of the actual parameter is not equal to the
- // expected size.
- bool GetParameterPtr(uint32 index, uint32 expected_size, void** pointer);
-
- // Frees the memory associated with the IPC parameters.
- static void operator delete(void* raw_memory) throw();
-
- private:
- // Only the factory method CreateFromBuffer can construct these objects.
- CrossCallParamsEx();
-
- ParamInfo param_info_[1];
- DISALLOW_COPY_AND_ASSIGN(CrossCallParamsEx);
-};
-
-// Simple helper function that sets the members of CrossCallReturn
-// to the proper state to signal a basic error.
-void SetCallError(ResultCode error, CrossCallReturn* call_return);
-
-// Sets the internal status of call_return to signify the that IPC call
-// completed successfully.
-void SetCallSuccess(CrossCallReturn* call_return);
-
-// Represents the client process that initiated the IPC which boils down to the
-// process handle and the job object handle that contains the client process.
-struct ClientInfo {
- HANDLE process;
- HANDLE job_object;
- DWORD process_id;
-};
-
-// All IPC-related information to be passed to the IPC handler.
-struct IPCInfo {
- int ipc_tag;
- const ClientInfo* client_info;
- CrossCallReturn return_info;
-};
-
-// This structure identifies IPC signatures.
-struct IPCParams {
- int ipc_tag;
- ArgType args[kMaxIpcParams];
-
- bool Matches(IPCParams* other) const {
- return !memcmp(this, other, sizeof(*other));
- }
-};
-
-// Models an entity that can process an IPC message or it can route to another
-// one that could handle it. When an IPC arrives the IPC implementation will:
-// 1) call OnMessageReady() with the tag of the pending IPC. If the dispatcher
-// returns NULL it means that it cannot handle this IPC but if it returns
-// non-null, it must be the pointer to a dispatcher that can handle it.
-// 2) When the IPC finally obtains a valid Dispatcher the IPC
-// implementation creates a CrossCallParamsEx from the raw IPC buffer.
-// 3) It calls the returned callback, with the IPC info and arguments.
-class Dispatcher {
- public:
- // Called from the IPC implementation to handle a specific IPC message.
- typedef bool (Dispatcher::*CallbackGeneric)();
- typedef bool (Dispatcher::*Callback0)(IPCInfo* ipc);
- typedef bool (Dispatcher::*Callback1)(IPCInfo* ipc, void* p1);
- typedef bool (Dispatcher::*Callback2)(IPCInfo* ipc, void* p1, void* p2);
- typedef bool (Dispatcher::*Callback3)(IPCInfo* ipc, void* p1, void* p2,
- void* p3);
- typedef bool (Dispatcher::*Callback4)(IPCInfo* ipc, void* p1, void* p2,
- void* p3, void* p4);
- typedef bool (Dispatcher::*Callback5)(IPCInfo* ipc, void* p1, void* p2,
- void* p3, void* p4, void* p5);
- typedef bool (Dispatcher::*Callback6)(IPCInfo* ipc, void* p1, void* p2,
- void* p3, void* p4, void* p5, void* p6);
- typedef bool (Dispatcher::*Callback7)(IPCInfo* ipc, void* p1, void* p2,
- void* p3, void* p4, void* p5, void* p6,
- void* p7);
- typedef bool (Dispatcher::*Callback8)(IPCInfo* ipc, void* p1, void* p2,
- void* p3, void* p4, void* p5, void* p6,
- void* p7, void* p8);
- typedef bool (Dispatcher::*Callback9)(IPCInfo* ipc, void* p1, void* p2,
- void* p3, void* p4, void* p5, void* p6,
- void* p7, void* p8, void* p9);
-
- // Called from the IPC implementation when an IPC message is ready override
- // on a derived class to handle a set of IPC messages. Return NULL if your
- // subclass does not handle the message or return the pointer to the subclass
- // that can handle it.
- virtual Dispatcher* OnMessageReady(IPCParams* ipc, CallbackGeneric* callback);
-
- // Called when a target proces is created, to setup the interceptions related
- // with the given service (IPC).
- virtual bool SetupService(InterceptionManager* manager, int service) = 0;
-
- virtual ~Dispatcher() {}
-
- protected:
- // Structure that defines an IPC Call with all the parameters and the handler.
- struct IPCCall {
- IPCParams params;
- CallbackGeneric callback;
- };
-
- // List of IPC Calls supported by the class.
- std::vector<IPCCall> ipc_calls_;
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_CROSSCALL_SERVER_H_
diff --git a/sandbox/win/src/dep.cc b/sandbox/win/src/dep.cc
deleted file mode 100644
index 0c42050..0000000
--- a/sandbox/win/src/dep.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/dep.h"
-
-#include <windows.h>
-
-#include "base/logging.h"
-
-namespace sandbox {
-
-namespace {
-
-// These values are in the Windows 2008 SDK but not in the previous ones. Define
-// the values here until we're sure everyone updated their SDK.
-#ifndef PROCESS_DEP_ENABLE
-#define PROCESS_DEP_ENABLE 0x00000001
-#endif
-#ifndef PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION
-#define PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION 0x00000002
-#endif
-
-// SetProcessDEPPolicy is declared in the Windows 2008 SDK.
-typedef BOOL (WINAPI *FnSetProcessDEPPolicy)(DWORD dwFlags);
-
-enum PROCESS_INFORMATION_CLASS {
- ProcessExecuteFlags = 0x22,
-};
-
-// Flags named as per their usage.
-const int MEM_EXECUTE_OPTION_ENABLE = 1;
-const int MEM_EXECUTE_OPTION_DISABLE = 2;
-const int MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4;
-const int MEM_EXECUTE_OPTION_PERMANENT = 8;
-
-// Not exactly the right signature but that will suffice.
-typedef HRESULT (WINAPI *FnNtSetInformationProcess)(
- HANDLE ProcessHandle,
- PROCESS_INFORMATION_CLASS ProcessInformationClass,
- PVOID ProcessInformation,
- ULONG ProcessInformationLength);
-
-} // namespace
-
-bool SetCurrentProcessDEP(DepEnforcement enforcement) {
-#ifdef _WIN64
- // DEP is always on in x64.
- return enforcement != DEP_DISABLED;
-#endif
- // Only available on Windows XP SP2 and Windows Server 2003 SP1.
- // For reference: http://www.uninformed.org/?v=2&a=4
- FnNtSetInformationProcess NtSetInformationProc =
- reinterpret_cast<FnNtSetInformationProcess>(
- GetProcAddress(GetModuleHandle(L"ntdll.dll"),
- "NtSetInformationProcess"));
-
- if (!NtSetInformationProc)
- return false;
-
- // Flags being used as per SetProcessDEPPolicy on Vista SP1.
- ULONG dep_flags;
- switch (enforcement) {
- case DEP_DISABLED:
- // 2
- dep_flags = MEM_EXECUTE_OPTION_DISABLE;
- break;
- case DEP_ENABLED:
- // 9
- dep_flags = MEM_EXECUTE_OPTION_PERMANENT | MEM_EXECUTE_OPTION_ENABLE;
- break;
- case DEP_ENABLED_ATL7_COMPAT:
- // 0xD
- dep_flags = MEM_EXECUTE_OPTION_PERMANENT | MEM_EXECUTE_OPTION_ENABLE |
- MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION;
- break;
- default:
- NOTREACHED();
- return false;
- }
-
- HRESULT status = NtSetInformationProc(GetCurrentProcess(),
- ProcessExecuteFlags,
- &dep_flags,
- sizeof(dep_flags));
- return SUCCEEDED(status);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/dep.h b/sandbox/win/src/dep.h
deleted file mode 100644
index 9016285..0000000
--- a/sandbox/win/src/dep.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_DEP_H__
-#define SANDBOX_SRC_DEP_H__
-
-namespace sandbox {
-
-enum DepEnforcement {
- // DEP is completely disabled.
- DEP_DISABLED,
- // DEP is permanently enforced.
- DEP_ENABLED,
- // DEP with support for ATL7 thunking is permanently enforced.
- DEP_ENABLED_ATL7_COMPAT,
-};
-
-// Change the Data Execution Prevention (DEP) status for the current process.
-// Once enabled, it cannot be disabled.
-bool SetCurrentProcessDEP(DepEnforcement enforcement);
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_DEP_H__
diff --git a/sandbox/win/src/dep_test.cc b/sandbox/win/src/dep_test.cc
deleted file mode 100644
index 2817caa..0000000
--- a/sandbox/win/src/dep_test.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/dep.h"
-
-#include "sandbox/win/src/sandbox_utils.h"
-#include "sandbox/win/tests/common/controller.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace sandbox {
-
-namespace {
-
-BYTE kReturnCode[] = {
- // ret
- 0xC3,
-};
-
-typedef void (*NullFunction)();
-
-// This doesn't fail on Vista Service Pack 0 but it does on XP SP2 and Vista
-// SP1. I guess this is a bug in Vista SP0 w.r.t .data PE section. Needs
-// investigation to be sure it is a bug and not an error on my part.
-bool GenerateDepException() {
- bool result = false;
- __try {
- void* code = kReturnCode;
- // Call this code.
- reinterpret_cast<NullFunction>(code)();
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- result = true;
- }
- return result;
-}
-
-bool GenerateDepAtl7Exception() {
- // TODO(maruel): bug 1207762 Somehow test ATL7
- return GenerateDepException();
-}
-
-SBOX_TESTS_COMMAND int CheckDepLevel(int argc, wchar_t **argv) {
- if (1 != argc)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- int flag = _wtoi(argv[0]);
- switch (flag) {
- case 1:
- // DEP is completely disabled.
- if (!SetCurrentProcessDEP(DEP_DISABLED)) {
- if (!IsXPSP2OrLater())
- // That's fine.
- return SBOX_TEST_SUCCEEDED;
- return SBOX_TEST_DENIED;
- }
- if (GenerateDepException())
- return SBOX_TEST_FAILED;
- if (GenerateDepAtl7Exception())
- return SBOX_TEST_FAILED;
- return SBOX_TEST_SUCCEEDED;
- case 2:
- // DEP is enabled with ATL7 thunk support.
- if (!SetCurrentProcessDEP(DEP_ENABLED_ATL7_COMPAT)) {
- if (!IsXPSP2OrLater())
- // That's fine.
- return SBOX_TEST_SUCCEEDED;
- return SBOX_TEST_DENIED;
- }
- if (!GenerateDepException())
- return SBOX_TEST_FAILED;
- if (GenerateDepAtl7Exception())
- return SBOX_TEST_FAILED;
- return SBOX_TEST_SUCCEEDED;
- case 3:
- // DEP is enabled.
- if (!SetCurrentProcessDEP(DEP_ENABLED)) {
- if (!IsXPSP2OrLater())
- // That's fine.
- return SBOX_TEST_SUCCEEDED;
- return SBOX_TEST_DENIED;
- }
- if (!GenerateDepException())
- return SBOX_TEST_FAILED;
- if (!GenerateDepAtl7Exception())
- return SBOX_TEST_FAILED;
- return SBOX_TEST_SUCCEEDED;
- case 4:
- // DEP can't be disabled.
- if (!SetCurrentProcessDEP(DEP_ENABLED)) {
- if (!IsXPSP2OrLater())
- // That's fine.
- return SBOX_TEST_SUCCEEDED;
- }
- if (SetCurrentProcessDEP(DEP_DISABLED)) {
- return SBOX_TEST_DENIED;
- }
- // Verify that it is still enabled.
- if (!GenerateDepException())
- return SBOX_TEST_FAILED;
- if (!GenerateDepAtl7Exception())
- return SBOX_TEST_FAILED;
- return SBOX_TEST_SUCCEEDED;
- case 5:
- // DEP can't be disabled.
- if (!SetCurrentProcessDEP(DEP_ENABLED_ATL7_COMPAT)) {
- if (!IsXPSP2OrLater())
- // That's fine.
- return SBOX_TEST_SUCCEEDED;
- }
- if (SetCurrentProcessDEP(DEP_DISABLED)) {
- return SBOX_TEST_DENIED;
- }
- // Verify that it is still enabled.
- if (!GenerateDepException())
- return SBOX_TEST_FAILED;
- if (!GenerateDepAtl7Exception())
- return SBOX_TEST_FAILED;
- return SBOX_TEST_SUCCEEDED;
- case 6:
- // DEP can't be disabled.
- if (!SetCurrentProcessDEP(DEP_ENABLED)) {
- if (!IsXPSP2OrLater())
- // That's fine.
- return SBOX_TEST_SUCCEEDED;
- }
- if (SetCurrentProcessDEP(DEP_ENABLED_ATL7_COMPAT)) {
- return SBOX_TEST_DENIED;
- }
- // Verify that it is still enabled.
- if (!GenerateDepException())
- return SBOX_TEST_FAILED;
- if (!GenerateDepAtl7Exception())
- return SBOX_TEST_FAILED;
- return SBOX_TEST_SUCCEEDED;
- default:
- return SBOX_TEST_INVALID_PARAMETER;
- }
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-}
-
-} // namespace
-
-// This test is disabled. See bug 1275842
-TEST(DepTest, DISABLED_TestDepDisable) {
- TestRunner runner(JOB_UNPROTECTED, USER_INTERACTIVE, USER_INTERACTIVE);
-
- runner.SetTimeout(INFINITE);
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckDepLevel 1"));
- // TODO(maruel): bug 1207762 Somehow test ATL7
- // EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckDepLevel 2"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckDepLevel 3"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckDepLevel 4"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckDepLevel 5"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckDepLevel 6"));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/eat_resolver.cc b/sandbox/win/src/eat_resolver.cc
deleted file mode 100644
index 8e81820..0000000
--- a/sandbox/win/src/eat_resolver.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/eat_resolver.h"
-
-#include "base/win/pe_image.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-
-namespace sandbox {
-
-NTSTATUS EatResolverThunk::Setup(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes,
- size_t* storage_used) {
- NTSTATUS ret = Init(target_module, interceptor_module, target_name,
- interceptor_name, interceptor_entry_point,
- thunk_storage, storage_bytes);
- if (!NT_SUCCESS(ret))
- return ret;
-
- if (!eat_entry_)
- return STATUS_INVALID_PARAMETER;
-
- size_t thunk_bytes = GetInternalThunkSize();
-
-#if defined(_WIN64)
- // We have two thunks, in order: the return path and the forward path.
- if (!SetInternalThunk(thunk_storage, storage_bytes, NULL, target_))
- return STATUS_BUFFER_TOO_SMALL;
-
- storage_bytes -= thunk_bytes;
- thunk_storage = reinterpret_cast<char*>(thunk_storage) + thunk_bytes;
-#endif
-
- if (!SetInternalThunk(thunk_storage, storage_bytes, target_, interceptor_))
- return STATUS_BUFFER_TOO_SMALL;
-
- AutoProtectMemory memory;
- memory.ChangeProtection(eat_entry_, sizeof(DWORD), PAGE_READWRITE);
-
- // Perform the patch.
-#pragma warning(push)
-#pragma warning(disable: 4311)
- // These casts generate warnings because they are 32 bit specific.
- *eat_entry_ = reinterpret_cast<DWORD>(thunk_storage) -
- reinterpret_cast<DWORD>(target_module);
-#pragma warning(pop)
-
- if (NULL != storage_used)
- *storage_used = GetThunkSize();
-
- return ret;
-}
-
-NTSTATUS EatResolverThunk::ResolveTarget(const void* module,
- const char* function_name,
- void** address) {
- DCHECK_NT(address);
- if (!module)
- return STATUS_INVALID_PARAMETER;
-
- base::win::PEImage pe(module);
- if (!pe.VerifyMagic())
- return STATUS_INVALID_IMAGE_FORMAT;
-
- eat_entry_ = pe.GetExportEntry(function_name);
-
- if (!eat_entry_)
- return STATUS_PROCEDURE_NOT_FOUND;
-
- *address = pe.RVAToAddr(*eat_entry_);
-
- return STATUS_SUCCESS;
-}
-
-size_t EatResolverThunk::GetThunkSize() const {
-#if defined(_WIN64)
- return GetInternalThunkSize() * 2;
-#else
- return GetInternalThunkSize();
-#endif
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/eat_resolver.h b/sandbox/win/src/eat_resolver.h
deleted file mode 100644
index 5e4b6e8..0000000
--- a/sandbox/win/src/eat_resolver.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_EAT_RESOLVER_H__
-#define SANDBOX_SRC_EAT_RESOLVER_H__
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/resolver.h"
-
-namespace sandbox {
-
-// This is the concrete resolver used to perform exports table interceptions.
-class EatResolverThunk : public ResolverThunk {
- public:
- EatResolverThunk() : eat_entry_(NULL) {}
- virtual ~EatResolverThunk() {}
-
- // Implementation of Resolver::Setup.
- virtual NTSTATUS Setup(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes,
- size_t* storage_used);
-
- // Implementation of Resolver::ResolveTarget.
- virtual NTSTATUS ResolveTarget(const void* module,
- const char* function_name,
- void** address);
-
- // Implementation of Resolver::GetThunkSize.
- virtual size_t GetThunkSize() const;
-
- private:
- // The entry to patch.
- DWORD* eat_entry_;
-
- DISALLOW_COPY_AND_ASSIGN(EatResolverThunk);
-};
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_EAT_RESOLVER_H__
diff --git a/sandbox/win/src/file_policy_test.cc b/sandbox/win/src/file_policy_test.cc
deleted file mode 100644
index ef33101..0000000
--- a/sandbox/win/src/file_policy_test.cc
+++ /dev/null
@@ -1,598 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <algorithm>
-#include <cctype>
-
-#include <windows.h>
-#include <winioctl.h>
-
-#include "base/win/scoped_handle.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/sandbox_policy.h"
-#include "sandbox/win/src/win_utils.h"
-#include "sandbox/win/tests/common/controller.h"
-#include "sandbox/win/tests/common/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#define BINDNTDLL(name) \
- name ## Function name = reinterpret_cast<name ## Function>( \
- ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), #name))
-
-namespace sandbox {
-
-const ULONG kSharing = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;
-
-// Creates a file using different desired access. Returns if the call succeeded
-// or not. The first argument in argv is the filename. If the second argument
-// is "read", we try read only access. Otherwise we try read-write access.
-SBOX_TESTS_COMMAND int File_Create(int argc, wchar_t **argv) {
- if (argc != 2)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- bool read = (_wcsicmp(argv[0], L"Read") == 0);
-
- if (read) {
- base::win::ScopedHandle file1(CreateFile(
- argv[1], GENERIC_READ, kSharing, NULL, OPEN_EXISTING, 0, NULL));
- base::win::ScopedHandle file2(CreateFile(
- argv[1], FILE_EXECUTE, kSharing, NULL, OPEN_EXISTING, 0, NULL));
-
- if (file1.Get() && file2.Get())
- return SBOX_TEST_SUCCEEDED;
- return SBOX_TEST_DENIED;
- } else {
- base::win::ScopedHandle file1(CreateFile(
- argv[1], GENERIC_ALL, kSharing, NULL, OPEN_EXISTING, 0, NULL));
- base::win::ScopedHandle file2(CreateFile(
- argv[1], GENERIC_READ | FILE_WRITE_DATA, kSharing, NULL, OPEN_EXISTING,
- 0, NULL));
-
- if (file1.Get() && file2.Get())
- return SBOX_TEST_SUCCEEDED;
- return SBOX_TEST_DENIED;
- }
-}
-
-SBOX_TESTS_COMMAND int File_Win32Create(int argc, wchar_t **argv) {
- if (argc != 1) {
- SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
- }
-
- std::wstring full_path = MakePathToSys(argv[0], false);
- if (full_path.empty()) {
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
- }
-
- HANDLE file = ::CreateFileW(full_path.c_str(), GENERIC_READ, kSharing,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if (INVALID_HANDLE_VALUE != file) {
- ::CloseHandle(file);
- return SBOX_TEST_SUCCEEDED;
- } else {
- if (ERROR_ACCESS_DENIED == ::GetLastError()) {
- return SBOX_TEST_DENIED;
- } else {
- return SBOX_TEST_FAILED;
- }
- }
- return SBOX_TEST_SUCCEEDED;
-}
-
-// Creates the file in parameter using the NtCreateFile api and returns if the
-// call succeeded or not.
-SBOX_TESTS_COMMAND int File_CreateSys32(int argc, wchar_t **argv) {
- BINDNTDLL(NtCreateFile);
- BINDNTDLL(RtlInitUnicodeString);
- if (!NtCreateFile || !RtlInitUnicodeString)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- if (argc != 1)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- std::wstring file(argv[0]);
- if (0 != _wcsnicmp(file.c_str(), kNTObjManPrefix, kNTObjManPrefixLen))
- file = MakePathToSys(argv[0], true);
-
- UNICODE_STRING object_name;
- RtlInitUnicodeString(&object_name, file.c_str());
-
- OBJECT_ATTRIBUTES obj_attributes = {0};
- InitializeObjectAttributes(&obj_attributes, &object_name,
- OBJ_CASE_INSENSITIVE, NULL, NULL);
-
- HANDLE handle;
- IO_STATUS_BLOCK io_block = {0};
- NTSTATUS status = NtCreateFile(&handle, FILE_READ_DATA, &obj_attributes,
- &io_block, NULL, 0, kSharing, FILE_OPEN,
- 0, NULL, 0);
- if (NT_SUCCESS(status)) {
- ::CloseHandle(handle);
- return SBOX_TEST_SUCCEEDED;
- } else if (STATUS_ACCESS_DENIED == status) {
- return SBOX_TEST_DENIED;
- } else if (STATUS_OBJECT_NAME_NOT_FOUND == status) {
- return SBOX_TEST_NOT_FOUND;
- }
- return SBOX_TEST_FAILED;
-}
-
-// Opens the file in parameter using the NtOpenFile api and returns if the
-// call succeeded or not.
-SBOX_TESTS_COMMAND int File_OpenSys32(int argc, wchar_t **argv) {
- BINDNTDLL(NtOpenFile);
- BINDNTDLL(RtlInitUnicodeString);
- if (!NtOpenFile || !RtlInitUnicodeString)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- if (argc != 1)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- std::wstring file = MakePathToSys(argv[0], true);
- UNICODE_STRING object_name;
- RtlInitUnicodeString(&object_name, file.c_str());
-
- OBJECT_ATTRIBUTES obj_attributes = {0};
- InitializeObjectAttributes(&obj_attributes, &object_name,
- OBJ_CASE_INSENSITIVE, NULL, NULL);
-
- HANDLE handle;
- IO_STATUS_BLOCK io_block = {0};
- NTSTATUS status = NtOpenFile(&handle, FILE_READ_DATA, &obj_attributes,
- &io_block, kSharing, 0);
- if (NT_SUCCESS(status)) {
- ::CloseHandle(handle);
- return SBOX_TEST_SUCCEEDED;
- } else if (STATUS_ACCESS_DENIED == status) {
- return SBOX_TEST_DENIED;
- } else if (STATUS_OBJECT_NAME_NOT_FOUND == status) {
- return SBOX_TEST_NOT_FOUND;
- }
- return SBOX_TEST_FAILED;
-}
-
-SBOX_TESTS_COMMAND int File_GetDiskSpace(int argc, wchar_t **argv) {
- std::wstring sys_path = MakePathToSys(L"", false);
- if (sys_path.empty()) {
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
- }
- ULARGE_INTEGER free_user = {0};
- ULARGE_INTEGER total = {0};
- ULARGE_INTEGER free_total = {0};
- if (::GetDiskFreeSpaceExW(sys_path.c_str(), &free_user, &total,
- &free_total)) {
- if ((total.QuadPart != 0) && (free_total.QuadPart !=0)) {
- return SBOX_TEST_SUCCEEDED;
- }
- } else {
- if (ERROR_ACCESS_DENIED == ::GetLastError()) {
- return SBOX_TEST_DENIED;
- } else {
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
- }
- }
- return SBOX_TEST_SUCCEEDED;
-}
-
-// Move a file using the MoveFileEx api and returns if the call succeeded or
-// not.
-SBOX_TESTS_COMMAND int File_Rename(int argc, wchar_t **argv) {
- if (argc != 2)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- if (::MoveFileEx(argv[0], argv[1], 0))
- return SBOX_TEST_SUCCEEDED;
-
- if (::GetLastError() != ERROR_ACCESS_DENIED)
- return SBOX_TEST_FAILED;
-
- return SBOX_TEST_DENIED;
-}
-
-// Query the attributes of file in parameter using the NtQueryAttributesFile api
-// and NtQueryFullAttributesFile and returns if the call succeeded or not. The
-// second argument in argv is "d" or "f" telling if we expect the attributes to
-// specify a file or a directory. The expected attribute has to match the real
-// attributes for the call to be successful.
-SBOX_TESTS_COMMAND int File_QueryAttributes(int argc, wchar_t **argv) {
- BINDNTDLL(NtQueryAttributesFile);
- BINDNTDLL(NtQueryFullAttributesFile);
- BINDNTDLL(RtlInitUnicodeString);
- if (!NtQueryAttributesFile || !NtQueryFullAttributesFile ||
- !RtlInitUnicodeString)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- if (argc != 2)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- bool expect_directory = (L'd' == argv[1][0]);
-
- UNICODE_STRING object_name;
- std::wstring file = MakePathToSys(argv[0], true);
- RtlInitUnicodeString(&object_name, file.c_str());
-
- OBJECT_ATTRIBUTES obj_attributes = {0};
- InitializeObjectAttributes(&obj_attributes, &object_name,
- OBJ_CASE_INSENSITIVE, NULL, NULL);
-
- FILE_BASIC_INFORMATION info = {0};
- FILE_NETWORK_OPEN_INFORMATION full_info = {0};
- NTSTATUS status1 = NtQueryAttributesFile(&obj_attributes, &info);
- NTSTATUS status2 = NtQueryFullAttributesFile(&obj_attributes, &full_info);
-
- if (status1 != status2)
- return SBOX_TEST_FAILED;
-
- if (NT_SUCCESS(status1)) {
- if (info.FileAttributes != full_info.FileAttributes)
- return SBOX_TEST_FAILED;
-
- bool is_directory1 = (info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
- if (expect_directory == is_directory1)
- return SBOX_TEST_SUCCEEDED;
- } else if (STATUS_ACCESS_DENIED == status1) {
- return SBOX_TEST_DENIED;
- } else if (STATUS_OBJECT_NAME_NOT_FOUND == status1) {
- return SBOX_TEST_NOT_FOUND;
- }
-
- return SBOX_TEST_FAILED;
-}
-
-TEST(FilePolicyTest, DenyNtCreateCalc) {
- TestRunner runner;
- EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_DIR_ANY,
- L"calc.exe"));
-
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_CreateSys32 calc.exe"));
-
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_CreateSys32 calc.exe"));
-}
-
-TEST(FilePolicyTest, AllowNtCreateCalc) {
- TestRunner runner;
- EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY, L"calc.exe"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_CreateSys32 calc.exe"));
-
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_CreateSys32 calc.exe"));
-}
-
-TEST(FilePolicyTest, AllowNtCreateWithNativePath) {
- std::wstring calc = MakePathToSys(L"calc.exe", false);
- std::wstring nt_path;
- ASSERT_TRUE(GetNtPathFromWin32Path(calc, &nt_path));
- TestRunner runner;
- runner.AddFsRule(TargetPolicy::FILES_ALLOW_READONLY, nt_path.c_str());
-
- wchar_t buff[MAX_PATH];
- ::wsprintfW(buff, L"File_CreateSys32 %s", nt_path.c_str());
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(buff));
-
- std::transform(nt_path.begin(), nt_path.end(), nt_path.begin(), std::tolower);
- ::wsprintfW(buff, L"File_CreateSys32 %s", nt_path.c_str());
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(buff));
-}
-
-TEST(FilePolicyTest, AllowReadOnly) {
- TestRunner runner;
-
- // Create a temp file because we need write access to it.
- wchar_t temp_directory[MAX_PATH];
- wchar_t temp_file_name[MAX_PATH];
- ASSERT_NE(::GetTempPath(MAX_PATH, temp_directory), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name), 0u);
-
- EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_READONLY,
- temp_file_name));
-
- wchar_t command_read[MAX_PATH + 20] = {0};
- wsprintf(command_read, L"File_Create Read \"%ls\"", temp_file_name);
- wchar_t command_write[MAX_PATH + 20] = {0};
- wsprintf(command_write, L"File_Create Write \"%ls\"", temp_file_name);
-
- // Verify that we have read access after revert.
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command_read));
-
- // Verify that we don't have write access after revert.
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command_write));
-
- // Verify that we really have write access to the file.
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command_write));
-
- DeleteFile(temp_file_name);
-}
-
-TEST(FilePolicyTest, AllowWildcard) {
- TestRunner runner;
-
- // Create a temp file because we need write access to it.
- wchar_t temp_directory[MAX_PATH];
- wchar_t temp_file_name[MAX_PATH];
- ASSERT_NE(::GetTempPath(MAX_PATH, temp_directory), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name), 0u);
-
- wcscat_s(temp_directory, MAX_PATH, L"*");
- EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_directory));
-
- wchar_t command_write[MAX_PATH + 20] = {0};
- wsprintf(command_write, L"File_Create Write \"%ls\"", temp_file_name);
-
- // Verify that we have write access after revert.
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command_write));
-
- DeleteFile(temp_file_name);
-}
-
-TEST(FilePolicyTest, AllowNtCreatePatternRule) {
- TestRunner runner;
- EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY, L"App*.dll"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED,
- runner.RunTest(L"File_OpenSys32 appmgmts.dll"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_OpenSys32 appwiz.cpl"));
-
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED,
- runner.RunTest(L"File_OpenSys32 appmgmts.dll"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_OpenSys32 appwiz.cpl"));
-}
-
-TEST(FilePolicyTest, CheckNotFound) {
- TestRunner runner;
- EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY, L"n*.dll"));
-
- EXPECT_EQ(SBOX_TEST_NOT_FOUND,
- runner.RunTest(L"File_OpenSys32 notfound.dll"));
-}
-
-TEST(FilePolicyTest, CheckNoLeak) {
- TestRunner runner;
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_CreateSys32 notfound.exe"));
-}
-
-TEST(FilePolicyTest, TestQueryAttributesFile) {
- TestRunner runner;
- EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY,
- L"appmgmts.dll"));
- EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY,
- L"notfound.exe"));
- EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY, L"drivers"));
- EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_QUERY,
- L"ipconfig.exe"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED,
- runner.RunTest(L"File_QueryAttributes drivers d"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED,
- runner.RunTest(L"File_QueryAttributes appmgmts.dll f"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED,
- runner.RunTest(L"File_QueryAttributes ipconfig.exe f"));
-
- EXPECT_EQ(SBOX_TEST_DENIED,
- runner.RunTest(L"File_QueryAttributes ftp.exe f"));
-
- EXPECT_EQ(SBOX_TEST_NOT_FOUND,
- runner.RunTest(L"File_QueryAttributes notfound.exe f"));
-}
-
-// Makes sure that we don't leak information when there is not policy to allow
-// a path.
-TEST(FilePolicyTest, TestQueryAttributesFileNoPolicy) {
- TestRunner runner;
- EXPECT_EQ(SBOX_TEST_DENIED,
- runner.RunTest(L"File_QueryAttributes ftp.exe f"));
-
- EXPECT_EQ(SBOX_TEST_DENIED,
- runner.RunTest(L"File_QueryAttributes notfound.exe f"));
-}
-
-TEST(FilePolicyTest, TestRename) {
- TestRunner runner;
-
- // Give access to the temp directory.
- wchar_t temp_directory[MAX_PATH];
- wchar_t temp_file_name1[MAX_PATH];
- wchar_t temp_file_name2[MAX_PATH];
- wchar_t temp_file_name3[MAX_PATH];
- wchar_t temp_file_name4[MAX_PATH];
- wchar_t temp_file_name5[MAX_PATH];
- wchar_t temp_file_name6[MAX_PATH];
- wchar_t temp_file_name7[MAX_PATH];
- wchar_t temp_file_name8[MAX_PATH];
- ASSERT_NE(::GetTempPath(MAX_PATH, temp_directory), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name1), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name2), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name3), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name4), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name5), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name6), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name7), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name8), 0u);
-
-
- // Add rules to make file1->file2 succeed.
- ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_file_name1));
- ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_file_name2));
-
- // Add rules to make file3->file4 fail.
- ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_file_name3));
- ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_READONLY,
- temp_file_name4));
-
- // Add rules to make file5->file6 fail.
- ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_READONLY,
- temp_file_name5));
- ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_file_name6));
-
- // Add rules to make file7->no_pol_file fail.
- ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_file_name7));
-
- // Delete the files where the files are going to be renamed to.
- ::DeleteFile(temp_file_name2);
- ::DeleteFile(temp_file_name4);
- ::DeleteFile(temp_file_name6);
- ::DeleteFile(temp_file_name8);
-
-
- wchar_t command[MAX_PATH*2 + 20] = {0};
- wsprintf(command, L"File_Rename \"%ls\" \"%ls\"", temp_file_name1,
- temp_file_name2);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command));
-
- wsprintf(command, L"File_Rename \"%ls\" \"%ls\"", temp_file_name3,
- temp_file_name4);
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command));
-
- wsprintf(command, L"File_Rename \"%ls\" \"%ls\"", temp_file_name5,
- temp_file_name6);
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command));
-
- wsprintf(command, L"File_Rename \"%ls\" \"%ls\"", temp_file_name7,
- temp_file_name8);
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command));
-
-
- // Delete all the files in case they are still there.
- ::DeleteFile(temp_file_name1);
- ::DeleteFile(temp_file_name2);
- ::DeleteFile(temp_file_name3);
- ::DeleteFile(temp_file_name4);
- ::DeleteFile(temp_file_name5);
- ::DeleteFile(temp_file_name6);
- ::DeleteFile(temp_file_name7);
- ::DeleteFile(temp_file_name8);
-}
-
-TEST(FilePolicyTest, OpenSys32FilesDenyBecauseOfDir) {
- TestRunner runner;
- EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_DIR_ANY,
- L"notepad.exe"));
-
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_Win32Create notepad.exe"));
-
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED,
- runner.RunTest(L"File_Win32Create notepad.exe"));
-}
-
-TEST(FilePolicyTest, OpenSys32FilesAllowNotepad) {
- TestRunner runner;
- EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY,
- L"notepad.exe"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED,
- runner.RunTest(L"File_Win32Create notepad.exe"));
-
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_Win32Create calc.exe"));
-
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED,
- runner.RunTest(L"File_Win32Create notepad.exe"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_Win32Create calc.exe"));
-}
-
-TEST(FilePolicyTest, FileGetDiskSpace) {
- TestRunner runner;
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_GetDiskSpace"));
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_GetDiskSpace"));
-
- // Add an 'allow' rule in the windows\system32 such that GetDiskFreeSpaceEx
- // succeeds (it does an NtOpenFile) but windows\system32\notepad.exe is
- // denied since there is no wild card in the rule.
- EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_DIR_ANY, L""));
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_GetDiskSpace"));
-
- runner.SetTestState(AFTER_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_GetDiskSpace"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_Win32Create notepad.exe"));
-}
-
-TEST(FilePolicyTest, TestReparsePoint) {
- TestRunner runner;
-
- // Create a temp file because we need write access to it.
- wchar_t temp_directory[MAX_PATH];
- wchar_t temp_file_name[MAX_PATH];
- ASSERT_NE(::GetTempPath(MAX_PATH, temp_directory), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name), 0u);
-
- // Delete the file and create a directory instead.
- ASSERT_TRUE(::DeleteFile(temp_file_name));
- ASSERT_TRUE(::CreateDirectory(temp_file_name, NULL));
-
- // Create a temporary file in the subfolder.
- std::wstring subfolder = temp_file_name;
- std::wstring temp_file_title = subfolder.substr(subfolder.rfind(L"\\") + 1);
- std::wstring temp_file = subfolder + L"\\file_" + temp_file_title;
-
- HANDLE file = ::CreateFile(temp_file.c_str(), FILE_ALL_ACCESS,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- CREATE_ALWAYS, 0, NULL);
- ASSERT_TRUE(INVALID_HANDLE_VALUE != file);
- ASSERT_TRUE(::CloseHandle(file));
-
- // Create a temporary file in the temp directory.
- std::wstring temp_dir = temp_directory;
- std::wstring temp_file_in_temp = temp_dir + L"file_" + temp_file_title;
- file = ::CreateFile(temp_file_in_temp.c_str(), FILE_ALL_ACCESS,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- CREATE_ALWAYS, 0, NULL);
- ASSERT_TRUE(file != NULL);
- ASSERT_TRUE(::CloseHandle(file));
-
- // Give write access to the temp directory.
- std::wstring temp_dir_wildcard = temp_dir + L"*";
- EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY,
- temp_dir_wildcard.c_str()));
-
- // Prepare the command to execute.
- std::wstring command_write;
- command_write += L"File_Create Write \"";
- command_write += temp_file;
- command_write += L"\"";
-
- // Verify that we have write access to the original file
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command_write.c_str()));
-
- // Replace the subfolder by a reparse point to %temp%.
- ::DeleteFile(temp_file.c_str());
- HANDLE dir = ::CreateFile(subfolder.c_str(), FILE_ALL_ACCESS,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
- EXPECT_TRUE(INVALID_HANDLE_VALUE != dir);
-
- std::wstring temp_dir_nt;
- temp_dir_nt += L"\\??\\";
- temp_dir_nt += temp_dir;
- EXPECT_TRUE(SetReparsePoint(dir, temp_dir_nt.c_str()));
- EXPECT_TRUE(::CloseHandle(dir));
-
- // Try to open the file again.
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command_write.c_str()));
-
- // Remove the reparse point.
- dir = ::CreateFile(subfolder.c_str(), FILE_ALL_ACCESS,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
- NULL);
- EXPECT_TRUE(INVALID_HANDLE_VALUE != dir);
- EXPECT_TRUE(DeleteReparsePoint(dir));
- EXPECT_TRUE(::CloseHandle(dir));
-
- // Cleanup.
- EXPECT_TRUE(::DeleteFile(temp_file_in_temp.c_str()));
- EXPECT_TRUE(::RemoveDirectory(subfolder.c_str()));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/filesystem_dispatcher.cc b/sandbox/win/src/filesystem_dispatcher.cc
deleted file mode 100644
index 22240ff..0000000
--- a/sandbox/win/src/filesystem_dispatcher.cc
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/filesystem_dispatcher.h"
-
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/filesystem_interception.h"
-#include "sandbox/win/src/filesystem_policy.h"
-#include "sandbox/win/src/interception.h"
-#include "sandbox/win/src/interceptors.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_broker.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-
-namespace sandbox {
-
-FilesystemDispatcher::FilesystemDispatcher(PolicyBase* policy_base)
- : policy_base_(policy_base) {
- static const IPCCall create_params = {
- {IPC_NTCREATEFILE_TAG, WCHAR_TYPE, ULONG_TYPE, ULONG_TYPE, ULONG_TYPE,
- ULONG_TYPE, ULONG_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(&FilesystemDispatcher::NtCreateFile)
- };
-
- static const IPCCall open_file = {
- {IPC_NTOPENFILE_TAG, WCHAR_TYPE, ULONG_TYPE, ULONG_TYPE, ULONG_TYPE,
- ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(&FilesystemDispatcher::NtOpenFile)
- };
-
- static const IPCCall attribs = {
- {IPC_NTQUERYATTRIBUTESFILE_TAG, WCHAR_TYPE, ULONG_TYPE, INOUTPTR_TYPE},
- reinterpret_cast<CallbackGeneric>(
- &FilesystemDispatcher::NtQueryAttributesFile)
- };
-
- static const IPCCall full_attribs = {
- {IPC_NTQUERYFULLATTRIBUTESFILE_TAG, WCHAR_TYPE, ULONG_TYPE, INOUTPTR_TYPE},
- reinterpret_cast<CallbackGeneric>(
- &FilesystemDispatcher::NtQueryFullAttributesFile)
- };
-
- static const IPCCall set_info = {
- {IPC_NTSETINFO_RENAME_TAG, VOIDPTR_TYPE, INOUTPTR_TYPE, INOUTPTR_TYPE,
- ULONG_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(
- &FilesystemDispatcher::NtSetInformationFile)
- };
-
- ipc_calls_.push_back(create_params);
- ipc_calls_.push_back(open_file);
- ipc_calls_.push_back(attribs);
- ipc_calls_.push_back(full_attribs);
- ipc_calls_.push_back(set_info);
-}
-
-bool FilesystemDispatcher::SetupService(InterceptionManager* manager,
- int service) {
- switch (service) {
- case IPC_NTCREATEFILE_TAG:
- return INTERCEPT_NT(manager, NtCreateFile, CREATE_FILE_ID, 48);
-
- case IPC_NTOPENFILE_TAG:
- return INTERCEPT_NT(manager, NtOpenFile, OPEN_FILE_ID, 28);
-
- case IPC_NTQUERYATTRIBUTESFILE_TAG:
- return INTERCEPT_NT(manager, NtQueryAttributesFile, QUERY_ATTRIB_FILE_ID,
- 12);
-
- case IPC_NTQUERYFULLATTRIBUTESFILE_TAG:
- return INTERCEPT_NT(manager, NtQueryFullAttributesFile,
- QUERY_FULL_ATTRIB_FILE_ID, 12);
-
- case IPC_NTSETINFO_RENAME_TAG:
- return INTERCEPT_NT(manager, NtSetInformationFile, SET_INFO_FILE_ID, 24);
-
- default:
- return false;
- }
-}
-
-bool FilesystemDispatcher::NtCreateFile(
- IPCInfo* ipc, std::wstring* name, DWORD attributes, DWORD desired_access,
- DWORD file_attributes, DWORD share_access, DWORD create_disposition,
- DWORD create_options) {
- if (!PreProcessName(*name, name)) {
- // The path requested might contain a reparse point.
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- const wchar_t* filename = name->c_str();
-
- ULONG broker = TRUE;
- CountedParameterSet<OpenFile> params;
- params[OpenFile::NAME] = ParamPickerMake(filename);
- params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
- params[OpenFile::OPTIONS] = ParamPickerMake(create_options);
- params[OpenFile::BROKER] = ParamPickerMake(broker);
-
- // To evaluate the policy we need to call back to the policy object. We
- // are just middlemen in the operation since is the FileSystemPolicy which
- // knows what to do.
- EvalResult result = policy_base_->EvalPolicy(IPC_NTCREATEFILE_TAG,
- params.GetBase());
- HANDLE handle;
- ULONG_PTR io_information = 0;
- NTSTATUS nt_status;
- if (!FileSystemPolicy::CreateFileAction(result, *ipc->client_info, *name,
- attributes, desired_access,
- file_attributes, share_access,
- create_disposition, create_options,
- &handle, &nt_status,
- &io_information)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- // Return operation status on the IPC.
- ipc->return_info.extended[0].ulong_ptr = io_information;
- ipc->return_info.nt_status = nt_status;
- ipc->return_info.handle = handle;
- return true;
-}
-
-bool FilesystemDispatcher::NtOpenFile(
- IPCInfo* ipc, std::wstring* name, DWORD attributes, DWORD desired_access,
- DWORD share_access, DWORD open_options) {
- if (!PreProcessName(*name, name)) {
- // The path requested might contain a reparse point.
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- const wchar_t* filename = name->c_str();
-
- ULONG broker = TRUE;
- CountedParameterSet<OpenFile> params;
- params[OpenFile::NAME] = ParamPickerMake(filename);
- params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
- params[OpenFile::OPTIONS] = ParamPickerMake(open_options);
- params[OpenFile::BROKER] = ParamPickerMake(broker);
-
- // To evaluate the policy we need to call back to the policy object. We
- // are just middlemen in the operation since is the FileSystemPolicy which
- // knows what to do.
- EvalResult result = policy_base_->EvalPolicy(IPC_NTOPENFILE_TAG,
- params.GetBase());
- HANDLE handle;
- ULONG_PTR io_information = 0;
- NTSTATUS nt_status;
- if (!FileSystemPolicy::OpenFileAction(result, *ipc->client_info, *name,
- attributes, desired_access,
- share_access, open_options, &handle,
- &nt_status, &io_information)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- // Return operation status on the IPC.
- ipc->return_info.extended[0].ulong_ptr = io_information;
- ipc->return_info.nt_status = nt_status;
- ipc->return_info.handle = handle;
- return true;
-}
-
-bool FilesystemDispatcher::NtQueryAttributesFile(
- IPCInfo* ipc, std::wstring* name, DWORD attributes, CountedBuffer* info) {
- if (sizeof(FILE_BASIC_INFORMATION) != info->Size())
- return false;
-
- if (!PreProcessName(*name, name)) {
- // The path requested might contain a reparse point.
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- ULONG broker = TRUE;
- const wchar_t* filename = name->c_str();
- CountedParameterSet<FileName> params;
- params[FileName::NAME] = ParamPickerMake(filename);
- params[FileName::BROKER] = ParamPickerMake(broker);
-
- // To evaluate the policy we need to call back to the policy object. We
- // are just middlemen in the operation since is the FileSystemPolicy which
- // knows what to do.
- EvalResult result = policy_base_->EvalPolicy(IPC_NTQUERYATTRIBUTESFILE_TAG,
- params.GetBase());
-
- FILE_BASIC_INFORMATION* information =
- reinterpret_cast<FILE_BASIC_INFORMATION*>(info->Buffer());
- NTSTATUS nt_status;
- if (!FileSystemPolicy::QueryAttributesFileAction(result, *ipc->client_info,
- *name, attributes,
- information, &nt_status)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- // Return operation status on the IPC.
- ipc->return_info.nt_status = nt_status;
- return true;
-}
-
-bool FilesystemDispatcher::NtQueryFullAttributesFile(
- IPCInfo* ipc, std::wstring* name, DWORD attributes, CountedBuffer* info) {
- if (sizeof(FILE_NETWORK_OPEN_INFORMATION) != info->Size())
- return false;
-
- if (!PreProcessName(*name, name)) {
- // The path requested might contain a reparse point.
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- ULONG broker = TRUE;
- const wchar_t* filename = name->c_str();
- CountedParameterSet<FileName> params;
- params[FileName::NAME] = ParamPickerMake(filename);
- params[FileName::BROKER] = ParamPickerMake(broker);
-
- // To evaluate the policy we need to call back to the policy object. We
- // are just middlemen in the operation since is the FileSystemPolicy which
- // knows what to do.
- EvalResult result = policy_base_->EvalPolicy(
- IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase());
-
- FILE_NETWORK_OPEN_INFORMATION* information =
- reinterpret_cast<FILE_NETWORK_OPEN_INFORMATION*>(info->Buffer());
- NTSTATUS nt_status;
- if (!FileSystemPolicy::QueryFullAttributesFileAction(result,
- *ipc->client_info,
- *name, attributes,
- information,
- &nt_status)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- // Return operation status on the IPC.
- ipc->return_info.nt_status = nt_status;
- return true;
-}
-
-bool FilesystemDispatcher::NtSetInformationFile(
- IPCInfo* ipc, HANDLE handle, CountedBuffer* status, CountedBuffer* info,
- DWORD length, DWORD info_class) {
- if (sizeof(IO_STATUS_BLOCK) != status->Size())
- return false;
- if (length != info->Size())
- return false;
-
- FILE_RENAME_INFORMATION* rename_info =
- reinterpret_cast<FILE_RENAME_INFORMATION*>(info->Buffer());
-
- if (!IsSupportedRenameCall(rename_info, length, info_class))
- return false;
-
- std::wstring name;
- name.assign(rename_info->FileName, rename_info->FileNameLength /
- sizeof(rename_info->FileName[0]));
- if (!PreProcessName(name, &name)) {
- // The path requested might contain a reparse point.
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- ULONG broker = TRUE;
- const wchar_t* filename = name.c_str();
- CountedParameterSet<FileName> params;
- params[FileName::NAME] = ParamPickerMake(filename);
- params[FileName::BROKER] = ParamPickerMake(broker);
-
- // To evaluate the policy we need to call back to the policy object. We
- // are just middlemen in the operation since is the FileSystemPolicy which
- // knows what to do.
- EvalResult result = policy_base_->EvalPolicy(IPC_NTSETINFO_RENAME_TAG,
- params.GetBase());
-
- IO_STATUS_BLOCK* io_status =
- reinterpret_cast<IO_STATUS_BLOCK*>(status->Buffer());
- NTSTATUS nt_status;
- if (!FileSystemPolicy::SetInformationFileAction(result, *ipc->client_info,
- handle, rename_info, length,
- info_class, io_status,
- &nt_status)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- // Return operation status on the IPC.
- ipc->return_info.nt_status = nt_status;
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/filesystem_dispatcher.h b/sandbox/win/src/filesystem_dispatcher.h
deleted file mode 100644
index b0d9a7a..0000000
--- a/sandbox/win/src/filesystem_dispatcher.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_FILESYSTEM_DISPATCHER_H__
-#define SANDBOX_SRC_FILESYSTEM_DISPATCHER_H__
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/sandbox_policy_base.h"
-
-namespace sandbox {
-
-// This class handles file system-related IPC calls.
-class FilesystemDispatcher : public Dispatcher {
- public:
- explicit FilesystemDispatcher(PolicyBase* policy_base);
- ~FilesystemDispatcher() {}
-
- // Dispatcher interface.
- virtual bool SetupService(InterceptionManager* manager, int service);
-
- private:
- // Processes IPC requests coming from calls to NtCreateFile in the target.
- bool NtCreateFile(IPCInfo* ipc, std::wstring* name, DWORD attributes,
- DWORD desired_access, DWORD file_attributes,
- DWORD share_access, DWORD create_disposition,
- DWORD create_options);
-
- // Processes IPC requests coming from calls to NtOpenFile in the target.
- bool NtOpenFile(IPCInfo* ipc, std::wstring* name, DWORD attributes,
- DWORD desired_access, DWORD share_access,
- DWORD create_options);
-
- // Processes IPC requests coming from calls to NtQueryAttributesFile in the
- // target.
- bool NtQueryAttributesFile(IPCInfo* ipc, std::wstring* name, DWORD attributes,
- CountedBuffer* info);
-
- // Processes IPC requests coming from calls to NtQueryFullAttributesFile in
- // the target.
- bool NtQueryFullAttributesFile(IPCInfo* ipc, std::wstring* name,
- DWORD attributes, CountedBuffer* info);
-
- // Processes IPC requests coming from calls to NtSetInformationFile with the
- // rename information class.
- bool NtSetInformationFile(IPCInfo* ipc, HANDLE handle, CountedBuffer* status,
- CountedBuffer* info, DWORD length,
- DWORD info_class);
-
- PolicyBase* policy_base_;
- DISALLOW_COPY_AND_ASSIGN(FilesystemDispatcher);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_FILESYSTEM_DISPATCHER_H__
diff --git a/sandbox/win/src/filesystem_interception.cc b/sandbox/win/src/filesystem_interception.cc
deleted file mode 100644
index 33688f0..0000000
--- a/sandbox/win/src/filesystem_interception.cc
+++ /dev/null
@@ -1,351 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/filesystem_interception.h"
-
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/policy_target.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "sandbox/win/src/target_services.h"
-
-namespace sandbox {
-
-NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
- PHANDLE file, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes,
- PIO_STATUS_BLOCK io_status,
- PLARGE_INTEGER allocation_size,
- ULONG file_attributes, ULONG sharing,
- ULONG disposition, ULONG options,
- PVOID ea_buffer, ULONG ea_length) {
- // Check if the process can open it first.
- NTSTATUS status = orig_CreateFile(file, desired_access, object_attributes,
- io_status, allocation_size,
- file_attributes, sharing, disposition,
- options, ea_buffer, ea_length);
- if (STATUS_ACCESS_DENIED != status)
- return status;
-
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return status;
-
- do {
- if (!ValidParameter(file, sizeof(HANDLE), WRITE))
- break;
- if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- wchar_t* name;
- uint32 attributes = 0;
- NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
- NULL);
- if (!NT_SUCCESS(ret) || NULL == name)
- break;
-
- ULONG broker = FALSE;
- CountedParameterSet<OpenFile> params;
- params[OpenFile::NAME] = ParamPickerMake(name);
- params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
- params[OpenFile::OPTIONS] = ParamPickerMake(options);
- params[OpenFile::BROKER] = ParamPickerMake(broker);
-
- if (!QueryBroker(IPC_NTCREATEFILE_TAG, params.GetBase()))
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- // The following call must match in the parameters with
- // FilesystemDispatcher::ProcessNtCreateFile.
- ResultCode code = CrossCall(ipc, IPC_NTCREATEFILE_TAG, name, attributes,
- desired_access, file_attributes, sharing,
- disposition, options, &answer);
-
- operator delete(name, NT_ALLOC);
-
- if (SBOX_ALL_OK != code)
- break;
-
- if (!NT_SUCCESS(answer.nt_status))
- return answer.nt_status;
-
- __try {
- *file = answer.handle;
- io_status->Status = answer.nt_status;
- io_status->Information = answer.extended[0].ulong_ptr;
- status = io_status->Status;
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- break;
- }
- } while (false);
-
- return status;
-}
-
-NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile, PHANDLE file,
- ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes,
- PIO_STATUS_BLOCK io_status, ULONG sharing,
- ULONG options) {
- // Check if the process can open it first.
- NTSTATUS status = orig_OpenFile(file, desired_access, object_attributes,
- io_status, sharing, options);
- if (STATUS_ACCESS_DENIED != status)
- return status;
-
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return status;
-
- do {
- if (!ValidParameter(file, sizeof(HANDLE), WRITE))
- break;
- if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- wchar_t* name;
- uint32 attributes;
- NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
- NULL);
- if (!NT_SUCCESS(ret) || NULL == name)
- break;
-
- ULONG broker = FALSE;
- CountedParameterSet<OpenFile> params;
- params[OpenFile::NAME] = ParamPickerMake(name);
- params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
- params[OpenFile::OPTIONS] = ParamPickerMake(options);
- params[OpenFile::BROKER] = ParamPickerMake(broker);
-
- if (!QueryBroker(IPC_NTOPENFILE_TAG, params.GetBase()))
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_NTOPENFILE_TAG, name, attributes,
- desired_access, sharing, options, &answer);
-
- operator delete(name, NT_ALLOC);
-
- if (SBOX_ALL_OK != code)
- break;
-
- if (!NT_SUCCESS(answer.nt_status))
- return answer.nt_status;
-
- __try {
- *file = answer.handle;
- io_status->Status = answer.nt_status;
- io_status->Information = answer.extended[0].ulong_ptr;
- status = io_status->Status;
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- break;
- }
- } while (false);
-
- return status;
-}
-
-NTSTATUS WINAPI TargetNtQueryAttributesFile(
- NtQueryAttributesFileFunction orig_QueryAttributes,
- POBJECT_ATTRIBUTES object_attributes,
- PFILE_BASIC_INFORMATION file_attributes) {
- // Check if the process can query it first.
- NTSTATUS status = orig_QueryAttributes(object_attributes, file_attributes);
- if (STATUS_ACCESS_DENIED != status)
- return status;
-
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return status;
-
- do {
- if (!ValidParameter(file_attributes, sizeof(FILE_BASIC_INFORMATION), WRITE))
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- wchar_t* name = NULL;
- uint32 attributes = 0;
- NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
- NULL);
- if (!NT_SUCCESS(ret) || NULL == name)
- break;
-
- InOutCountedBuffer file_info(file_attributes,
- sizeof(FILE_BASIC_INFORMATION));
-
- ULONG broker = FALSE;
- CountedParameterSet<FileName> params;
- params[FileName::NAME] = ParamPickerMake(name);
- params[FileName::BROKER] = ParamPickerMake(broker);
-
- if (!QueryBroker(IPC_NTQUERYATTRIBUTESFILE_TAG, params.GetBase()))
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_NTQUERYATTRIBUTESFILE_TAG, name,
- attributes, file_info, &answer);
-
- operator delete(name, NT_ALLOC);
-
- if (SBOX_ALL_OK != code)
- break;
-
- return answer.nt_status;
-
- } while (false);
-
- return status;
-}
-
-NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
- NtQueryFullAttributesFileFunction orig_QueryFullAttributes,
- POBJECT_ATTRIBUTES object_attributes,
- PFILE_NETWORK_OPEN_INFORMATION file_attributes) {
- // Check if the process can query it first.
- NTSTATUS status = orig_QueryFullAttributes(object_attributes,
- file_attributes);
- if (STATUS_ACCESS_DENIED != status)
- return status;
-
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return status;
-
- do {
- if (!ValidParameter(file_attributes, sizeof(FILE_NETWORK_OPEN_INFORMATION),
- WRITE))
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- wchar_t* name = NULL;
- uint32 attributes = 0;
- NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
- NULL);
- if (!NT_SUCCESS(ret) || NULL == name)
- break;
-
- InOutCountedBuffer file_info(file_attributes,
- sizeof(FILE_NETWORK_OPEN_INFORMATION));
-
- ULONG broker = FALSE;
- CountedParameterSet<FileName> params;
- params[FileName::NAME] = ParamPickerMake(name);
- params[FileName::BROKER] = ParamPickerMake(broker);
-
- if (!QueryBroker(IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase()))
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_NTQUERYFULLATTRIBUTESFILE_TAG, name,
- attributes, file_info, &answer);
-
- operator delete(name, NT_ALLOC);
-
- if (SBOX_ALL_OK != code)
- break;
-
- return answer.nt_status;
- } while (false);
-
- return status;
-}
-
-NTSTATUS WINAPI TargetNtSetInformationFile(
- NtSetInformationFileFunction orig_SetInformationFile, HANDLE file,
- PIO_STATUS_BLOCK io_status, PVOID file_info, ULONG length,
- FILE_INFORMATION_CLASS file_info_class) {
- // Check if the process can open it first.
- NTSTATUS status = orig_SetInformationFile(file, io_status, file_info, length,
- file_info_class);
- if (STATUS_ACCESS_DENIED != status)
- return status;
-
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return status;
-
- do {
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
- break;
-
- if (!ValidParameter(file_info, length, READ))
- break;
-
- FILE_RENAME_INFORMATION* file_rename_info =
- reinterpret_cast<FILE_RENAME_INFORMATION*>(file_info);
- OBJECT_ATTRIBUTES object_attributes;
- UNICODE_STRING object_name;
- InitializeObjectAttributes(&object_attributes, &object_name, 0, NULL, NULL);
-
- __try {
- if (!IsSupportedRenameCall(file_rename_info, length, file_info_class))
- break;
-
- object_attributes.RootDirectory = file_rename_info->RootDirectory;
- object_name.Buffer = file_rename_info->FileName;
- object_name.Length = object_name.MaximumLength =
- static_cast<USHORT>(file_rename_info->FileNameLength);
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- break;
- }
-
- wchar_t* name;
- NTSTATUS ret = AllocAndCopyName(&object_attributes, &name, NULL, NULL);
- if (!NT_SUCCESS(ret) || !name)
- break;
-
- ULONG broker = FALSE;
- CountedParameterSet<FileName> params;
- params[FileName::NAME] = ParamPickerMake(name);
- params[FileName::BROKER] = ParamPickerMake(broker);
-
- if (!QueryBroker(IPC_NTSETINFO_RENAME_TAG, params.GetBase()))
- break;
-
- InOutCountedBuffer io_status_buffer(io_status, sizeof(IO_STATUS_BLOCK));
- // This is actually not an InOut buffer, only In, but using InOut facility
- // really helps to simplify the code.
- InOutCountedBuffer file_info_buffer(file_info, length);
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_NTSETINFO_RENAME_TAG, file,
- io_status_buffer, file_info_buffer, length,
- file_info_class, &answer);
-
- if (SBOX_ALL_OK != code)
- break;
-
- status = answer.nt_status;
- } while (false);
-
- return status;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/filesystem_interception.h b/sandbox/win/src/filesystem_interception.h
deleted file mode 100644
index 2fafb44..0000000
--- a/sandbox/win/src/filesystem_interception.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-#ifndef SANDBOX_SRC_FILESYSTEM_INTERCEPTION_H__
-#define SANDBOX_SRC_FILESYSTEM_INTERCEPTION_H__
-
-namespace sandbox {
-
-extern "C" {
-
-// Interception of NtCreateFile on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtCreateFile(
- NtCreateFileFunction orig_CreateFile, PHANDLE file,
- ACCESS_MASK desired_access, POBJECT_ATTRIBUTES object_attributes,
- PIO_STATUS_BLOCK io_status, PLARGE_INTEGER allocation_size,
- ULONG file_attributes, ULONG sharing, ULONG disposition, ULONG options,
- PVOID ea_buffer, ULONG ea_length);
-
-// Interception of NtOpenFile on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenFile(
- NtOpenFileFunction orig_OpenFile, PHANDLE file, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, PIO_STATUS_BLOCK io_status,
- ULONG sharing, ULONG options);
-
-// Interception of NtQueryAtttributesFile on the child process.
-// It should never be called directly.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtQueryAttributesFile(
- NtQueryAttributesFileFunction orig_QueryAttributes,
- POBJECT_ATTRIBUTES object_attributes,
- PFILE_BASIC_INFORMATION file_attributes);
-
-// Interception of NtQueryFullAtttributesFile on the child process.
-// It should never be called directly.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
- NtQueryFullAttributesFileFunction orig_QueryAttributes,
- POBJECT_ATTRIBUTES object_attributes,
- PFILE_NETWORK_OPEN_INFORMATION file_attributes);
-
-// Interception of NtSetInformationFile on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtSetInformationFile(
- NtSetInformationFileFunction orig_SetInformationFile, HANDLE file,
- PIO_STATUS_BLOCK io_status, PVOID file_information, ULONG length,
- FILE_INFORMATION_CLASS file_information_class);
-
-} // extern "C"
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_FILESYSTEM_INTERCEPTION_H__
diff --git a/sandbox/win/src/filesystem_policy.cc b/sandbox/win/src/filesystem_policy.cc
deleted file mode 100644
index b3eddab..0000000
--- a/sandbox/win/src/filesystem_policy.cc
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "sandbox/win/src/filesystem_policy.h"
-
-#include "base/logging.h"
-#include "base/win/scoped_handle.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_engine_opcodes.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox_utils.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace {
-
-NTSTATUS NtCreateFileInTarget(HANDLE* target_file_handle,
- ACCESS_MASK desired_access,
- OBJECT_ATTRIBUTES* obj_attributes,
- IO_STATUS_BLOCK* io_status_block,
- ULONG file_attributes,
- ULONG share_access,
- ULONG create_disposition,
- ULONG create_options,
- PVOID ea_buffer,
- ULONG ea_lenght,
- HANDLE target_process) {
- NtCreateFileFunction NtCreateFile = NULL;
- ResolveNTFunctionPtr("NtCreateFile", &NtCreateFile);
-
- HANDLE local_handle = INVALID_HANDLE_VALUE;
- NTSTATUS status = NtCreateFile(&local_handle, desired_access, obj_attributes,
- io_status_block, NULL, file_attributes,
- share_access, create_disposition,
- create_options, ea_buffer, ea_lenght);
- if (!NT_SUCCESS(status)) {
- return status;
- }
-
- if (!sandbox::SameObject(local_handle, obj_attributes->ObjectName->Buffer)) {
- // The handle points somewhere else. Fail the operation.
- ::CloseHandle(local_handle);
- return STATUS_ACCESS_DENIED;
- }
-
- if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
- target_process, target_file_handle, 0, FALSE,
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- ::CloseHandle(local_handle);
- return STATUS_ACCESS_DENIED;
- }
- return STATUS_SUCCESS;
-}
-
-} // namespace.
-
-namespace sandbox {
-
-bool FileSystemPolicy::GenerateRules(const wchar_t* name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy) {
- std::wstring mod_name(name);
- if (mod_name.empty()) {
- return false;
- }
-
- // Don't do any pre-processing if the name starts like the the native
- // object manager style.
- if (0 != _wcsnicmp(mod_name.c_str(), kNTObjManPrefix, kNTObjManPrefixLen)) {
- // TODO(cpu) bug 32224: This prefix add is a hack because we don't have the
- // infrastructure to normalize names. In any case we need to escape the
- // question marks.
- if (!PreProcessName(mod_name, &mod_name)) {
- // The path to be added might contain a reparse point.
- NOTREACHED();
- return false;
- }
- if (0 != mod_name.compare(0, kNTPrefixLen, kNTPrefix)) {
- // TODO(nsylvain): Find a better way to do name resolution. Right now we
- // take the name and we expand it.
- mod_name.insert(0, L"\\/?/?\\");
- name = mod_name.c_str();
- }
- }
-
- EvalResult result = ASK_BROKER;
-
- // List of supported calls for the filesystem.
- const unsigned kCallNtCreateFile = 0x1;
- const unsigned kCallNtOpenFile = 0x2;
- const unsigned kCallNtQueryAttributesFile = 0x4;
- const unsigned kCallNtQueryFullAttributesFile = 0x8;
- const unsigned kCallNtSetInfoRename = 0x10;
-
- DWORD rule_to_add = kCallNtOpenFile | kCallNtCreateFile |
- kCallNtQueryAttributesFile |
- kCallNtQueryFullAttributesFile | kCallNtSetInfoRename;
-
- PolicyRule create(result);
- PolicyRule open(result);
- PolicyRule query(result);
- PolicyRule query_full(result);
- PolicyRule rename(result);
-
- switch (semantics) {
- case TargetPolicy::FILES_ALLOW_DIR_ANY: {
- open.AddNumberMatch(IF, OpenFile::OPTIONS, FILE_DIRECTORY_FILE, AND);
- create.AddNumberMatch(IF, OpenFile::OPTIONS, FILE_DIRECTORY_FILE, AND);
- break;
- }
- case TargetPolicy::FILES_ALLOW_READONLY: {
- // We consider all flags that are not known to be readonly as potentially
- // used for write.
- DWORD allowed_flags = FILE_READ_DATA | FILE_READ_ATTRIBUTES |
- FILE_READ_EA | SYNCHRONIZE | FILE_EXECUTE |
- GENERIC_READ | GENERIC_EXECUTE | READ_CONTROL;
- DWORD restricted_flags = ~allowed_flags;
- open.AddNumberMatch(IF_NOT, OpenFile::ACCESS, restricted_flags, AND);
- create.AddNumberMatch(IF_NOT, OpenFile::ACCESS, restricted_flags, AND);
-
- // Read only access don't work for rename.
- rule_to_add &= ~kCallNtSetInfoRename;
- break;
- }
- case TargetPolicy::FILES_ALLOW_QUERY: {
- // Here we don't want to add policy for the open or the create.
- rule_to_add &= ~(kCallNtOpenFile | kCallNtCreateFile |
- kCallNtSetInfoRename);
- break;
- }
- case TargetPolicy::FILES_ALLOW_ANY: {
- break;
- }
- default: {
- NOTREACHED();
- return false;
- }
- }
-
- if ((rule_to_add & kCallNtCreateFile) &&
- (!create.AddStringMatch(IF, OpenFile::NAME, name, CASE_INSENSITIVE) ||
- !policy->AddRule(IPC_NTCREATEFILE_TAG, &create))) {
- return false;
- }
-
- if ((rule_to_add & kCallNtOpenFile) &&
- (!open.AddStringMatch(IF, OpenFile::NAME, name, CASE_INSENSITIVE) ||
- !policy->AddRule(IPC_NTOPENFILE_TAG, &open))) {
- return false;
- }
-
- if ((rule_to_add & kCallNtQueryAttributesFile) &&
- (!query.AddStringMatch(IF, FileName::NAME, name, CASE_INSENSITIVE) ||
- !policy->AddRule(IPC_NTQUERYATTRIBUTESFILE_TAG, &query))) {
- return false;
- }
-
- if ((rule_to_add & kCallNtQueryFullAttributesFile) &&
- (!query_full.AddStringMatch(IF, FileName::NAME, name, CASE_INSENSITIVE)
- || !policy->AddRule(IPC_NTQUERYFULLATTRIBUTESFILE_TAG,
- &query_full))) {
- return false;
- }
-
- if ((rule_to_add & kCallNtSetInfoRename) &&
- (!rename.AddStringMatch(IF, FileName::NAME, name, CASE_INSENSITIVE) ||
- !policy->AddRule(IPC_NTSETINFO_RENAME_TAG, &rename))) {
- return false;
- }
-
- return true;
-}
-
-// Right now we insert two rules, to be evaluated before any user supplied rule:
-// - go to the broker if the path doesn't look like the paths that we push on
-// the policy (namely \??\something).
-// - go to the broker if it looks like this is a short-name path.
-//
-// It is possible to add a rule to go to the broker in any case; it would look
-// something like:
-// rule = new PolicyRule(ASK_BROKER);
-// rule->AddNumberMatch(IF_NOT, FileName::BROKER, TRUE, AND);
-// policy->AddRule(service, rule);
-bool FileSystemPolicy::SetInitialRules(LowLevelPolicy* policy) {
- PolicyRule format(ASK_BROKER);
- PolicyRule short_name(ASK_BROKER);
-
- bool rv = format.AddNumberMatch(IF_NOT, FileName::BROKER, TRUE, AND);
- rv &= format.AddStringMatch(IF_NOT, FileName::NAME, L"\\/?/?\\*",
- CASE_SENSITIVE);
-
- rv &= short_name.AddNumberMatch(IF_NOT, FileName::BROKER, TRUE, AND);
- rv &= short_name.AddStringMatch(IF, FileName::NAME, L"*~*", CASE_SENSITIVE);
-
- if (!rv || !policy->AddRule(IPC_NTCREATEFILE_TAG, &format))
- return false;
-
- if (!policy->AddRule(IPC_NTCREATEFILE_TAG, &short_name))
- return false;
-
- if (!policy->AddRule(IPC_NTOPENFILE_TAG, &format))
- return false;
-
- if (!policy->AddRule(IPC_NTOPENFILE_TAG, &short_name))
- return false;
-
- if (!policy->AddRule(IPC_NTQUERYATTRIBUTESFILE_TAG, &format))
- return false;
-
- if (!policy->AddRule(IPC_NTQUERYATTRIBUTESFILE_TAG, &short_name))
- return false;
-
- if (!policy->AddRule(IPC_NTQUERYFULLATTRIBUTESFILE_TAG, &format))
- return false;
-
- if (!policy->AddRule(IPC_NTQUERYFULLATTRIBUTESFILE_TAG, &short_name))
- return false;
-
- if (!policy->AddRule(IPC_NTSETINFO_RENAME_TAG, &format))
- return false;
-
- if (!policy->AddRule(IPC_NTSETINFO_RENAME_TAG, &short_name))
- return false;
-
- return true;
-}
-
-bool FileSystemPolicy::CreateFileAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &file,
- uint32 attributes,
- uint32 desired_access,
- uint32 file_attributes,
- uint32 share_access,
- uint32 create_disposition,
- uint32 create_options,
- HANDLE *handle,
- NTSTATUS* nt_status,
- ULONG_PTR *io_information) {
- // The only action supported is ASK_BROKER which means create the requested
- // file as specified.
- if (ASK_BROKER != eval_result) {
- *nt_status = STATUS_ACCESS_DENIED;
- return false;
- }
- IO_STATUS_BLOCK io_block = {0};
- UNICODE_STRING uni_name = {0};
- OBJECT_ATTRIBUTES obj_attributes = {0};
- InitObjectAttribs(file, attributes, NULL, &obj_attributes, &uni_name);
- *nt_status = NtCreateFileInTarget(handle, desired_access, &obj_attributes,
- &io_block, file_attributes, share_access,
- create_disposition, create_options, NULL,
- 0, client_info.process);
-
- *io_information = io_block.Information;
- return true;
-}
-
-bool FileSystemPolicy::OpenFileAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &file,
- uint32 attributes,
- uint32 desired_access,
- uint32 share_access,
- uint32 open_options,
- HANDLE *handle,
- NTSTATUS* nt_status,
- ULONG_PTR *io_information) {
- // The only action supported is ASK_BROKER which means open the requested
- // file as specified.
- if (ASK_BROKER != eval_result) {
- *nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- // An NtOpen is equivalent to an NtCreate with FileAttributes = 0 and
- // CreateDisposition = FILE_OPEN.
- IO_STATUS_BLOCK io_block = {0};
- UNICODE_STRING uni_name = {0};
- OBJECT_ATTRIBUTES obj_attributes = {0};
- InitObjectAttribs(file, attributes, NULL, &obj_attributes, &uni_name);
- *nt_status = NtCreateFileInTarget(handle, desired_access, &obj_attributes,
- &io_block, 0, share_access, FILE_OPEN,
- open_options, NULL, 0,
- client_info.process);
-
- *io_information = io_block.Information;
- return true;
-}
-
-bool FileSystemPolicy::QueryAttributesFileAction(
- EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &file,
- uint32 attributes,
- FILE_BASIC_INFORMATION* file_info,
- NTSTATUS* nt_status) {
- // The only action supported is ASK_BROKER which means query the requested
- // file as specified.
- if (ASK_BROKER != eval_result) {
- *nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- NtQueryAttributesFileFunction NtQueryAttributesFile = NULL;
- ResolveNTFunctionPtr("NtQueryAttributesFile", &NtQueryAttributesFile);
-
- UNICODE_STRING uni_name = {0};
- OBJECT_ATTRIBUTES obj_attributes = {0};
- InitObjectAttribs(file, attributes, NULL, &obj_attributes, &uni_name);
- *nt_status = NtQueryAttributesFile(&obj_attributes, file_info);
-
- return true;
-}
-
-bool FileSystemPolicy::QueryFullAttributesFileAction(
- EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &file,
- uint32 attributes,
- FILE_NETWORK_OPEN_INFORMATION* file_info,
- NTSTATUS* nt_status) {
- // The only action supported is ASK_BROKER which means query the requested
- // file as specified.
- if (ASK_BROKER != eval_result) {
- *nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- NtQueryFullAttributesFileFunction NtQueryFullAttributesFile = NULL;
- ResolveNTFunctionPtr("NtQueryFullAttributesFile", &NtQueryFullAttributesFile);
-
- UNICODE_STRING uni_name = {0};
- OBJECT_ATTRIBUTES obj_attributes = {0};
- InitObjectAttribs(file, attributes, NULL, &obj_attributes, &uni_name);
- *nt_status = NtQueryFullAttributesFile(&obj_attributes, file_info);
-
- return true;
-}
-
-bool FileSystemPolicy::SetInformationFileAction(
- EvalResult eval_result, const ClientInfo& client_info,
- HANDLE target_file_handle, void* file_info, uint32 length,
- uint32 info_class, IO_STATUS_BLOCK* io_block,
- NTSTATUS* nt_status) {
- // The only action supported is ASK_BROKER which means open the requested
- // file as specified.
- if (ASK_BROKER != eval_result) {
- *nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- NtSetInformationFileFunction NtSetInformationFile = NULL;
- ResolveNTFunctionPtr("NtSetInformationFile", &NtSetInformationFile);
-
- HANDLE local_handle = NULL;
- if (!::DuplicateHandle(client_info.process, target_file_handle,
- ::GetCurrentProcess(), &local_handle, 0, FALSE,
- DUPLICATE_SAME_ACCESS)) {
- *nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- base::win::ScopedHandle handle(local_handle);
-
- FILE_INFORMATION_CLASS file_info_class =
- static_cast<FILE_INFORMATION_CLASS>(info_class);
- *nt_status = NtSetInformationFile(local_handle, io_block, file_info, length,
- file_info_class);
-
- return true;
-}
-
-bool PreProcessName(const std::wstring& path, std::wstring* new_path) {
- ConvertToLongPath(path, new_path);
-
- bool reparsed = false;
- if (ERROR_SUCCESS != IsReparsePoint(*new_path, &reparsed))
- return false;
-
- // We can't process reparsed file.
- return !reparsed;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/filesystem_policy.h b/sandbox/win/src/filesystem_policy.h
deleted file mode 100644
index bcedb63..0000000
--- a/sandbox/win/src/filesystem_policy.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_FILESYSTEM_POLICY_H__
-#define SANDBOX_SRC_FILESYSTEM_POLICY_H__
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/policy_low_level.h"
-#include "sandbox/win/src/sandbox_policy.h"
-
-namespace sandbox {
-
-enum EvalResult;
-
-// This class centralizes most of the knowledge related to file system policy
-class FileSystemPolicy {
- public:
- // Creates the required low-level policy rules to evaluate a high-level
- // policy rule for File IO, in particular open or create actions.
- // 'name' is the file or directory name.
- // 'semantics' is the desired semantics for the open or create.
- // 'policy' is the policy generator to which the rules are going to be added.
- static bool GenerateRules(const wchar_t* name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy);
-
- // Add basic file system rules.
- static bool SetInitialRules(LowLevelPolicy* policy);
-
- // Performs the desired policy action on a create request with an
- // API that is compatible with the IPC-received parameters.
- // 'client_info' : the target process that is making the request.
- // 'eval_result' : The desired policy action to accomplish.
- // 'file' : The target file or directory.
- static bool CreateFileAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &file,
- uint32 attributes,
- uint32 desired_access,
- uint32 file_attributes,
- uint32 share_access,
- uint32 create_disposition,
- uint32 create_options,
- HANDLE* handle,
- NTSTATUS* nt_status,
- ULONG_PTR* io_information);
-
- // Performs the desired policy action on an open request with an
- // API that is compatible with the IPC-received parameters.
- // 'client_info' : the target process that is making the request.
- // 'eval_result' : The desired policy action to accomplish.
- // 'file' : The target file or directory.
- static bool OpenFileAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &file,
- uint32 attributes,
- uint32 desired_access,
- uint32 share_access,
- uint32 open_options,
- HANDLE* handle,
- NTSTATUS* nt_status,
- ULONG_PTR* io_information);
-
- // Performs the desired policy action on a query request with an
- // API that is compatible with the IPC-received parameters.
- static bool QueryAttributesFileAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &file,
- uint32 attributes,
- FILE_BASIC_INFORMATION* file_info,
- NTSTATUS* nt_status);
-
- // Performs the desired policy action on a query request with an
- // API that is compatible with the IPC-received parameters.
- static bool QueryFullAttributesFileAction(
- EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &file,
- uint32 attributes,
- FILE_NETWORK_OPEN_INFORMATION* file_info,
- NTSTATUS* nt_status);
-
- // Performs the desired policy action on a set_info request with an
- // API that is compatible with the IPC-received parameters.
- static bool SetInformationFileAction(EvalResult eval_result,
- const ClientInfo& client_info,
- HANDLE target_file_handle,
- void* file_info,
- uint32 length,
- uint32 info_class,
- IO_STATUS_BLOCK* io_block,
- NTSTATUS* nt_status);
-};
-
-// Expands the path and check if it's a reparse point. Returns false if
-// we cannot determine or if there is an unexpected error. In that case
-// the path cannot be trusted.
-bool PreProcessName(const std::wstring& path, std::wstring* new_path);
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_FILESYSTEM_POLICY_H__
diff --git a/sandbox/win/src/handle_closer.cc b/sandbox/win/src/handle_closer.cc
deleted file mode 100644
index fc72835..0000000
--- a/sandbox/win/src/handle_closer.cc
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/handle_closer.h"
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/win/windows_version.h"
-#include "sandbox/win/src/interceptors.h"
-#include "sandbox/win/src/internal_types.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/process_thread_interception.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace {
-
-template<typename T> T RoundUpToWordSize(T v) {
- if (size_t mod = v % sizeof(size_t))
- v += sizeof(size_t) - mod;
- return v;
-}
-
-template<typename T> T* RoundUpToWordSize(T* v) {
- return reinterpret_cast<T*>(RoundUpToWordSize(reinterpret_cast<size_t>(v)));
-}
-
-} // namespace
-
-namespace sandbox {
-
-// Memory buffer mapped from the parent, with the list of handles.
-SANDBOX_INTERCEPT HandleCloserInfo* g_handles_to_close;
-
-HandleCloser::HandleCloser() {}
-
-ResultCode HandleCloser::AddHandle(const char16* handle_type,
- const char16* handle_name) {
- if (!handle_type)
- return SBOX_ERROR_BAD_PARAMS;
-
- HandleMap::iterator names = handles_to_close_.find(handle_type);
- if (names == handles_to_close_.end()) { // We have no entries for this type.
- std::pair<HandleMap::iterator, bool> result = handles_to_close_.insert(
- HandleMap::value_type(handle_type, HandleMap::mapped_type()));
- names = result.first;
- if (handle_name)
- names->second.insert(handle_name);
- } else if (!handle_name) { // Now we need to close all handles of this type.
- names->second.clear();
- } else if (!names->second.empty()) { // Add another name for this type.
- names->second.insert(handle_name);
- } // If we're already closing all handles of type then we're done.
-
- return SBOX_ALL_OK;
-}
-
-size_t HandleCloser::GetBufferSize() {
- size_t bytes_total = offsetof(HandleCloserInfo, handle_entries);
-
- for (HandleMap::iterator i = handles_to_close_.begin();
- i != handles_to_close_.end(); ++i) {
- size_t bytes_entry = offsetof(HandleListEntry, handle_type) +
- (i->first.size() + 1) * sizeof(char16);
- for (HandleMap::mapped_type::iterator j = i->second.begin();
- j != i->second.end(); ++j) {
- bytes_entry += ((*j).size() + 1) * sizeof(char16);
- }
-
- // Round up to the nearest multiple of word size.
- bytes_entry = RoundUpToWordSize(bytes_entry);
- bytes_total += bytes_entry;
- }
-
- return bytes_total;
-}
-
-bool HandleCloser::InitializeTargetHandles(TargetProcess* target) {
- // Do nothing on an empty list (global pointer already initialized to NULL).
- if (handles_to_close_.empty())
- return true;
-
- size_t bytes_needed = GetBufferSize();
- scoped_array<size_t> local_buffer(
- new size_t[bytes_needed / sizeof(size_t)]);
-
- if (!SetupHandleList(local_buffer.get(), bytes_needed))
- return false;
-
- HANDLE child = target->Process();
-
- // Allocate memory in the target process without specifying the address
- void* remote_data = ::VirtualAllocEx(child, NULL, bytes_needed,
- MEM_COMMIT, PAGE_READWRITE);
- if (NULL == remote_data)
- return false;
-
- // Copy the handle buffer over.
- SIZE_T bytes_written;
- BOOL result = ::WriteProcessMemory(child, remote_data, local_buffer.get(),
- bytes_needed, &bytes_written);
- if (!result || bytes_written != bytes_needed) {
- ::VirtualFreeEx(child, remote_data, 0, MEM_RELEASE);
- return false;
- }
-
- g_handles_to_close = reinterpret_cast<HandleCloserInfo*>(remote_data);
-
- ResultCode rc = target->TransferVariable("g_handles_to_close",
- &g_handles_to_close,
- sizeof(g_handles_to_close));
-
- return (SBOX_ALL_OK == rc);
-}
-
-bool HandleCloser::SetupHandleList(void* buffer, size_t buffer_bytes) {
- ::ZeroMemory(buffer, buffer_bytes);
- HandleCloserInfo* handle_info = reinterpret_cast<HandleCloserInfo*>(buffer);
- handle_info->record_bytes = buffer_bytes;
- handle_info->num_handle_types = handles_to_close_.size();
-
- char16* output = reinterpret_cast<char16*>(&handle_info->handle_entries[0]);
- char16* end = reinterpret_cast<char16*>(
- reinterpret_cast<char*>(buffer) + buffer_bytes);
- for (HandleMap::iterator i = handles_to_close_.begin();
- i != handles_to_close_.end(); ++i) {
- if (output >= end)
- return false;
- HandleListEntry* list_entry = reinterpret_cast<HandleListEntry*>(output);
- output = &list_entry->handle_type[0];
-
- // Copy the typename and set the offset and count.
- i->first._Copy_s(output, i->first.size(), i->first.size());
- *(output += i->first.size()) = L'\0';
- output++;
- list_entry->offset_to_names = reinterpret_cast<char*>(output) -
- reinterpret_cast<char*>(list_entry);
- list_entry->name_count = i->second.size();
-
- // Copy the handle names.
- for (HandleMap::mapped_type::iterator j = i->second.begin();
- j != i->second.end(); ++j) {
- output = std::copy((*j).begin(), (*j).end(), output) + 1;
- }
-
- // Round up to the nearest multiple of sizeof(size_t).
- output = RoundUpToWordSize(output);
- list_entry->record_bytes = reinterpret_cast<char*>(output) -
- reinterpret_cast<char*>(list_entry);
- }
-
- DCHECK_EQ(reinterpret_cast<size_t>(output), reinterpret_cast<size_t>(end));
- return output <= end;
-}
-
-bool HandleCloser::SetupHandleInterceptions(InterceptionManager* manager) {
- // We need to intercept CreateThread if we're closing ALPC port clients.
- HandleMap::iterator names = handles_to_close_.find(L"ALPC Port");
- if (base::win::GetVersion() >= base::win::VERSION_VISTA &&
- names != handles_to_close_.end() &&
- (names->second.empty() || names->second.size() == 0)) {
- if (!INTERCEPT_EAT(manager, kKerneldllName, CreateThread,
- CREATE_THREAD_ID, 28)) {
- return false;
- }
- if (!INTERCEPT_EAT(manager, kKerneldllName, GetUserDefaultLCID,
- GET_USER_DEFAULT_LCID_ID, 4)) {
- return false;
- }
-
- return true;
- }
-
- return true;
-}
-
-bool GetHandleName(HANDLE handle, string16* handle_name) {
- static NtQueryObject QueryObject = NULL;
- if (!QueryObject)
- ResolveNTFunctionPtr("NtQueryObject", &QueryObject);
-
- ULONG size = MAX_PATH;
- scoped_ptr<UNICODE_STRING> name;
- NTSTATUS result;
-
- do {
- name.reset(reinterpret_cast<UNICODE_STRING*>(new BYTE[size]));
- result = QueryObject(handle, ObjectNameInformation, name.get(),
- size, &size);
- } while (result == STATUS_INFO_LENGTH_MISMATCH ||
- result == STATUS_BUFFER_OVERFLOW);
-
- if (NT_SUCCESS(result) && name->Buffer && name->Length)
- handle_name->assign(name->Buffer, name->Length / sizeof(wchar_t));
- else
- handle_name->clear();
-
- return NT_SUCCESS(result);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/handle_closer.h b/sandbox/win/src/handle_closer.h
deleted file mode 100644
index b43e50f..0000000
--- a/sandbox/win/src/handle_closer.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_HANDLE_CLOSER_H_
-#define SANDBOX_SRC_HANDLE_CLOSER_H_
-
-#include <map>
-#include <set>
-
-#include "base/basictypes.h"
-#include "base/string16.h"
-#include "sandbox/win/src/interception.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/target_process.h"
-
-namespace sandbox {
-
-// This is a map of handle-types to names that we need to close in the
-// target process. A null set means we need to close all handles of the
-// given type.
-typedef std::map<const string16, std::set<const string16> > HandleMap;
-
-// Type and set of corresponding handle names to close.
-struct HandleListEntry {
- size_t record_bytes; // Rounded to sizeof(size_t) bytes.
- size_t offset_to_names; // Nul terminated strings of name_count names.
- size_t name_count;
- char16 handle_type[1];
-};
-
-// Global parameters and a pointer to the list of entries.
-struct HandleCloserInfo {
- size_t record_bytes; // Rounded to sizeof(size_t) bytes.
- size_t num_handle_types;
- struct HandleListEntry handle_entries[1];
-};
-
-SANDBOX_INTERCEPT HandleCloserInfo* g_handle_closer_info;
-
-// Adds handles to close after lockdown.
-class HandleCloser {
- public:
- HandleCloser();
-
- // Adds a handle that will be closed in the target process after lockdown.
- // A NULL value for handle_name indicates all handles of the specified type.
- // An empty string for handle_name indicates the handle is unnamed.
- ResultCode AddHandle(const char16* handle_type, const char16* handle_name);
-
- // Serializes and copies the closer table into the target process.
- bool InitializeTargetHandles(TargetProcess* target);
-
- // Adds any interceptions that may be required due to closed system handles.
- bool SetupHandleInterceptions(InterceptionManager* manager);
-
- private:
- // Calculates the memory needed to copy the serialized handles list (rounded
- // to the nearest machine-word size).
- size_t GetBufferSize();
-
- // Serializes the handle list into the target process.
- bool SetupHandleList(void* buffer, size_t buffer_bytes);
-
- HandleMap handles_to_close_;
-
- DISALLOW_COPY_AND_ASSIGN(HandleCloser);
-};
-
-// Returns the object manager's name associated with a handle
-bool GetHandleName(HANDLE handle, string16* handle_name);
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_HANDLE_CLOSER_H_
diff --git a/sandbox/win/src/handle_closer_agent.cc b/sandbox/win/src/handle_closer_agent.cc
deleted file mode 100644
index be262e8..0000000
--- a/sandbox/win/src/handle_closer_agent.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/handle_closer_agent.h"
-
-#include "base/logging.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace {
-
-// Returns type infomation for an NT object. This routine is expected to be
-// called for invalid handles so it catches STATUS_INVALID_HANDLE exceptions
-// that can be generated when handle tracing is enabled.
-NTSTATUS QueryObjectTypeInformation(HANDLE handle,
- void* buffer,
- ULONG* size) {
- static NtQueryObject QueryObject = NULL;
- if (!QueryObject)
- ResolveNTFunctionPtr("NtQueryObject", &QueryObject);
-
- NTSTATUS status = STATUS_UNSUCCESSFUL;
- __try {
- status = QueryObject(handle, ObjectTypeInformation, buffer, *size, size);
- } __except(GetExceptionCode() == STATUS_INVALID_HANDLE ?
- EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
- status = STATUS_INVALID_HANDLE;
- }
- return status;
-}
-
-} // namespace
-
-namespace sandbox {
-
-// Memory buffer mapped from the parent, with the list of handles.
-SANDBOX_INTERCEPT HandleCloserInfo* g_handles_to_close = NULL;
-
-bool HandleCloserAgent::NeedsHandlesClosed() {
- return g_handles_to_close != NULL;
-}
-
-// Reads g_handles_to_close and creates the lookup map.
-void HandleCloserAgent::InitializeHandlesToClose() {
- CHECK(g_handles_to_close != NULL);
-
- // Grab the header.
- HandleListEntry* entry = g_handles_to_close->handle_entries;
- for (size_t i = 0; i < g_handles_to_close->num_handle_types; ++i) {
- // Set the type name.
- char16* input = entry->handle_type;
- HandleMap::mapped_type& handle_names = handles_to_close_[input];
- input = reinterpret_cast<char16*>(reinterpret_cast<char*>(entry)
- + entry->offset_to_names);
- // Grab all the handle names.
- for (size_t j = 0; j < entry->name_count; ++j) {
- std::pair<HandleMap::mapped_type::iterator, bool> name
- = handle_names.insert(input);
- CHECK(name.second);
- input += name.first->size() + 1;
- }
-
- // Move on to the next entry.
- entry = reinterpret_cast<HandleListEntry*>(reinterpret_cast<char*>(entry)
- + entry->record_bytes);
-
- DCHECK(reinterpret_cast<char16*>(entry) >= input);
- DCHECK(reinterpret_cast<char16*>(entry) - input <
- sizeof(size_t) / sizeof(char16));
- }
-
- // Clean up the memory we copied over.
- ::VirtualFree(g_handles_to_close, 0, MEM_RELEASE);
- g_handles_to_close = NULL;
-}
-
-bool HandleCloserAgent::CloseHandles() {
- DWORD handle_count = UINT_MAX;
- const int kInvalidHandleThreshold = 100;
- const size_t kHandleOffset = sizeof(HANDLE);
-
- if (!::GetProcessHandleCount(::GetCurrentProcess(), &handle_count))
- return false;
-
- // Set up buffers for the type info and the name.
- std::vector<BYTE> type_info_buffer(sizeof(OBJECT_TYPE_INFORMATION) +
- 32 * sizeof(wchar_t));
- OBJECT_TYPE_INFORMATION* type_info =
- reinterpret_cast<OBJECT_TYPE_INFORMATION*>(&(type_info_buffer[0]));
- string16 handle_name;
- HANDLE handle = NULL;
- int invalid_count = 0;
-
- // Keep incrementing until we hit the number of handles reported by
- // GetProcessHandleCount(). If we hit a very long sequence of invalid
- // handles we assume that we've run past the end of the table.
- while (handle_count && invalid_count < kInvalidHandleThreshold) {
- reinterpret_cast<size_t&>(handle) += kHandleOffset;
- NTSTATUS rc;
-
- // Get the type name, reusing the buffer.
- ULONG size = static_cast<ULONG>(type_info_buffer.size());
- rc = QueryObjectTypeInformation(handle, type_info, &size);
- while (rc == STATUS_INFO_LENGTH_MISMATCH ||
- rc == STATUS_BUFFER_OVERFLOW) {
- type_info_buffer.resize(size + sizeof(wchar_t));
- type_info = reinterpret_cast<OBJECT_TYPE_INFORMATION*>(
- &(type_info_buffer[0]));
- rc = QueryObjectTypeInformation(handle, type_info, &size);
- // Leave padding for the nul terminator.
- if (NT_SUCCESS(0) && size == type_info_buffer.size())
- rc = STATUS_INFO_LENGTH_MISMATCH;
- }
- if (!NT_SUCCESS(rc) || !type_info->Name.Buffer) {
- ++invalid_count;
- continue;
- }
-
- --handle_count;
- type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] = L'\0';
-
- // Check if we're looking for this type of handle.
- HandleMap::iterator result =
- handles_to_close_.find(type_info->Name.Buffer);
- if (result != handles_to_close_.end()) {
- HandleMap::mapped_type& names = result->second;
- // Empty set means close all handles of this type; otherwise check name.
- if (!names.empty()) {
- // Move on to the next handle if this name doesn't match.
- if (!GetHandleName(handle, &handle_name) || !names.count(handle_name))
- continue;
- }
-
- if (!::SetHandleInformation(handle, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0))
- return false;
- if (!::CloseHandle(handle))
- return false;
- }
- }
-
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/handle_closer_agent.h b/sandbox/win/src/handle_closer_agent.h
deleted file mode 100644
index 602f327..0000000
--- a/sandbox/win/src/handle_closer_agent.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_HANDLE_CLOSER_AGENT_H_
-#define SANDBOX_SRC_HANDLE_CLOSER_AGENT_H_
-
-#include "base/basictypes.h"
-#include "base/string16.h"
-#include "sandbox/win/src/handle_closer.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-namespace sandbox {
-
-// Target process code to close the handle list copied over from the broker.
-class HandleCloserAgent {
- public:
- HandleCloserAgent() {}
-
- // Reads the serialized list from the broker and creates the lookup map.
- void InitializeHandlesToClose();
-
- // Closes any handles matching those in the lookup map.
- bool CloseHandles();
-
- // True if we have handles waiting to be closed
- static bool NeedsHandlesClosed();
-
- private:
- HandleMap handles_to_close_;
-
- DISALLOW_COPY_AND_ASSIGN(HandleCloserAgent);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_HANDLE_CLOSER_AGENT_H_
diff --git a/sandbox/win/src/handle_closer_test.cc b/sandbox/win/src/handle_closer_test.cc
deleted file mode 100644
index b35ff5e..0000000
--- a/sandbox/win/src/handle_closer_test.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/stringprintf.h"
-#include "base/win/scoped_handle.h"
-#include "sandbox/win/src/handle_closer_agent.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/target_services.h"
-#include "sandbox/win/tests/common/controller.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-const wchar_t *kFileExtensions[] = { L".1", L".2", L".3", L".4" };
-
-// Returns a handle to a unique marker file that can be retrieved between runs.
-HANDLE GetMarkerFile(const wchar_t *extension) {
- wchar_t path_buffer[MAX_PATH + 1];
- CHECK(::GetTempPath(MAX_PATH, path_buffer));
- string16 marker_path = path_buffer;
- marker_path += L"\\sbox_marker_";
-
- // Generate a unique value from the exe's size and timestamp.
- CHECK(::GetModuleFileName(NULL, path_buffer, MAX_PATH));
- base::win::ScopedHandle module(::CreateFile(path_buffer,
- FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
- CHECK(module.IsValid());
- FILETIME timestamp;
- CHECK(::GetFileTime(module, &timestamp, NULL, NULL));
- marker_path += base::StringPrintf(L"%08x%08x%08x",
- ::GetFileSize(module, NULL),
- timestamp.dwLowDateTime,
- timestamp.dwHighDateTime);
- marker_path += extension;
-
- // Make the file delete-on-close so cleanup is automatic.
- return CreateFile(marker_path.c_str(), FILE_ALL_ACCESS,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, OPEN_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
-}
-
-// Used by the thread pool tests.
-HANDLE finish_event;
-const int kWaitCount = 20;
-
-} // namespace
-
-namespace sandbox {
-
-// Checks for the presence of a list of files (in object path form).
-// Format: CheckForFileHandle (Y|N) \path\to\file1 [\path\to\file2 ...]
-// - Y or N depending if the file should exist or not.
-SBOX_TESTS_COMMAND int CheckForFileHandles(int argc, wchar_t **argv) {
- if (argc < 2)
- return SBOX_TEST_FAILED_TO_RUN_TEST;
- bool should_find = argv[0][0] == L'Y';
- if (argv[0][1] != L'\0' || !should_find && argv[0][0] != L'N')
- return SBOX_TEST_FAILED_TO_RUN_TEST;
-
- static int state = BEFORE_INIT;
- switch (state++) {
- case BEFORE_INIT:
- // Create a unique marker file that is open while the test is running.
- // The handles leak, but it will be closed by the test or on exit.
- for (int i = 0; i < arraysize(kFileExtensions); ++i)
- EXPECT_NE(GetMarkerFile(kFileExtensions[i]), INVALID_HANDLE_VALUE);
- return SBOX_TEST_SUCCEEDED;
-
- case AFTER_REVERT: {
- // Brute force the handle table to find what we're looking for.
- DWORD handle_count = UINT_MAX;
- const int kInvalidHandleThreshold = 100;
- const size_t kHandleOffset = sizeof(HANDLE);
- HANDLE handle = NULL;
- int invalid_count = 0;
- string16 handle_name;
-
- if (!::GetProcessHandleCount(::GetCurrentProcess(), &handle_count))
- return SBOX_TEST_FAILED_TO_RUN_TEST;
-
- while (handle_count && invalid_count < kInvalidHandleThreshold) {
- reinterpret_cast<size_t&>(handle) += kHandleOffset;
- if (GetHandleName(handle, &handle_name)) {
- for (int i = 1; i < argc; ++i) {
- if (handle_name == argv[i])
- return should_find ? SBOX_TEST_SUCCEEDED : SBOX_TEST_FAILED;
- }
- --handle_count;
- } else {
- ++invalid_count;
- }
- }
-
- return should_find ? SBOX_TEST_FAILED : SBOX_TEST_SUCCEEDED;
- }
-
- default: // Do nothing.
- break;
- }
-
- return SBOX_TEST_SUCCEEDED;
-}
-
-TEST(HandleCloserTest, CheckForMarkerFiles) {
- TestRunner runner;
- runner.SetTimeout(2000);
- runner.SetTestState(EVERY_STATE);
- sandbox::TargetPolicy* policy = runner.GetPolicy();
-
- string16 command = string16(L"CheckForFileHandles Y");
- for (int i = 0; i < arraysize(kFileExtensions); ++i) {
- string16 handle_name;
- base::win::ScopedHandle marker(GetMarkerFile(kFileExtensions[i]));
- CHECK(marker.IsValid());
- CHECK(sandbox::GetHandleName(marker, &handle_name));
- command += (L" ");
- command += handle_name;
- }
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command.c_str())) <<
- "Failed: " << command;
-}
-
-TEST(HandleCloserTest, CloseMarkerFiles) {
- TestRunner runner;
- runner.SetTimeout(2000);
- runner.SetTestState(EVERY_STATE);
- sandbox::TargetPolicy* policy = runner.GetPolicy();
-
- string16 command = string16(L"CheckForFileHandles N");
- for (int i = 0; i < arraysize(kFileExtensions); ++i) {
- string16 handle_name;
- base::win::ScopedHandle marker(GetMarkerFile(kFileExtensions[i]));
- CHECK(marker.IsValid());
- CHECK(sandbox::GetHandleName(marker, &handle_name));
- CHECK_EQ(policy->AddKernelObjectToClose(L"File", handle_name.c_str()),
- SBOX_ALL_OK);
- command += (L" ");
- command += handle_name;
- }
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command.c_str())) <<
- "Failed: " << command;
-}
-
-void WINAPI ThreadPoolTask(void* event, BOOLEAN timeout) {
- static volatile LONG waiters_remaining = kWaitCount;
- CHECK(!timeout);
- CHECK(::CloseHandle(event));
- if (::InterlockedDecrement(&waiters_remaining) == 0)
- CHECK(::SetEvent(finish_event));
-}
-
-// Run a thread pool inside a sandbox without a CSRSS connection.
-SBOX_TESTS_COMMAND int RunThreadPool(int argc, wchar_t **argv) {
- HANDLE wait_list[20];
- CHECK(finish_event = ::CreateEvent(NULL, TRUE, FALSE, NULL));
-
- // Set up a bunch of waiters.
- HANDLE pool = NULL;
- for (int i = 0; i < kWaitCount; ++i) {
- HANDLE event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- CHECK(event);
- CHECK(::RegisterWaitForSingleObject(&pool, event, ThreadPoolTask, event,
- INFINITE, WT_EXECUTEONLYONCE));
- wait_list[i] = event;
- }
-
- // Signal all the waiters.
- for (int i = 0; i < kWaitCount; ++i)
- CHECK(::SetEvent(wait_list[i]));
-
- CHECK_EQ(::WaitForSingleObject(finish_event, INFINITE), WAIT_OBJECT_0);
- CHECK(::CloseHandle(finish_event));
-
- return SBOX_TEST_SUCCEEDED;
-}
-
-TEST(HandleCloserTest, RunThreadPool) {
- TestRunner runner;
- runner.SetTimeout(2000);
- runner.SetTestState(AFTER_REVERT);
- sandbox::TargetPolicy* policy = runner.GetPolicy();
-
- // Sever the CSRSS connection by closing ALPC ports inside the sandbox.
- CHECK_EQ(policy->AddKernelObjectToClose(L"ALPC Port", NULL), SBOX_ALL_OK);
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"RunThreadPool"));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/handle_dispatcher.cc b/sandbox/win/src/handle_dispatcher.cc
deleted file mode 100644
index 26b8fc3..0000000
--- a/sandbox/win/src/handle_dispatcher.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/handle_dispatcher.h"
-
-#include "base/win/scoped_handle.h"
-#include "sandbox/win/src/handle_interception.h"
-#include "sandbox/win/src/handle_policy.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_broker.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/sandbox_utils.h"
-
-namespace sandbox {
-
-HandleDispatcher::HandleDispatcher(PolicyBase* policy_base)
- : policy_base_(policy_base) {
- static const IPCCall duplicate_handle_proxy = {
- {IPC_DUPLICATEHANDLEPROXY_TAG, VOIDPTR_TYPE, ULONG_TYPE, ULONG_TYPE,
- ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(&HandleDispatcher::DuplicateHandleProxy)
- };
-
- ipc_calls_.push_back(duplicate_handle_proxy);
-}
-
-bool HandleDispatcher::SetupService(InterceptionManager* manager,
- int service) {
- // We perform no interceptions for handles right now.
- switch (service) {
- case IPC_DUPLICATEHANDLEPROXY_TAG:
- return true;
- }
-
- return false;
-}
-
-bool HandleDispatcher::DuplicateHandleProxy(IPCInfo* ipc,
- HANDLE source_handle,
- DWORD target_process_id,
- DWORD desired_access,
- DWORD options) {
- NTSTATUS error;
- static NtQueryObject QueryObject = NULL;
- if (!QueryObject)
- ResolveNTFunctionPtr("NtQueryObject", &QueryObject);
-
- // Get a copy of the handle for use in the broker process.
- HANDLE handle_temp;
- if (!::DuplicateHandle(ipc->client_info->process, source_handle,
- ::GetCurrentProcess(), &handle_temp,
- 0, FALSE, DUPLICATE_SAME_ACCESS)) {
- ipc->return_info.win32_result = ::GetLastError();
- return false;
- }
- base::win::ScopedHandle handle(handle_temp);
-
- // Get the object type (32 characters is safe; current max is 14).
- BYTE buffer[sizeof(OBJECT_TYPE_INFORMATION) + 32 * sizeof(wchar_t)];
- OBJECT_TYPE_INFORMATION* type_info =
- reinterpret_cast<OBJECT_TYPE_INFORMATION*>(buffer);
- ULONG size = sizeof(buffer) - sizeof(wchar_t);
- error = QueryObject(handle, ObjectTypeInformation, type_info, size, &size);
- if (!NT_SUCCESS(error)) {
- ipc->return_info.win32_result = error;
- return false;
- }
- type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] = L'\0';
-
- CountedParameterSet<HandleTarget> params;
- params[HandleTarget::NAME] = ParamPickerMake(type_info->Name.Buffer);
- params[HandleTarget::TARGET] = ParamPickerMake(target_process_id);
-
- EvalResult eval = policy_base_->EvalPolicy(IPC_DUPLICATEHANDLEPROXY_TAG,
- params.GetBase());
- ipc->return_info.win32_result =
- HandlePolicy::DuplicateHandleProxyAction(eval, *ipc->client_info,
- source_handle,
- target_process_id,
- &ipc->return_info.handle,
- desired_access, options);
- return true;
-}
-
-} // namespace sandbox
-
diff --git a/sandbox/win/src/handle_dispatcher.h b/sandbox/win/src/handle_dispatcher.h
deleted file mode 100644
index a3dc6cf..0000000
--- a/sandbox/win/src/handle_dispatcher.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_HANDLE_DISPATCHER_H_
-#define SANDBOX_SRC_HANDLE_DISPATCHER_H_
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/sandbox_policy_base.h"
-
-namespace sandbox {
-
-// This class handles handle-related IPC calls.
-class HandleDispatcher : public Dispatcher {
- public:
- explicit HandleDispatcher(PolicyBase* policy_base);
- ~HandleDispatcher() {}
-
- // Dispatcher interface.
- virtual bool SetupService(InterceptionManager* manager, int service);
-
- private:
- // Processes IPC requests coming from calls to
- // TargetServices::DuplicateHandle() in the target.
- bool DuplicateHandleProxy(IPCInfo* ipc, HANDLE source_handle,
- DWORD target_process_id, DWORD desired_access,
- DWORD options);
-
- PolicyBase* policy_base_;
- DISALLOW_COPY_AND_ASSIGN(HandleDispatcher);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_HANDLE_DISPATCHER_H_
-
diff --git a/sandbox/win/src/handle_interception.cc b/sandbox/win/src/handle_interception.cc
deleted file mode 100644
index af0bebc..0000000
--- a/sandbox/win/src/handle_interception.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/handle_interception.h"
-
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "sandbox/win/src/target_services.h"
-
-namespace sandbox {
-
-ResultCode DuplicateHandleProxy(HANDLE source_handle,
- DWORD target_process_id,
- HANDLE* target_handle,
- DWORD desired_access,
- DWORD options) {
- *target_handle = NULL;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- return SBOX_ERROR_NO_SPACE;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_DUPLICATEHANDLEPROXY_TAG,
- source_handle, target_process_id,
- desired_access, options, &answer);
- if (SBOX_ALL_OK != code)
- return code;
-
- if (answer.win32_result) {
- ::SetLastError(answer.nt_status);
- return SBOX_ERROR_GENERIC;
- }
-
- *target_handle = answer.handle;
- return SBOX_ALL_OK;
-}
-
-} // namespace sandbox
-
diff --git a/sandbox/win/src/handle_interception.h b/sandbox/win/src/handle_interception.h
deleted file mode 100644
index 6f60811..0000000
--- a/sandbox/win/src/handle_interception.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-#ifndef SANDBOX_SRC_HANDLE_INTERCEPTION_H_
-#define SANDBOX_SRC_HANDLE_INTERCEPTION_H_
-
-namespace sandbox {
-
-// TODO(jschuh) Add an interception to catch dangerous DuplicateHandle calls.
-
-ResultCode DuplicateHandleProxy(HANDLE source_handle,
- DWORD target_process_id,
- HANDLE* target_handle,
- DWORD desired_access,
- DWORD options);
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_HANDLE_INTERCEPTION_H_
-
diff --git a/sandbox/win/src/handle_policy.cc b/sandbox/win/src/handle_policy.cc
deleted file mode 100644
index eeeea7b..0000000
--- a/sandbox/win/src/handle_policy.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/handle_policy.h"
-
-#include <string>
-
-#include "base/win/scoped_handle.h"
-#include "sandbox/win/src/broker_services.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_engine_opcodes.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/sandbox_utils.h"
-
-namespace sandbox {
-
-bool HandlePolicy::GenerateRules(const wchar_t* type_name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy) {
- PolicyRule duplicate_rule(ASK_BROKER);
-
- switch (semantics) {
- case TargetPolicy::HANDLES_DUP_ANY: {
- if (!duplicate_rule.AddNumberMatch(IF_NOT, HandleTarget::TARGET,
- ::GetCurrentProcessId(), EQUAL)) {
- return false;
- }
- break;
- }
-
- case TargetPolicy::HANDLES_DUP_BROKER: {
- if (!duplicate_rule.AddNumberMatch(IF, HandleTarget::TARGET,
- ::GetCurrentProcessId(), EQUAL)) {
- return false;
- }
- break;
- }
-
- default:
- return false;
- }
- if (!duplicate_rule.AddStringMatch(IF, HandleTarget::NAME, type_name,
- CASE_INSENSITIVE)) {
- return false;
- }
- if (!policy->AddRule(IPC_DUPLICATEHANDLEPROXY_TAG, &duplicate_rule)) {
- return false;
- }
- return true;
-}
-
-DWORD HandlePolicy::DuplicateHandleProxyAction(EvalResult eval_result,
- const ClientInfo& client_info,
- HANDLE source_handle,
- DWORD target_process_id,
- HANDLE* target_handle,
- DWORD desired_access,
- DWORD options) {
- // The only action supported is ASK_BROKER which means duplicate the handle.
- if (ASK_BROKER != eval_result) {
- return ERROR_ACCESS_DENIED;
- }
-
- base::win::ScopedHandle remote_target_process;
- if (target_process_id != ::GetCurrentProcessId()) {
- // Sandboxed children are dynamic, so we check that manually.
- if (!BrokerServicesBase::GetInstance()->IsActiveTarget(target_process_id)) {
- return ERROR_ACCESS_DENIED;
- }
-
- remote_target_process.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE,
- target_process_id));
- if (!remote_target_process.IsValid())
- return ::GetLastError();
- }
-
- // If the policy didn't block us and we have no valid target, then the broker
- // (this process) is the valid target.
- HANDLE target_process = remote_target_process.IsValid() ?
- remote_target_process : ::GetCurrentProcess();
- DWORD result = ERROR_SUCCESS;
- if (!::DuplicateHandle(client_info.process, source_handle, target_process,
- target_handle, desired_access, FALSE,
- options)) {
- return ::GetLastError();
- }
-
- return ERROR_SUCCESS;
-}
-
-} // namespace sandbox
-
diff --git a/sandbox/win/src/handle_policy.h b/sandbox/win/src/handle_policy.h
deleted file mode 100644
index d91a039..0000000
--- a/sandbox/win/src/handle_policy.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_HANDLE_POLICY_H_
-#define SANDBOX_SRC_HANDLE_POLICY_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/policy_low_level.h"
-#include "sandbox/win/src/sandbox_policy.h"
-
-namespace sandbox {
-
-enum EvalResult;
-
-// This class centralizes most of the knowledge related to handle policy.
-class HandlePolicy {
- public:
- // Creates the required low-level policy rules to evaluate a high-level
- // policy rule for handles, in particular duplicate action.
- static bool GenerateRules(const wchar_t* type_name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy);
-
- // Processes a 'TargetPolicy::DuplicateHandle()' request from the target.
- static DWORD DuplicateHandleProxyAction(EvalResult eval_result,
- const ClientInfo& client_info,
- HANDLE source_handle,
- DWORD target_process_id,
- HANDLE* target_handle,
- DWORD desired_access,
- DWORD options);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_HANDLE_POLICY_H_
-
diff --git a/sandbox/win/src/handle_policy_test.cc b/sandbox/win/src/handle_policy_test.cc
deleted file mode 100644
index 65efbc85..0000000
--- a/sandbox/win/src/handle_policy_test.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/stringprintf.h"
-#include "sandbox/win/src/handle_policy.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/sandbox_policy.h"
-#include "sandbox/win/src/win_utils.h"
-#include "sandbox/win/tests/common/controller.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace sandbox {
-
-// Just waits for the supplied number of milliseconds.
-SBOX_TESTS_COMMAND int Handle_WaitProcess(int argc, wchar_t **argv) {
- if (argc != 1)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- ::Sleep(::wcstoul(argv[0], NULL, 10));
- return SBOX_TEST_TIMED_OUT;
-}
-
-// Attempts to duplicate an event handle into the target process.
-SBOX_TESTS_COMMAND int Handle_DuplicateEvent(int argc, wchar_t **argv) {
- if (argc != 1)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- // Create a test event to use as a handle.
- base::win::ScopedHandle test_event;
- test_event.Set(::CreateEvent(NULL, TRUE, TRUE, NULL));
- if (!test_event.IsValid())
- return SBOX_TEST_FIRST_ERROR;
-
- // Get the target process ID.
- DWORD target_process_id = ::wcstoul(argv[0], NULL, 10);
-
- HANDLE handle = NULL;
- ResultCode result = SandboxFactory::GetTargetServices()->DuplicateHandle(
- test_event, target_process_id, &handle, 0, DUPLICATE_SAME_ACCESS);
-
- return (result == SBOX_ALL_OK) ? SBOX_TEST_SUCCEEDED : SBOX_TEST_DENIED;
-}
-
-// Tests that duplicating an object works only when the policy allows it.
-TEST(HandlePolicyTest, DuplicateHandle) {
- TestRunner target;
- TestRunner runner;
-
- // Kick off an asynchronous target process for testing.
- target.SetAsynchronous(true);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"Handle_WaitProcess 30000"));
-
- // First test that we fail to open the event.
- std::wstring cmd_line = base::StringPrintf(L"Handle_DuplicateEvent %d",
- target.process_id());
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(cmd_line.c_str()));
-
- // Now successfully open the event after adding a duplicate handle rule.
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_HANDLES,
- TargetPolicy::HANDLES_DUP_ANY,
- L"Event"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd_line.c_str()));
-}
-
-// Tests that duplicating an object works only when the policy allows it.
-TEST(HandlePolicyTest, DuplicatePeerHandle) {
- TestRunner target;
- TestRunner runner;
-
- // Kick off an asynchronous target process for testing.
- target.SetAsynchronous(true);
- target.SetUnsandboxed(true);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, target.RunTest(L"Handle_WaitProcess 30000"));
-
- // First test that we fail to open the event.
- std::wstring cmd_line = base::StringPrintf(L"Handle_DuplicateEvent %d",
- target.process_id());
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(cmd_line.c_str()));
-
- // Now successfully open the event after adding a duplicate handle rule.
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_HANDLES,
- TargetPolicy::HANDLES_DUP_ANY,
- L"Event"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd_line.c_str()));
-}
-
-// Tests that duplicating an object works only when the policy allows it.
-TEST(HandlePolicyTest, DuplicateBrokerHandle) {
- TestRunner runner;
-
- // First test that we fail to open the event.
- std::wstring cmd_line = base::StringPrintf(L"Handle_DuplicateEvent %d",
- ::GetCurrentProcessId());
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(cmd_line.c_str()));
-
- // Add the peer rule and make sure we fail again.
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_HANDLES,
- TargetPolicy::HANDLES_DUP_ANY,
- L"Event"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(cmd_line.c_str()));
-
-
- // Now successfully open the event after adding a broker handle rule.
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_HANDLES,
- TargetPolicy::HANDLES_DUP_BROKER,
- L"Event"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(cmd_line.c_str()));
-}
-
-} // namespace sandbox
-
diff --git a/sandbox/win/src/handle_table.cc b/sandbox/win/src/handle_table.cc
deleted file mode 100644
index a497f74..0000000
--- a/sandbox/win/src/handle_table.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/handle_table.h"
-
-#include <algorithm>
-#include <cstdlib>
-
-#include "base/memory/scoped_ptr.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace {
-
-bool CompareHandleEntries(const SYSTEM_HANDLE_INFORMATION& a,
- const SYSTEM_HANDLE_INFORMATION& b) {
- return a.ProcessId < b.ProcessId;
-}
-
-} // namespace
-
-namespace sandbox {
-
-const char16* HandleTable::kTypeProcess = L"Process";
-const char16* HandleTable::kTypeThread = L"Thread";
-const char16* HandleTable::kTypeFile = L"File";
-const char16* HandleTable::kTypeDirectory = L"Directory";
-const char16* HandleTable::kTypeKey = L"Key";
-const char16* HandleTable::kTypeWindowStation = L"WindowStation";
-const char16* HandleTable::kTypeDesktop = L"Desktop";
-const char16* HandleTable::kTypeService = L"Service";
-const char16* HandleTable::kTypeMutex = L"Mutex";
-const char16* HandleTable::kTypeSemaphore = L"Semaphore";
-const char16* HandleTable::kTypeEvent = L"Event";
-const char16* HandleTable::kTypeTimer = L"Timer";
-const char16* HandleTable::kTypeNamedPipe = L"NamedPipe";
-const char16* HandleTable::kTypeJobObject = L"JobObject";
-const char16* HandleTable::kTypeFileMap = L"FileMap";
-const char16* HandleTable::kTypeAlpcPort = L"ALPC Port";
-
-HandleTable::HandleTable() {
- static NtQuerySystemInformation QuerySystemInformation = NULL;
- if (!QuerySystemInformation)
- ResolveNTFunctionPtr("NtQuerySystemInformation", &QuerySystemInformation);
-
- ULONG size = 0x15000;
- NTSTATUS result;
- do {
- handle_info_buffer_.resize(size);
- result = QuerySystemInformation(SystemHandleInformation,
- handle_info_internal(), size, &size);
- } while (result == STATUS_INFO_LENGTH_MISMATCH);
-
- // We failed, so make an empty table.
- if (!NT_SUCCESS(result)) {
- handle_info_buffer_.resize(0);
- return;
- }
-
- // Sort it to make process lookups faster.
- std::sort(handle_info_internal()->Information,
- handle_info_internal()->Information +
- handle_info_internal()->NumberOfHandles, CompareHandleEntries);
-}
-
-HandleTable::Iterator HandleTable::HandlesForProcess(ULONG process_id) const {
- SYSTEM_HANDLE_INFORMATION key;
- key.ProcessId = process_id;
-
- const SYSTEM_HANDLE_INFORMATION* start = handle_info()->Information;
- const SYSTEM_HANDLE_INFORMATION* finish =
- &handle_info()->Information[handle_info()->NumberOfHandles];
-
- start = std::lower_bound(start, finish, key, CompareHandleEntries);
- if (start->ProcessId != process_id)
- return Iterator(*this, finish, finish);
- finish = std::upper_bound(start, finish, key, CompareHandleEntries);
- return Iterator(*this, start, finish);
-}
-
-HandleTable::HandleEntry::HandleEntry(
- const SYSTEM_HANDLE_INFORMATION* handle_info_entry)
- : handle_entry_(handle_info_entry), last_entry_(0) {
-}
-
-void HandleTable::HandleEntry::UpdateInfo(UpdateType flag) {
- static NtQueryObject QueryObject = NULL;
- if (!QueryObject)
- ResolveNTFunctionPtr("NtQueryObject", &QueryObject);
-
- NTSTATUS result;
-
- // Always update the basic type info, but grab the names as needed.
- if (needs_info_update()) {
- handle_name_.clear();
- type_name_.clear();
- last_entry_ = handle_entry_;
-
- // Most handle names are very short, so start small and reuse this buffer.
- if (type_info_buffer_.empty())
- type_info_buffer_.resize(sizeof(OBJECT_TYPE_INFORMATION)
- + (32 * sizeof(wchar_t)));
- ULONG size = static_cast<ULONG>(type_info_buffer_.size());
- result = QueryObject(reinterpret_cast<HANDLE>(handle_entry_->Handle),
- ObjectTypeInformation, type_info_internal(), size, &size);
- while (result == STATUS_INFO_LENGTH_MISMATCH) {
- type_info_buffer_.resize(size);
- result = QueryObject(reinterpret_cast<HANDLE>(handle_entry_->Handle),
- ObjectTypeInformation, type_info_internal(), size, &size);
- }
-
- if (!NT_SUCCESS(result)) {
- type_info_buffer_.clear();
- return;
- }
- }
-
- // Don't bother copying out names until we ask for them, and then cache them.
- switch (flag) {
- case UPDATE_INFO_AND_NAME:
- if (type_info_buffer_.size() && handle_name_.empty()) {
- ULONG size = MAX_PATH;
- scoped_ptr<UNICODE_STRING> name;
- do {
- name.reset(reinterpret_cast<UNICODE_STRING*>(new BYTE[size]));
- result = QueryObject(reinterpret_cast<HANDLE>(
- handle_entry_->Handle), ObjectNameInformation, name.get(),
- size, &size);
- } while (result == STATUS_INFO_LENGTH_MISMATCH);
-
- if (NT_SUCCESS(result)) {
- handle_name_.assign(name->Buffer, name->Length / sizeof(wchar_t));
- }
- }
- break;
-
- case UPDATE_INFO_AND_TYPE_NAME:
- if (!type_info_buffer_.empty() && type_info_internal()->Name.Buffer &&
- type_name_.empty()) {
- type_name_.assign(type_info_internal()->Name.Buffer,
- type_info_internal()->Name.Length / sizeof(wchar_t));
- }
- break;
- }
-}
-
-const OBJECT_TYPE_INFORMATION* HandleTable::HandleEntry::TypeInfo() {
- UpdateInfo(UPDATE_INFO_ONLY);
- return type_info_buffer_.empty() ? NULL : type_info_internal();
-}
-
-const string16& HandleTable::HandleEntry::Name() {
- UpdateInfo(UPDATE_INFO_AND_NAME);
- return handle_name_;
-}
-
-const string16& HandleTable::HandleEntry::Type() {
- UpdateInfo(UPDATE_INFO_AND_TYPE_NAME);
- return type_name_;
-}
-
-bool HandleTable::HandleEntry::IsType(const string16& type_string) {
- UpdateInfo(UPDATE_INFO_ONLY);
- if (type_info_buffer_.empty())
- return false;
- return type_string.compare(0,
- type_info_internal()->Name.Length / sizeof(wchar_t),
- type_info_internal()->Name.Buffer) == 0;
-}
-
-HandleTable::Iterator::Iterator(const HandleTable& table,
- const SYSTEM_HANDLE_INFORMATION* start,
- const SYSTEM_HANDLE_INFORMATION* end)
- : table_(table), current_(start), end_(end) {
-}
-
-HandleTable::Iterator::Iterator(const Iterator& it)
- : table_(it.table_), current_(it.current_.handle_entry_), end_(it.end_) {
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/handle_table.h b/sandbox/win/src/handle_table.h
deleted file mode 100644
index acdc88d..0000000
--- a/sandbox/win/src/handle_table.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_HANDLE_TABLE_H_
-#define SANDBOX_SRC_HANDLE_TABLE_H_
-
-#include <windows.h>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/string16.h"
-#include "sandbox/win/src/nt_internals.h"
-
-namespace sandbox {
-
-// HandleTable retrieves the global handle table and provides helper classes
-// for iterating through the table and retrieving handle info.
-class HandleTable {
- public:
- static const char16* HandleTable::kTypeProcess;
- static const char16* HandleTable::kTypeThread;
- static const char16* HandleTable::kTypeFile;
- static const char16* HandleTable::kTypeDirectory;
- static const char16* HandleTable::kTypeKey;
- static const char16* HandleTable::kTypeWindowStation;
- static const char16* HandleTable::kTypeDesktop;
- static const char16* HandleTable::kTypeService;
- static const char16* HandleTable::kTypeMutex;
- static const char16* HandleTable::kTypeSemaphore;
- static const char16* HandleTable::kTypeEvent;
- static const char16* HandleTable::kTypeTimer;
- static const char16* HandleTable::kTypeNamedPipe;
- static const char16* HandleTable::kTypeJobObject;
- static const char16* HandleTable::kTypeFileMap;
- static const char16* HandleTable::kTypeAlpcPort;
-
- class Iterator;
-
- // Used by the iterator to provide simple caching accessors to handle data.
- class HandleEntry {
- public:
- bool operator==(const HandleEntry& rhs) const {
- return handle_entry_ == rhs.handle_entry_;
- }
-
- bool operator!=(const HandleEntry& rhs) const {
- return handle_entry_ != rhs.handle_entry_;
- }
-
- const SYSTEM_HANDLE_INFORMATION* handle_entry() const {
- return handle_entry_;
- }
-
- const OBJECT_TYPE_INFORMATION* TypeInfo();
-
- const string16& Name();
-
- const string16& Type();
-
- bool IsType(const string16& type_string);
-
- private:
- friend class Iterator;
- friend class HandleTable;
-
- enum UpdateType {
- UPDATE_INFO_ONLY,
- UPDATE_INFO_AND_NAME,
- UPDATE_INFO_AND_TYPE_NAME,
- };
-
- explicit HandleEntry(const SYSTEM_HANDLE_INFORMATION* handle_info_entry);
-
- bool needs_info_update() { return handle_entry_ != last_entry_; }
-
- void UpdateInfo(UpdateType flag);
-
- OBJECT_TYPE_INFORMATION* type_info_internal() {
- return reinterpret_cast<OBJECT_TYPE_INFORMATION*>(
- &(type_info_buffer_[0]));
- }
-
- const SYSTEM_HANDLE_INFORMATION* handle_entry_;
- const SYSTEM_HANDLE_INFORMATION* last_entry_;
- std::vector<BYTE> type_info_buffer_;
- string16 handle_name_;
- string16 type_name_;
-
- DISALLOW_COPY_AND_ASSIGN(HandleEntry);
- };
-
- class Iterator {
- public:
- Iterator(const HandleTable& table, const SYSTEM_HANDLE_INFORMATION* start,
- const SYSTEM_HANDLE_INFORMATION* stop);
-
- Iterator(const Iterator& it);
-
- Iterator& operator++() {
- if (++(current_.handle_entry_) == end_)
- current_.handle_entry_ = table_.end();
- return *this;
- }
-
- bool operator==(const Iterator& rhs) const {
- return current_ == rhs.current_;
- }
-
- bool operator!=(const Iterator& rhs) const {
- return current_ != rhs.current_;
- }
-
- HandleEntry& operator*() { return current_; }
-
- operator const SYSTEM_HANDLE_INFORMATION*() {
- return current_.handle_entry_;
- }
-
- HandleEntry* operator->() { return &current_; }
-
- private:
- const HandleTable& table_;
- HandleEntry current_;
- const SYSTEM_HANDLE_INFORMATION* end_;
- };
-
- HandleTable();
-
- Iterator begin() const {
- return Iterator(*this, handle_info()->Information,
- &handle_info()->Information[handle_info()->NumberOfHandles]);
- }
-
- const SYSTEM_HANDLE_INFORMATION_EX* handle_info() const {
- return reinterpret_cast<const SYSTEM_HANDLE_INFORMATION_EX*>(
- &(handle_info_buffer_[0]));
- }
-
- // Returns an iterator to the handles for only the supplied process ID.
- Iterator HandlesForProcess(ULONG process_id) const;
- const SYSTEM_HANDLE_INFORMATION* end() const {
- return &handle_info()->Information[handle_info()->NumberOfHandles];
- }
-
- private:
- SYSTEM_HANDLE_INFORMATION_EX* handle_info_internal() {
- return reinterpret_cast<SYSTEM_HANDLE_INFORMATION_EX*>(
- &(handle_info_buffer_[0]));
- }
-
- std::vector<BYTE> handle_info_buffer_;
-
- DISALLOW_COPY_AND_ASSIGN(HandleTable);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_HANDLE_TABLE_H_
diff --git a/sandbox/win/src/integrity_level_test.cc b/sandbox/win/src/integrity_level_test.cc
deleted file mode 100644
index 67ea9de..0000000
--- a/sandbox/win/src/integrity_level_test.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <windows.h>
-#include <atlsecurity.h>
-
-#include "base/win/windows_version.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_policy.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/tests/common/controller.h"
-
-namespace sandbox {
-
-
-SBOX_TESTS_COMMAND int CheckIntegrityLevel(int argc, wchar_t **argv) {
- ATL::CAccessToken token;
- if (!token.GetEffectiveToken(TOKEN_READ))
- return SBOX_TEST_FAILED;
-
- char* buffer[100];
- DWORD buf_size = 100;
- if (!::GetTokenInformation(token.GetHandle(), TokenIntegrityLevel,
- reinterpret_cast<void*>(buffer), buf_size,
- &buf_size))
- return SBOX_TEST_FAILED;
-
- TOKEN_MANDATORY_LABEL* label =
- reinterpret_cast<TOKEN_MANDATORY_LABEL*>(buffer);
-
- PSID sid_low = NULL;
- if (!::ConvertStringSidToSid(L"S-1-16-4096", &sid_low))
- return SBOX_TEST_FAILED;
-
- BOOL is_low_sid = ::EqualSid(label->Label.Sid, sid_low);
-
- ::LocalFree(sid_low);
-
- if (is_low_sid)
- return SBOX_TEST_SUCCEEDED;
-
- return SBOX_TEST_DENIED;
-}
-
-TEST(IntegrityLevelTest, TestLowILReal) {
- if (base::win::GetVersion() != base::win::VERSION_VISTA)
- return;
-
- TestRunner runner(JOB_LOCKDOWN, USER_INTERACTIVE, USER_INTERACTIVE);
-
- runner.SetTimeout(INFINITE);
-
- runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckIntegrityLevel"));
-
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckIntegrityLevel"));
-}
-
-TEST(DelayedIntegrityLevelTest, TestLowILDelayed) {
- if (base::win::GetVersion() != base::win::VERSION_VISTA)
- return;
-
- TestRunner runner(JOB_LOCKDOWN, USER_INTERACTIVE, USER_INTERACTIVE);
-
- runner.SetTimeout(INFINITE);
-
- runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW);
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckIntegrityLevel"));
-
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"CheckIntegrityLevel"));
-}
-
-TEST(IntegrityLevelTest, TestNoILChange) {
- if (base::win::GetVersion() != base::win::VERSION_VISTA)
- return;
-
- TestRunner runner(JOB_LOCKDOWN, USER_INTERACTIVE, USER_INTERACTIVE);
-
- runner.SetTimeout(INFINITE);
-
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"CheckIntegrityLevel"));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/interception.cc b/sandbox/win/src/interception.cc
deleted file mode 100644
index 929b621..0000000
--- a/sandbox/win/src/interception.cc
+++ /dev/null
@@ -1,551 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// For information about interceptions as a whole see
-// http://dev.chromium.org/developers/design-documents/sandbox .
-
-#include <set>
-
-#include "sandbox/win/src/interception.h"
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/win/pe_image.h"
-#include "base/win/windows_version.h"
-#include "sandbox/win/src/interception_internal.h"
-#include "sandbox/win/src/interceptors.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_utils.h"
-#include "sandbox/win/src/service_resolver.h"
-#include "sandbox/win/src/target_interceptions.h"
-#include "sandbox/win/src/target_process.h"
-#include "sandbox/win/src/wow64.h"
-
-namespace {
-
-const char kMapViewOfSectionName[] = "NtMapViewOfSection";
-const char kUnmapViewOfSectionName[] = "NtUnmapViewOfSection";
-
-// Standard allocation granularity and page size for Windows.
-const size_t kAllocGranularity = 65536;
-const size_t kPageSize = 4096;
-
-// Find a random offset within 64k and aligned to ceil(log2(size)).
-size_t GetGranularAlignedRandomOffset(size_t size) {
- CHECK_LE(size, kAllocGranularity);
- unsigned int offset;
-
- do {
- rand_s(&offset);
- offset &= (kAllocGranularity - 1);
- } while (offset > (kAllocGranularity - size));
-
- // Find an alignment between 64 and the page size (4096).
- size_t align_size = kPageSize;
- for (size_t new_size = align_size / 2; new_size >= size; new_size /= 2) {
- align_size = new_size;
- }
- return offset & ~(align_size - 1);
-}
-
-} // namespace
-
-namespace sandbox {
-
-SANDBOX_INTERCEPT SharedMemory* g_interceptions;
-
-// Table of the unpatched functions that we intercept. Mapped from the parent.
-SANDBOX_INTERCEPT OriginalFunctions g_originals = { NULL };
-
-// Magic constant that identifies that this function is not to be patched.
-const char kUnloadDLLDummyFunction[] = "@";
-
-InterceptionManager::InterceptionManager(TargetProcess* child_process,
- bool relaxed)
- : child_(child_process), names_used_(false), relaxed_(relaxed) {
- child_->AddRef();
-}
-InterceptionManager::~InterceptionManager() {
- child_->Release();
-}
-
-bool InterceptionManager::AddToPatchedFunctions(
- const wchar_t* dll_name, const char* function_name,
- InterceptionType interception_type, const void* replacement_code_address,
- InterceptorId id) {
- InterceptionData function;
- function.type = interception_type;
- function.id = id;
- function.dll = dll_name;
- function.function = function_name;
- function.interceptor_address = replacement_code_address;
-
- interceptions_.push_back(function);
- return true;
-}
-
-bool InterceptionManager::AddToPatchedFunctions(
- const wchar_t* dll_name, const char* function_name,
- InterceptionType interception_type, const char* replacement_function_name,
- InterceptorId id) {
- InterceptionData function;
- function.type = interception_type;
- function.id = id;
- function.dll = dll_name;
- function.function = function_name;
- function.interceptor = replacement_function_name;
- function.interceptor_address = NULL;
-
- interceptions_.push_back(function);
- names_used_ = true;
- return true;
-}
-
-bool InterceptionManager::AddToUnloadModules(const wchar_t* dll_name) {
- InterceptionData module_to_unload;
- module_to_unload.type = INTERCEPTION_UNLOAD_MODULE;
- module_to_unload.dll = dll_name;
- // The next two are dummy values that make the structures regular, instead
- // of having special cases. They should not be used.
- module_to_unload.function = kUnloadDLLDummyFunction;
- module_to_unload.interceptor_address = reinterpret_cast<void*>(1);
-
- interceptions_.push_back(module_to_unload);
- return true;
-}
-
-bool InterceptionManager::InitializeInterceptions() {
- if (interceptions_.empty())
- return true; // Nothing to do here
-
- size_t buffer_bytes = GetBufferSize();
- scoped_array<char> local_buffer(new char[buffer_bytes]);
-
- if (!SetupConfigBuffer(local_buffer.get(), buffer_bytes))
- return false;
-
- void* remote_buffer;
- if (!CopyDataToChild(local_buffer.get(), buffer_bytes, &remote_buffer))
- return false;
-
- bool hot_patch_needed = (0 != buffer_bytes);
- if (!PatchNtdll(hot_patch_needed))
- return false;
-
- g_interceptions = reinterpret_cast<SharedMemory*>(remote_buffer);
- ResultCode rc = child_->TransferVariable("g_interceptions",
- &g_interceptions,
- sizeof(g_interceptions));
- return (SBOX_ALL_OK == rc);
-}
-
-size_t InterceptionManager::GetBufferSize() const {
- std::set<std::wstring> dlls;
- size_t buffer_bytes = 0;
-
- std::list<InterceptionData>::const_iterator it = interceptions_.begin();
- for (; it != interceptions_.end(); ++it) {
- // skip interceptions that are performed from the parent
- if (!IsInterceptionPerformedByChild(*it))
- continue;
-
- if (!dlls.count(it->dll)) {
- // NULL terminate the dll name on the structure
- size_t dll_name_bytes = (it->dll.size() + 1) * sizeof(wchar_t);
-
- // include the dll related size
- buffer_bytes += RoundUpToMultiple(offsetof(DllPatchInfo, dll_name) +
- dll_name_bytes, sizeof(size_t));
- dlls.insert(it->dll);
- }
-
- // we have to NULL terminate the strings on the structure
- size_t strings_chars = it->function.size() + it->interceptor.size() + 2;
-
- // a new FunctionInfo is required per function
- size_t record_bytes = offsetof(FunctionInfo, function) + strings_chars;
- record_bytes = RoundUpToMultiple(record_bytes, sizeof(size_t));
- buffer_bytes += record_bytes;
- }
-
- if (0 != buffer_bytes)
- // add the part of SharedMemory that we have not counted yet
- buffer_bytes += offsetof(SharedMemory, dll_list);
-
- return buffer_bytes;
-}
-
-// Basically, walk the list of interceptions moving them to the config buffer,
-// but keeping together all interceptions that belong to the same dll.
-// The config buffer is a local buffer, not the one allocated on the child.
-bool InterceptionManager::SetupConfigBuffer(void* buffer, size_t buffer_bytes) {
- if (0 == buffer_bytes)
- return true;
-
- DCHECK(buffer_bytes > sizeof(SharedMemory));
-
- SharedMemory* shared_memory = reinterpret_cast<SharedMemory*>(buffer);
- DllPatchInfo* dll_info = shared_memory->dll_list;
- int num_dlls = 0;
-
- shared_memory->interceptor_base = names_used_ ? child_->MainModule() : NULL;
-
- buffer_bytes -= offsetof(SharedMemory, dll_list);
- buffer = dll_info;
-
- std::list<InterceptionData>::iterator it = interceptions_.begin();
- for (; it != interceptions_.end();) {
- // skip interceptions that are performed from the parent
- if (!IsInterceptionPerformedByChild(*it)) {
- ++it;
- continue;
- }
-
- const std::wstring dll = it->dll;
- if (!SetupDllInfo(*it, &buffer, &buffer_bytes))
- return false;
-
- // walk the interceptions from this point, saving the ones that are
- // performed on this dll, and removing the entry from the list.
- // advance the iterator before removing the element from the list
- std::list<InterceptionData>::iterator rest = it;
- for (; rest != interceptions_.end();) {
- if (rest->dll == dll) {
- if (!SetupInterceptionInfo(*rest, &buffer, &buffer_bytes, dll_info))
- return false;
- if (it == rest)
- ++it;
- rest = interceptions_.erase(rest);
- } else {
- ++rest;
- }
- }
- dll_info = reinterpret_cast<DllPatchInfo*>(buffer);
- ++num_dlls;
- }
-
- shared_memory->num_intercepted_dlls = num_dlls;
- return true;
-}
-
-// Fills up just the part that depends on the dll, not the info that depends on
-// the actual interception.
-bool InterceptionManager::SetupDllInfo(const InterceptionData& data,
- void** buffer,
- size_t* buffer_bytes) const {
- DCHECK(buffer_bytes);
- DCHECK(buffer);
- DCHECK(*buffer);
-
- DllPatchInfo* dll_info = reinterpret_cast<DllPatchInfo*>(*buffer);
-
- // the strings have to be zero terminated
- size_t required = offsetof(DllPatchInfo, dll_name) +
- (data.dll.size() + 1) * sizeof(wchar_t);
- required = RoundUpToMultiple(required, sizeof(size_t));
- if (*buffer_bytes < required)
- return false;
-
- *buffer_bytes -= required;
- *buffer = reinterpret_cast<char*>(*buffer) + required;
-
- // set up the dll info to be what we know about it at this time
- dll_info->unload_module = (data.type == INTERCEPTION_UNLOAD_MODULE);
- dll_info->record_bytes = required;
- dll_info->offset_to_functions = required;
- dll_info->num_functions = 0;
- data.dll._Copy_s(dll_info->dll_name, data.dll.size(), data.dll.size());
- dll_info->dll_name[data.dll.size()] = L'\0';
-
- return true;
-}
-
-bool InterceptionManager::SetupInterceptionInfo(const InterceptionData& data,
- void** buffer,
- size_t* buffer_bytes,
- DllPatchInfo* dll_info) const {
- DCHECK(buffer_bytes);
- DCHECK(buffer);
- DCHECK(*buffer);
-
- if ((dll_info->unload_module) &&
- (data.function != kUnloadDLLDummyFunction)) {
- // Can't specify a dll for both patch and unload.
- NOTREACHED();
- }
-
- FunctionInfo* function = reinterpret_cast<FunctionInfo*>(*buffer);
-
- size_t name_bytes = data.function.size();
- size_t interceptor_bytes = data.interceptor.size();
-
- // the strings at the end of the structure are zero terminated
- size_t required = offsetof(FunctionInfo, function) +
- name_bytes + interceptor_bytes + 2;
- required = RoundUpToMultiple(required, sizeof(size_t));
- if (*buffer_bytes < required)
- return false;
-
- // update the caller's values
- *buffer_bytes -= required;
- *buffer = reinterpret_cast<char*>(*buffer) + required;
-
- function->record_bytes = required;
- function->type = data.type;
- function->id = data.id;
- function->interceptor_address = data.interceptor_address;
- char* names = function->function;
-
- data.function._Copy_s(names, name_bytes, name_bytes);
- names += name_bytes;
- *names++ = '\0';
-
- // interceptor follows the function_name
- data.interceptor._Copy_s(names, interceptor_bytes, interceptor_bytes);
- names += interceptor_bytes;
- *names++ = '\0';
-
- // update the dll table
- dll_info->num_functions++;
- dll_info->record_bytes += required;
-
- return true;
-}
-
-bool InterceptionManager::CopyDataToChild(const void* local_buffer,
- size_t buffer_bytes,
- void** remote_buffer) const {
- DCHECK(NULL != remote_buffer);
- if (0 == buffer_bytes) {
- *remote_buffer = NULL;
- return true;
- }
-
- HANDLE child = child_->Process();
-
- // Allocate memory on the target process without specifying the address
- void* remote_data = ::VirtualAllocEx(child, NULL, buffer_bytes,
- MEM_COMMIT, PAGE_READWRITE);
- if (NULL == remote_data)
- return false;
-
- SIZE_T bytes_written;
- BOOL success = ::WriteProcessMemory(child, remote_data, local_buffer,
- buffer_bytes, &bytes_written);
- if (FALSE == success || bytes_written != buffer_bytes) {
- ::VirtualFreeEx(child, remote_data, 0, MEM_RELEASE);
- return false;
- }
-
- *remote_buffer = remote_data;
-
- return true;
-}
-
-// Only return true if the child should be able to perform this interception.
-bool InterceptionManager::IsInterceptionPerformedByChild(
- const InterceptionData& data) const {
- if (INTERCEPTION_INVALID == data.type)
- return false;
-
- if (INTERCEPTION_SERVICE_CALL == data.type)
- return false;
-
- if (data.type >= INTERCEPTION_LAST)
- return false;
-
- std::wstring ntdll(kNtdllName);
- if (ntdll == data.dll)
- return false; // ntdll has to be intercepted from the parent
-
- return true;
-}
-
-bool InterceptionManager::PatchNtdll(bool hot_patch_needed) {
- // Maybe there is nothing to do
- if (!hot_patch_needed && interceptions_.empty())
- return true;
-
- if (hot_patch_needed) {
-#if SANDBOX_EXPORTS
- // Make sure the functions are not excluded by the linker.
-#if defined(_WIN64)
- #pragma comment(linker, "/include:TargetNtMapViewOfSection64")
- #pragma comment(linker, "/include:TargetNtUnmapViewOfSection64")
-#else
- #pragma comment(linker, "/include:_TargetNtMapViewOfSection@44")
- #pragma comment(linker, "/include:_TargetNtUnmapViewOfSection@12")
-#endif
-#endif
- ADD_NT_INTERCEPTION(NtMapViewOfSection, MAP_VIEW_OF_SECTION_ID, 44);
- ADD_NT_INTERCEPTION(NtUnmapViewOfSection, UNMAP_VIEW_OF_SECTION_ID, 12);
- }
-
- // Reserve a full 64k memory range in the child process.
- HANDLE child = child_->Process();
- BYTE* thunk_base = reinterpret_cast<BYTE*>(
- ::VirtualAllocEx(child, NULL, kAllocGranularity,
- MEM_RESERVE, PAGE_NOACCESS));
-
- // Find an aligned, random location within the reserved range.
- size_t thunk_bytes = interceptions_.size() * sizeof(ThunkData) +
- sizeof(DllInterceptionData);
- size_t thunk_offset = GetGranularAlignedRandomOffset(thunk_bytes);
-
- // Split the base and offset along page boundaries.
- thunk_base += thunk_offset & ~(kPageSize - 1);
- thunk_offset &= kPageSize - 1;
-
- // Make an aligned, padded allocation, and move the pointer to our chunk.
- size_t thunk_bytes_padded = (thunk_bytes + kPageSize - 1) & kPageSize;
- thunk_base = reinterpret_cast<BYTE*>(
- ::VirtualAllocEx(child, thunk_base, thunk_bytes_padded,
- MEM_COMMIT, PAGE_EXECUTE_READWRITE));
- CHECK(thunk_base); // If this fails we'd crash anyway on an invalid access.
- DllInterceptionData* thunks = reinterpret_cast<DllInterceptionData*>(
- thunk_base + thunk_offset);
-
- DllInterceptionData dll_data;
- dll_data.data_bytes = thunk_bytes;
- dll_data.num_thunks = 0;
- dll_data.used_bytes = offsetof(DllInterceptionData, thunks);
-
- // Reset all helpers for a new child.
- memset(g_originals, 0, sizeof(g_originals));
-
- // this should write all the individual thunks to the child's memory
- if (!PatchClientFunctions(thunks, thunk_bytes, &dll_data))
- return false;
-
- // and now write the first part of the table to the child's memory
- SIZE_T written;
- bool ok = FALSE != ::WriteProcessMemory(child, thunks, &dll_data,
- offsetof(DllInterceptionData, thunks),
- &written);
-
- if (!ok || (offsetof(DllInterceptionData, thunks) != written))
- return false;
-
- // Attempt to protect all the thunks, but ignore failure
- DWORD old_protection;
- ::VirtualProtectEx(child, thunks, thunk_bytes,
- PAGE_EXECUTE_READ, &old_protection);
-
- ResultCode ret = child_->TransferVariable("g_originals", g_originals,
- sizeof(g_originals));
-
- return SBOX_ALL_OK == ret ? true : false;
-}
-
-bool InterceptionManager::PatchClientFunctions(DllInterceptionData* thunks,
- size_t thunk_bytes,
- DllInterceptionData* dll_data) {
- DCHECK(NULL != thunks);
- DCHECK(NULL != dll_data);
-
- HMODULE ntdll_base = ::GetModuleHandle(kNtdllName);
- if (!ntdll_base)
- return false;
-
- base::win::PEImage ntdll_image(ntdll_base);
-
- // Bypass purify's interception.
- wchar_t* loader_get = reinterpret_cast<wchar_t*>(
- ntdll_image.GetProcAddress("LdrGetDllHandle"));
- if (loader_get) {
- if (!GetModuleHandleHelper(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
- GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- loader_get, &ntdll_base))
- return false;
- }
-
- if (base::win::GetVersion() <= base::win::VERSION_VISTA) {
- Wow64 WowHelper(child_, ntdll_base);
- if (!WowHelper.WaitForNtdll())
- return false;
- }
-
- char* interceptor_base = NULL;
-
-#if SANDBOX_EXPORTS
- interceptor_base = reinterpret_cast<char*>(child_->MainModule());
- HMODULE local_interceptor = ::LoadLibrary(child_->Name());
-#endif
-
- ServiceResolverThunk* thunk;
-#if defined(_WIN64)
- thunk = new ServiceResolverThunk(child_->Process(), relaxed_);
-#else
- base::win::OSInfo* os_info = base::win::OSInfo::GetInstance();
- if (os_info->wow64_status() == base::win::OSInfo::WOW64_ENABLED) {
- if (os_info->version() >= base::win::VERSION_WIN8)
- thunk = new Wow64W8ResolverThunk(child_->Process(), relaxed_);
- else
- thunk = new Wow64ResolverThunk(child_->Process(), relaxed_);
- } else if (!IsXPSP2OrLater()) {
- thunk = new Win2kResolverThunk(child_->Process(), relaxed_);
- } else if (os_info->version() >= base::win::VERSION_WIN8) {
- thunk = new Win8ResolverThunk(child_->Process(), relaxed_);
- } else {
- thunk = new ServiceResolverThunk(child_->Process(), relaxed_);
- }
-#endif
-
- std::list<InterceptionData>::iterator it = interceptions_.begin();
- for (; it != interceptions_.end(); ++it) {
- const std::wstring ntdll(kNtdllName);
- if (it->dll != ntdll)
- break;
-
- if (INTERCEPTION_SERVICE_CALL != it->type)
- break;
-
-#if SANDBOX_EXPORTS
- // We may be trying to patch by function name.
- if (NULL == it->interceptor_address) {
- const char* address;
- NTSTATUS ret = thunk->ResolveInterceptor(local_interceptor,
- it->interceptor.c_str(),
- reinterpret_cast<const void**>(
- &address));
- if (!NT_SUCCESS(ret))
- break;
-
- // Translate the local address to an address on the child.
- it->interceptor_address = interceptor_base + (address -
- reinterpret_cast<char*>(local_interceptor));
- }
-#endif
- NTSTATUS ret = thunk->Setup(ntdll_base,
- interceptor_base,
- it->function.c_str(),
- it->interceptor.c_str(),
- it->interceptor_address,
- &thunks->thunks[dll_data->num_thunks],
- thunk_bytes - dll_data->used_bytes,
- NULL);
- if (!NT_SUCCESS(ret))
- break;
-
- DCHECK(!g_originals[it->id]);
- g_originals[it->id] = &thunks->thunks[dll_data->num_thunks];
-
- dll_data->num_thunks++;
- dll_data->used_bytes += sizeof(ThunkData);
- }
-
- delete(thunk);
-
-#if SANDBOX_EXPORTS
- if (NULL != local_interceptor)
- ::FreeLibrary(local_interceptor);
-#endif
-
- if (it != interceptions_.end())
- return false;
-
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/interception.h b/sandbox/win/src/interception.h
deleted file mode 100644
index 02fc592..0000000
--- a/sandbox/win/src/interception.h
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Defines InterceptionManager, the class in charge of setting up interceptions
-// for the sandboxed process. For more details see
-// http://dev.chromium.org/developers/design-documents/sandbox .
-
-#ifndef SANDBOX_SRC_INTERCEPTION_H_
-#define SANDBOX_SRC_INTERCEPTION_H_
-
-#include <list>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/gtest_prod_util.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-namespace sandbox {
-
-class TargetProcess;
-enum InterceptorId;
-
-// Internal structures used for communication between the broker and the target.
-struct DllPatchInfo;
-struct DllInterceptionData;
-
-// The InterceptionManager executes on the parent application, and it is in
-// charge of setting up the desired interceptions, and placing the Interception
-// Agent into the child application.
-//
-// The exposed API consists of two methods: AddToPatchedFunctions to set up a
-// particular interception, and InitializeInterceptions to actually go ahead and
-// perform all interceptions and transfer data to the child application.
-//
-// The typical usage is something like this:
-//
-// InterceptionManager interception_manager(child);
-// if (!interception_manager.AddToPatchedFunctions(
-// L"ntdll.dll", "NtCreateFile",
-// sandbox::INTERCEPTION_SERVICE_CALL, &MyNtCreateFile, MY_ID_1))
-// return false;
-//
-// if (!interception_manager.AddToPatchedFunctions(
-// L"kernel32.dll", "CreateDirectoryW",
-// sandbox::INTERCEPTION_EAT, L"MyCreateDirectoryW@12", MY_ID_2))
-// return false;
-//
-// if (!interception_manager.InitializeInterceptions()) {
-// DWORD error = ::GetLastError();
-// return false;
-// }
-//
-// Any required syncronization must be performed outside this class. Also, it is
-// not possible to perform further interceptions after InitializeInterceptions
-// is called.
-//
-class InterceptionManager {
- // The unit test will access private members.
- // Allow tests to be marked DISABLED_. Note that FLAKY_ and FAILS_ prefixes
- // do not work with sandbox tests.
- FRIEND_TEST_ALL_PREFIXES(InterceptionManagerTest, BufferLayout1);
- FRIEND_TEST_ALL_PREFIXES(InterceptionManagerTest, BufferLayout2);
-
- public:
- // An interception manager performs interceptions on a given child process.
- // If we are allowed to intercept functions that have been patched by somebody
- // else, relaxed should be set to true.
- // Note: We increase the child's reference count internally.
- InterceptionManager(TargetProcess* child_process, bool relaxed);
- ~InterceptionManager();
-
- // Patches function_name inside dll_name to point to replacement_code_address.
- // function_name has to be an exported symbol of dll_name.
- // Returns true on success.
- //
- // The new function should match the prototype and calling convention of the
- // function to intercept except for one extra argument (the first one) that
- // contains a pointer to the original function, to simplify the development
- // of interceptors (for IA32). In x64, there is no extra argument to the
- // interceptor, so the provided InterceptorId is used to keep a table of
- // intercepted functions so that the interceptor can index that table to get
- // the pointer that would have been the first argument (g_originals[id]).
- //
- // For example, to intercept NtClose, the following code could be used:
- //
- // typedef NTSTATUS (WINAPI *NtCloseFunction) (IN HANDLE Handle);
- // NTSTATUS WINAPI MyNtCose(IN NtCloseFunction OriginalClose,
- // IN HANDLE Handle) {
- // // do something
- // // call the original function
- // return OriginalClose(Handle);
- // }
- //
- // And in x64:
- //
- // typedef NTSTATUS (WINAPI *NtCloseFunction) (IN HANDLE Handle);
- // NTSTATUS WINAPI MyNtCose64(IN HANDLE Handle) {
- // // do something
- // // call the original function
- // NtCloseFunction OriginalClose = g_originals[NT_CLOSE_ID];
- // return OriginalClose(Handle);
- // }
- bool AddToPatchedFunctions(const wchar_t* dll_name,
- const char* function_name,
- InterceptionType interception_type,
- const void* replacement_code_address,
- InterceptorId id);
-
- // Patches function_name inside dll_name to point to
- // replacement_function_name.
- bool AddToPatchedFunctions(const wchar_t* dll_name,
- const char* function_name,
- InterceptionType interception_type,
- const char* replacement_function_name,
- InterceptorId id);
-
- // The interception agent will unload the dll with dll_name.
- bool AddToUnloadModules(const wchar_t* dll_name);
-
- // Initializes all interceptions on the client.
- // Returns true on success.
- //
- // The child process must be created suspended, and cannot be resumed until
- // after this method returns. In addition, no action should be performed on
- // the child that may cause it to resume momentarily, such as injecting
- // threads or APCs.
- //
- // This function must be called only once, after all interceptions have been
- // set up using AddToPatchedFunctions.
- bool InitializeInterceptions();
-
- private:
- // Used to store the interception information until the actual set-up.
- struct InterceptionData {
- InterceptionType type; // Interception type.
- InterceptorId id; // Interceptor id.
- std::wstring dll; // Name of dll to intercept.
- std::string function; // Name of function to intercept.
- std::string interceptor; // Name of interceptor function.
- const void* interceptor_address; // Interceptor's entry point.
- };
-
- // Calculates the size of the required configuration buffer.
- size_t GetBufferSize() const;
-
- // Rounds up the size of a given buffer, considering alignment (padding).
- // value is the current size of the buffer, and alignment is specified in
- // bytes.
- static inline size_t RoundUpToMultiple(size_t value, size_t alignment) {
- return ((value + alignment -1) / alignment) * alignment;
- }
-
- // Sets up a given buffer with all the information that has to be transfered
- // to the child.
- // Returns true on success.
- //
- // The buffer size should be at least the value returned by GetBufferSize
- bool SetupConfigBuffer(void* buffer, size_t buffer_bytes);
-
- // Fills up the part of the transfer buffer that corresponds to information
- // about one dll to patch.
- // data is the first recorded interception for this dll.
- // Returns true on success.
- //
- // On successful return, buffer will be advanced from it's current position
- // to the point where the next block of configuration data should be written
- // (the actual interception info), and the current size of the buffer will
- // decrease to account the space used by this method.
- bool SetupDllInfo(const InterceptionData& data,
- void** buffer, size_t* buffer_bytes) const;
-
- // Fills up the part of the transfer buffer that corresponds to a single
- // function to patch.
- // dll_info points to the dll being updated with the interception stored on
- // data. The buffer pointer and remaining size are updated by this call.
- // Returns true on success.
- bool SetupInterceptionInfo(const InterceptionData& data, void** buffer,
- size_t* buffer_bytes,
- DllPatchInfo* dll_info) const;
-
- // Returns true if this interception is to be performed by the child
- // as opposed to from the parent.
- bool IsInterceptionPerformedByChild(const InterceptionData& data) const;
-
- // Allocates a buffer on the child's address space (returned on
- // remote_buffer), and fills it with the contents of a local buffer.
- // Returns true on success.
- bool CopyDataToChild(const void* local_buffer, size_t buffer_bytes,
- void** remote_buffer) const;
-
- // Performs the cold patch (from the parent) of ntdll.
- // Returns true on success.
- //
- // This method will insert additional interceptions to launch the interceptor
- // agent on the child process, if there are additional interceptions to do.
- bool PatchNtdll(bool hot_patch_needed);
-
- // Peforms the actual interceptions on ntdll.
- // thunks is the memory to store all the thunks for this dll (on the child),
- // and dll_data is a local buffer to hold global dll interception info.
- // Returns true on success.
- bool PatchClientFunctions(DllInterceptionData* thunks,
- size_t thunk_bytes,
- DllInterceptionData* dll_data);
-
- // The process to intercept.
- TargetProcess* child_;
- // Holds all interception info until the call to initialize (perform the
- // actual patch).
- std::list<InterceptionData> interceptions_;
-
- // Keep track of patches added by name.
- bool names_used_;
-
- // true if we are allowed to patch already-patched functions.
- bool relaxed_;
-
- DISALLOW_COPY_AND_ASSIGN(InterceptionManager);
-};
-
-// This macro simply calls interception_manager.AddToPatchedFunctions with
-// the given service to intercept (INTERCEPTION_SERVICE_CALL), and assumes that
-// the interceptor is called "TargetXXX", where XXX is the name of the service.
-// Note that num_params is the number of bytes to pop out of the stack for
-// the exported interceptor, following the calling convention of a service call
-// (WINAPI = with the "C" underscore).
-#if SANDBOX_EXPORTS
-#if defined(_WIN64)
-#define MAKE_SERVICE_NAME(service, params) "Target" # service "64"
-#else
-#define MAKE_SERVICE_NAME(service, params) "_Target" # service "@" # params
-#endif
-
-#define ADD_NT_INTERCEPTION(service, id, num_params) \
- AddToPatchedFunctions(kNtdllName, #service, \
- sandbox::INTERCEPTION_SERVICE_CALL, \
- MAKE_SERVICE_NAME(service, num_params), id)
-
-#define INTERCEPT_NT(manager, service, id, num_params) \
- ((&Target##service) ? \
- manager->ADD_NT_INTERCEPTION(service, id, num_params) : false)
-
-#define INTERCEPT_EAT(manager, dll, function, id, num_params) \
- ((&Target##function) ? \
- manager->AddToPatchedFunctions(dll, #function, sandbox::INTERCEPTION_EAT, \
- MAKE_SERVICE_NAME(function, num_params), \
- id) : \
- false)
-#else // SANDBOX_EXPORTS
-#if defined(_WIN64)
-#define MAKE_SERVICE_NAME(service) &Target##service##64
-#else
-#define MAKE_SERVICE_NAME(service) &Target##service
-#endif
-
-#define ADD_NT_INTERCEPTION(service, id, num_params) \
- AddToPatchedFunctions(kNtdllName, #service, \
- sandbox::INTERCEPTION_SERVICE_CALL, \
- MAKE_SERVICE_NAME(service), id)
-
-#define INTERCEPT_NT(manager, service, id, num_params) \
- manager->ADD_NT_INTERCEPTION(service, id, num_params)
-
-#define INTERCEPT_EAT(manager, dll, function, id, num_params) \
- manager->AddToPatchedFunctions(dll, #function, sandbox::INTERCEPTION_EAT, \
- MAKE_SERVICE_NAME(function), id)
-#endif // SANDBOX_EXPORTS
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_INTERCEPTION_H_
diff --git a/sandbox/win/src/interception_agent.cc b/sandbox/win/src/interception_agent.cc
deleted file mode 100644
index b2a66c4..0000000
--- a/sandbox/win/src/interception_agent.cc
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// For information about interceptions as a whole see
-// http://dev.chromium.org/developers/design-documents/sandbox .
-
-#include "sandbox/win/src/interception_agent.h"
-
-#include "sandbox/win/src/interception_internal.h"
-#include "sandbox/win/src/interceptors.h"
-#include "sandbox/win/src/eat_resolver.h"
-#include "sandbox/win/src/sidestep_resolver.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-
-namespace {
-
-// Returns true if target lies between base and base + range.
-bool IsWithinRange(const void* base, size_t range, const void* target) {
- const char* end = reinterpret_cast<const char*>(base) + range;
- return reinterpret_cast<const char*>(target) < end;
-}
-
-} // namespace
-
-namespace sandbox {
-
-// This is the list of all imported symbols from ntdll.dll.
-SANDBOX_INTERCEPT NtExports g_nt;
-
-// The list of intercepted functions back-pointers.
-SANDBOX_INTERCEPT OriginalFunctions g_originals;
-
-// Memory buffer mapped from the parent, with the list of interceptions.
-SANDBOX_INTERCEPT SharedMemory* g_interceptions = NULL;
-
-InterceptionAgent* InterceptionAgent::GetInterceptionAgent() {
- static InterceptionAgent* s_singleton = NULL;
- if (!s_singleton) {
- if (!g_interceptions)
- return NULL;
-
- size_t array_bytes = g_interceptions->num_intercepted_dlls * sizeof(void*);
- s_singleton = reinterpret_cast<InterceptionAgent*>(
- new(NT_ALLOC) char[array_bytes + sizeof(InterceptionAgent)]);
-
- bool success = s_singleton->Init(g_interceptions);
- if (!success) {
- operator delete(s_singleton, NT_ALLOC);
- s_singleton = NULL;
- }
- }
- return s_singleton;
-}
-
-bool InterceptionAgent::Init(SharedMemory* shared_memory) {
- interceptions_ = shared_memory;
- for (int i = 0 ; i < shared_memory->num_intercepted_dlls; i++)
- dlls_[i] = NULL;
- return true;
-}
-
-bool InterceptionAgent::DllMatch(const UNICODE_STRING* full_path,
- const UNICODE_STRING* name,
- const DllPatchInfo* dll_info) {
- UNICODE_STRING current_name;
- current_name.Length = static_cast<USHORT>(g_nt.wcslen(dll_info->dll_name) *
- sizeof(wchar_t));
- current_name.MaximumLength = current_name.Length;
- current_name.Buffer = const_cast<wchar_t*>(dll_info->dll_name);
-
- BOOLEAN case_insensitive = TRUE;
- if (full_path &&
- !g_nt.RtlCompareUnicodeString(&current_name, full_path, case_insensitive))
- return true;
-
- if (name &&
- !g_nt.RtlCompareUnicodeString(&current_name, name, case_insensitive))
- return true;
-
- return false;
-}
-
-bool InterceptionAgent::OnDllLoad(const UNICODE_STRING* full_path,
- const UNICODE_STRING* name,
- void* base_address) {
- DllPatchInfo* dll_info = interceptions_->dll_list;
- int i = 0;
- for (; i < interceptions_->num_intercepted_dlls; i++) {
- if (DllMatch(full_path, name, dll_info))
- break;
-
- dll_info = reinterpret_cast<DllPatchInfo*>(
- reinterpret_cast<char*>(dll_info) + dll_info->record_bytes);
- }
-
- // Return now if the dll is not in our list of interest.
- if (i == interceptions_->num_intercepted_dlls)
- return true;
-
- // The dll must be unloaded.
- if (dll_info->unload_module)
- return false;
-
- // Purify causes this condition to trigger.
- if (dlls_[i])
- return true;
-
- size_t buffer_bytes = offsetof(DllInterceptionData, thunks) +
- dll_info->num_functions * sizeof(ThunkData);
- dlls_[i] = reinterpret_cast<DllInterceptionData*>(
- new(NT_PAGE, base_address) char[buffer_bytes]);
-
- DCHECK_NT(dlls_[i]);
- if (!dlls_[i])
- return true;
-
- dlls_[i]->data_bytes = buffer_bytes;
- dlls_[i]->num_thunks = 0;
- dlls_[i]->base = base_address;
- dlls_[i]->used_bytes = offsetof(DllInterceptionData, thunks);
-
- VERIFY(PatchDll(dll_info, dlls_[i]));
-
- ULONG old_protect;
- SIZE_T real_size = buffer_bytes;
- void* to_protect = dlls_[i];
- VERIFY_SUCCESS(g_nt.ProtectVirtualMemory(NtCurrentProcess, &to_protect,
- &real_size, PAGE_EXECUTE_READ,
- &old_protect));
- return true;
-}
-
-void InterceptionAgent::OnDllUnload(void* base_address) {
- for (int i = 0; i < interceptions_->num_intercepted_dlls; i++) {
- if (dlls_[i] && dlls_[i]->base == base_address) {
- operator delete(dlls_[i], NT_PAGE);
- dlls_[i] = NULL;
- break;
- }
- }
-}
-
-// TODO(rvargas): We have to deal with prebinded dlls. I see two options: change
-// the timestamp of the patched dll, or modify the info on the prebinded dll.
-// the first approach messes matching of debug symbols, the second one is more
-// complicated.
-bool InterceptionAgent::PatchDll(const DllPatchInfo* dll_info,
- DllInterceptionData* thunks) {
- DCHECK_NT(NULL != thunks);
- DCHECK_NT(NULL != dll_info);
-
- const FunctionInfo* function = reinterpret_cast<const FunctionInfo*>(
- reinterpret_cast<const char*>(dll_info) + dll_info->offset_to_functions);
-
- for (int i = 0; i < dll_info->num_functions; i++) {
- if (!IsWithinRange(dll_info, dll_info->record_bytes, function->function)) {
- NOTREACHED_NT();
- return false;
- }
-
- ResolverThunk* resolver = GetResolver(function->type);
- if (!resolver)
- return false;
-
- const char* interceptor = function->function +
- g_nt.strlen(function->function) + 1;
-
- if (!IsWithinRange(function, function->record_bytes, interceptor) ||
- !IsWithinRange(dll_info, dll_info->record_bytes, interceptor)) {
- NOTREACHED_NT();
- return false;
- }
-
- NTSTATUS ret = resolver->Setup(thunks->base,
- interceptions_->interceptor_base,
- function->function,
- interceptor,
- function->interceptor_address,
- &thunks->thunks[i],
- sizeof(ThunkData),
- NULL);
- if (!NT_SUCCESS(ret)) {
- NOTREACHED_NT();
- return false;
- }
-
- DCHECK_NT(!g_originals[function->id]);
- g_originals[function->id] = &thunks->thunks[i];
-
- thunks->num_thunks++;
- thunks->used_bytes += sizeof(ThunkData);
-
- function = reinterpret_cast<const FunctionInfo*>(
- reinterpret_cast<const char*>(function) + function->record_bytes);
- }
-
- return true;
-}
-
-// This method is called from within the loader lock
-ResolverThunk* InterceptionAgent::GetResolver(InterceptionType type) {
- static EatResolverThunk* eat_resolver = NULL;
- static SidestepResolverThunk* sidestep_resolver = NULL;
- static SmartSidestepResolverThunk* smart_sidestep_resolver = NULL;
-
- if (!eat_resolver)
- eat_resolver = new(NT_ALLOC) EatResolverThunk;
-
-#if !defined(_WIN64)
- // Sidestep is not supported for x64.
- if (!sidestep_resolver)
- sidestep_resolver = new(NT_ALLOC) SidestepResolverThunk;
-
- if (!smart_sidestep_resolver)
- smart_sidestep_resolver = new(NT_ALLOC) SmartSidestepResolverThunk;
-#endif
-
- switch (type) {
- case INTERCEPTION_EAT:
- return eat_resolver;
- case INTERCEPTION_SIDESTEP:
- return sidestep_resolver;
- case INTERCEPTION_SMART_SIDESTEP:
- return smart_sidestep_resolver;
- default:
- NOTREACHED_NT();
- }
-
- return NULL;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/interception_agent.h b/sandbox/win/src/interception_agent.h
deleted file mode 100644
index 2762c61..0000000
--- a/sandbox/win/src/interception_agent.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Defines InterceptionAgent, the class in charge of setting up interceptions
-// from the inside of the sandboxed process. For more details see
-// http://dev.chromium.org/developers/design-documents/sandbox .
-
-#ifndef SANDBOX_SRC_INTERCEPTION_AGENT_H__
-#define SANDBOX_SRC_INTERCEPTION_AGENT_H__
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-namespace sandbox {
-
-// Internal structures used for communication between the broker and the target.
-struct DllInterceptionData;
-struct SharedMemory;
-struct DllPatchInfo;
-
-class ResolverThunk;
-
-// The InterceptionAgent executes on the target application, and it is in charge
-// of setting up the desired interceptions or indicating what module needs to
-// be unloaded.
-//
-// The exposed API consists of three methods: GetInterceptionAgent to retrieve
-// the single class instance, OnDllLoad and OnDllUnload to process a dll being
-// loaded and unloaded respectively.
-//
-// This class assumes that it will get called for every dll being loaded,
-// starting with kernel32, so the singleton will be instantiated from within the
-// loader lock.
-class InterceptionAgent {
- public:
- // Returns the single InterceptionAgent object for this process.
- static InterceptionAgent* GetInterceptionAgent();
-
- // This method should be invoked whenever a new dll is loaded to perform the
- // required patches. If the return value is false, this dll should not be
- // allowed to load.
- //
- // full_path is the (optional) full name of the module being loaded and name
- // is the internal module name. If full_path is provided, it will be used
- // before the internal name to determine if we care about this dll.
- bool OnDllLoad(const UNICODE_STRING* full_path, const UNICODE_STRING* name,
- void* base_address);
-
- // Performs cleanup when a dll is unloaded.
- void OnDllUnload(void* base_address);
-
- private:
- ~InterceptionAgent() {}
-
- // Performs initialization of the singleton.
- bool Init(SharedMemory* shared_memory);
-
- // Returns true if we are interested on this dll. dll_info is an entry of the
- // list of intercepted dlls.
- bool DllMatch(const UNICODE_STRING* full_path, const UNICODE_STRING* name,
- const DllPatchInfo* dll_info);
-
- // Performs the patching of the dll loaded at base_address.
- // The patches to perform are described on dll_info, and thunks is the thunk
- // storage for the whole dll.
- // Returns true on success.
- bool PatchDll(const DllPatchInfo* dll_info, DllInterceptionData* thunks);
-
- // Returns a resolver for a given interception type.
- ResolverThunk* GetResolver(InterceptionType type);
-
- // Shared memory containing the list of functions to intercept.
- SharedMemory* interceptions_;
-
- // Array of thunk data buffers for the intercepted dlls. This object singleton
- // is allocated with a placement new with enough space to hold the complete
- // array of pointers, not just the first element.
- DllInterceptionData* dlls_[1];
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptionAgent);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_INTERCEPTION_AGENT_H__
diff --git a/sandbox/win/src/interception_internal.h b/sandbox/win/src/interception_internal.h
deleted file mode 100644
index 810478a..0000000
--- a/sandbox/win/src/interception_internal.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Defines InterceptionManager, the class in charge of setting up interceptions
-// for the sandboxed process. For more details see:
-// http://dev.chromium.org/developers/design-documents/sandbox .
-
-#ifndef SANDBOX_SRC_INTERCEPTION_INTERNAL_H_
-#define SANDBOX_SRC_INTERCEPTION_INTERNAL_H_
-
-#include "sandbox/win/src/sandbox_types.h"
-
-namespace sandbox {
-
-const int kMaxThunkDataBytes = 64;
-
-enum InterceptorId;
-
-// The following structures contain variable size fields at the end, and will be
-// used to transfer information between two processes. In order to guarantee
-// our ability to follow the chain of structures, the alignment should be fixed,
-// hence this pragma.
-#pragma pack(push, 4)
-
-// Structures for the shared memory that contains patching information
-// for the InterceptionAgent.
-// A single interception:
-struct FunctionInfo {
- size_t record_bytes; // rounded to sizeof(size_t) bytes
- InterceptionType type;
- InterceptorId id;
- const void* interceptor_address;
- char function[1]; // placeholder for null terminated name
- // char interceptor[] // followed by the interceptor function
-};
-
-// A single dll:
-struct DllPatchInfo {
- size_t record_bytes; // rounded to sizeof(size_t) bytes
- size_t offset_to_functions;
- int num_functions;
- bool unload_module;
- wchar_t dll_name[1]; // placeholder for null terminated name
- // FunctionInfo function_info[] // followed by the functions to intercept
-};
-
-// All interceptions:
-struct SharedMemory {
- int num_intercepted_dlls;
- void* interceptor_base;
- DllPatchInfo dll_list[1]; // placeholder for the list of dlls
-};
-
-// Dummy single thunk:
-struct ThunkData {
- char data[kMaxThunkDataBytes];
-};
-
-// In-memory representation of the interceptions for a given dll:
-struct DllInterceptionData {
- size_t data_bytes;
- size_t used_bytes;
- void* base;
- int num_thunks;
-#if defined(_WIN64)
- int dummy; // Improve alignment.
-#endif
- ThunkData thunks[1];
-};
-
-#pragma pack(pop)
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_INTERCEPTION_INTERNAL_H_
diff --git a/sandbox/win/src/interception_unittest.cc b/sandbox/win/src/interception_unittest.cc
deleted file mode 100644
index cc76767..0000000
--- a/sandbox/win/src/interception_unittest.cc
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains unit tests for InterceptionManager.
-// The tests require private information so the whole interception.cc file is
-// included from this file.
-
-#include <windows.h>
-
-#include "base/memory/scoped_ptr.h"
-#include "sandbox/win/src/interception.h"
-#include "sandbox/win/src/interceptors.h"
-#include "sandbox/win/src/interception_internal.h"
-#include "sandbox/win/src/target_process.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace sandbox {
-
-// Walks the settings buffer, verifying that the values make sense and counting
-// objects.
-// Arguments:
-// buffer (in): the buffer to walk.
-// size (in): buffer size
-// num_dlls (out): count of the dlls on the buffer.
-// num_function (out): count of intercepted functions.
-// num_names (out): count of named interceptor functions.
-void WalkBuffer(void* buffer, size_t size, int* num_dlls, int* num_functions,
- int* num_names) {
- ASSERT_TRUE(NULL != buffer);
- ASSERT_TRUE(NULL != num_functions);
- ASSERT_TRUE(NULL != num_names);
- *num_dlls = *num_functions = *num_names = 0;
- SharedMemory *memory = reinterpret_cast<SharedMemory*>(buffer);
-
- ASSERT_GT(size, sizeof(SharedMemory));
- DllPatchInfo *dll = &memory->dll_list[0];
-
- for (int i = 0; i < memory->num_intercepted_dlls; i++) {
- ASSERT_NE(0u, wcslen(dll->dll_name));
- ASSERT_EQ(0u, dll->record_bytes % sizeof(size_t));
- ASSERT_EQ(0u, dll->offset_to_functions % sizeof(size_t));
- ASSERT_NE(0, dll->num_functions);
-
- FunctionInfo *function = reinterpret_cast<FunctionInfo*>(
- reinterpret_cast<char*>(dll) + dll->offset_to_functions);
-
- for (int j = 0; j < dll->num_functions; j++) {
- ASSERT_EQ(0u, function->record_bytes % sizeof(size_t));
-
- char* name = function->function;
- size_t length = strlen(name);
- ASSERT_NE(0u, length);
- name += length + 1;
-
- // look for overflows
- ASSERT_GT(reinterpret_cast<char*>(buffer) + size, name + strlen(name));
-
- // look for a named interceptor
- if (strlen(name)) {
- (*num_names)++;
- EXPECT_TRUE(NULL == function->interceptor_address);
- } else {
- EXPECT_TRUE(NULL != function->interceptor_address);
- }
-
- (*num_functions)++;
- function = reinterpret_cast<FunctionInfo*>(
- reinterpret_cast<char*>(function) + function->record_bytes);
- }
-
- (*num_dlls)++;
- dll = reinterpret_cast<DllPatchInfo*>(reinterpret_cast<char*>(dll) +
- dll->record_bytes);
- }
-}
-
-TEST(InterceptionManagerTest, BufferLayout1) {
- wchar_t exe_name[MAX_PATH];
- ASSERT_NE(0u, GetModuleFileName(NULL, exe_name, MAX_PATH - 1));
-
- TargetProcess *target = MakeTestTargetProcess(::GetCurrentProcess(),
- ::GetModuleHandle(exe_name));
-
- InterceptionManager interceptions(target, true);
-
- // Any pointer will do for a function pointer.
- void* function = &interceptions;
-
- // We don't care about the interceptor id.
- interceptions.AddToPatchedFunctions(L"ntdll.dll", "NtCreateFile",
- INTERCEPTION_SERVICE_CALL, function,
- OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"kernel32.dll", "CreateFileEx",
- INTERCEPTION_EAT, function, OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"kernel32.dll", "SomeFileEx",
- INTERCEPTION_SMART_SIDESTEP, function,
- OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"user32.dll", "FindWindow",
- INTERCEPTION_EAT, function, OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"kernel32.dll", "CreateMutex",
- INTERCEPTION_EAT, function, OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"user32.dll", "PostMsg",
- INTERCEPTION_EAT, function, OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"user32.dll", "PostMsg",
- INTERCEPTION_EAT, "replacement",
- OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"comctl.dll", "SaveAsDlg",
- INTERCEPTION_EAT, function, OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"ntdll.dll", "NtClose",
- INTERCEPTION_SERVICE_CALL, function,
- OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"ntdll.dll", "NtOpenFile",
- INTERCEPTION_SIDESTEP, function,
- OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"some.dll", "Superfn",
- INTERCEPTION_EAT, function, OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"comctl.dll", "SaveAsDlg",
- INTERCEPTION_EAT, "a", OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"comctl.dll", "SaveAsDlg",
- INTERCEPTION_SIDESTEP, "ab", OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"comctl.dll", "SaveAsDlg",
- INTERCEPTION_EAT, "abc", OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"a.dll", "p",
- INTERCEPTION_EAT, function, OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"b.dll",
- "TheIncredibleCallToSaveTheWorld",
- INTERCEPTION_EAT, function, OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"a.dll", "BIsLame",
- INTERCEPTION_EAT, function, OPEN_KEY_ID);
- interceptions.AddToPatchedFunctions(L"a.dll", "ARules",
- INTERCEPTION_EAT, function, OPEN_KEY_ID);
-
- // Verify that all interceptions were added
- ASSERT_EQ(18, interceptions.interceptions_.size());
-
- size_t buffer_size = interceptions.GetBufferSize();
- scoped_array<BYTE> local_buffer(new BYTE[buffer_size]);
-
- ASSERT_TRUE(interceptions.SetupConfigBuffer(local_buffer.get(),
- buffer_size));
-
- // At this point, the interceptions should have been separated into two
- // groups: one group with the local ("cold") interceptions, consisting of
- // everything from ntdll and stuff set as INTRECEPTION_SERVICE_CALL, and
- // another group with the interceptions belonging to dlls that will be "hot"
- // patched on the client. The second group lives on local_buffer, and the
- // first group remains on the list of interceptions (inside the object
- // "interceptions"). There are 3 local interceptions (of ntdll); the
- // other 15 have to be sent to the child to be performed "hot".
- EXPECT_EQ(3, interceptions.interceptions_.size());
-
- int num_dlls, num_functions, num_names;
- WalkBuffer(local_buffer.get(), buffer_size, &num_dlls, &num_functions,
- &num_names);
-
- // The 15 interceptions on the buffer (to the child) should be grouped on 6
- // dlls. Only four interceptions are using an explicit name for the
- // interceptor function.
- EXPECT_EQ(6, num_dlls);
- EXPECT_EQ(15, num_functions);
- EXPECT_EQ(4, num_names);
-}
-
-TEST(InterceptionManagerTest, BufferLayout2) {
- wchar_t exe_name[MAX_PATH];
- ASSERT_NE(0u, GetModuleFileName(NULL, exe_name, MAX_PATH - 1));
-
- TargetProcess *target = MakeTestTargetProcess(::GetCurrentProcess(),
- ::GetModuleHandle(exe_name));
-
- InterceptionManager interceptions(target, true);
-
- // Any pointer will do for a function pointer.
- void* function = &interceptions;
- interceptions.AddToUnloadModules(L"some01.dll");
- // We don't care about the interceptor id.
- interceptions.AddToPatchedFunctions(L"ntdll.dll", "NtCreateFile",
- INTERCEPTION_SERVICE_CALL, function,
- OPEN_FILE_ID);
- interceptions.AddToPatchedFunctions(L"kernel32.dll", "CreateFileEx",
- INTERCEPTION_EAT, function, OPEN_FILE_ID);
- interceptions.AddToUnloadModules(L"some02.dll");
- interceptions.AddToPatchedFunctions(L"kernel32.dll", "SomeFileEx",
- INTERCEPTION_SMART_SIDESTEP, function,
- OPEN_FILE_ID);
- // Verify that all interceptions were added
- ASSERT_EQ(5, interceptions.interceptions_.size());
-
- size_t buffer_size = interceptions.GetBufferSize();
- scoped_array<BYTE> local_buffer(new BYTE[buffer_size]);
-
- ASSERT_TRUE(interceptions.SetupConfigBuffer(local_buffer.get(),
- buffer_size));
-
- // At this point, the interceptions should have been separated into two
- // groups: one group with the local ("cold") interceptions, and another
- // group with the interceptions belonging to dlls that will be "hot"
- // patched on the client. The second group lives on local_buffer, and the
- // first group remains on the list of interceptions, in this case just one.
- EXPECT_EQ(1, interceptions.interceptions_.size());
-
- int num_dlls, num_functions, num_names;
- WalkBuffer(local_buffer.get(), buffer_size, &num_dlls, &num_functions,
- &num_names);
-
- EXPECT_EQ(3, num_dlls);
- EXPECT_EQ(4, num_functions);
- EXPECT_EQ(0, num_names);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/interceptors.h b/sandbox/win/src/interceptors.h
deleted file mode 100644
index 43126d0..0000000
--- a/sandbox/win/src/interceptors.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_INTERCEPTORS_H_
-#define SANDBOX_SRC_INTERCEPTORS_H_
-
-#if defined(_WIN64)
-#include "sandbox/win/src/interceptors_64.h"
-#endif
-
-namespace sandbox {
-
-enum InterceptorId {
- // Internal use:
- MAP_VIEW_OF_SECTION_ID = 0,
- UNMAP_VIEW_OF_SECTION_ID,
- // Policy broker:
- SET_INFORMATION_THREAD_ID,
- OPEN_THREAD_TOKEN_ID,
- OPEN_THREAD_TOKEN_EX_ID,
- OPEN_TREAD_ID,
- OPEN_PROCESS_ID,
- OPEN_PROCESS_TOKEN_ID,
- OPEN_PROCESS_TOKEN_EX_ID,
- // Filesystem dispatcher:
- CREATE_FILE_ID,
- OPEN_FILE_ID,
- QUERY_ATTRIB_FILE_ID,
- QUERY_FULL_ATTRIB_FILE_ID,
- SET_INFO_FILE_ID,
- // Named pipe dispatcher:
- CREATE_NAMED_PIPE_ID,
- // Process-thread dispatcher:
- CREATE_PROCESSW_ID,
- CREATE_PROCESSA_ID,
- // Registry dispatcher:
- CREATE_KEY_ID,
- OPEN_KEY_ID,
- OPEN_KEY_EX_ID,
- // Sync dispatcher:
- CREATE_EVENT_ID,
- OPEN_EVENT_ID,
- // CSRSS bypasses for HandleCloser:
- CREATE_THREAD_ID,
- GET_USER_DEFAULT_LCID_ID,
- INTERCEPTOR_MAX_ID
-};
-
-typedef void* OriginalFunctions[INTERCEPTOR_MAX_ID];
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_INTERCEPTORS_H_
diff --git a/sandbox/win/src/interceptors_64.cc b/sandbox/win/src/interceptors_64.cc
deleted file mode 100644
index 30843fd..0000000
--- a/sandbox/win/src/interceptors_64.cc
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/interceptors_64.h"
-
-#include "sandbox/win/src/interceptors.h"
-#include "sandbox/win/src/filesystem_interception.h"
-#include "sandbox/win/src/named_pipe_interception.h"
-#include "sandbox/win/src/policy_target.h"
-#include "sandbox/win/src/process_thread_interception.h"
-#include "sandbox/win/src/registry_interception.h"
-#include "sandbox/win/src/sandbox_nt_types.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/sync_interception.h"
-#include "sandbox/win/src/target_interceptions.h"
-
-namespace sandbox {
-
-SANDBOX_INTERCEPT NtExports g_nt;
-SANDBOX_INTERCEPT OriginalFunctions g_originals;
-
-NTSTATUS WINAPI TargetNtMapViewOfSection64(
- HANDLE section, HANDLE process, PVOID *base, ULONG_PTR zero_bits,
- SIZE_T commit_size, PLARGE_INTEGER offset, PSIZE_T view_size,
- SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect) {
- NtMapViewOfSectionFunction orig_fn = reinterpret_cast<
- NtMapViewOfSectionFunction>(g_originals[MAP_VIEW_OF_SECTION_ID]);
-
- return TargetNtMapViewOfSection(orig_fn, section, process, base, zero_bits,
- commit_size, offset, view_size, inherit,
- allocation_type, protect);
-}
-
-NTSTATUS WINAPI TargetNtUnmapViewOfSection64(HANDLE process, PVOID base) {
- NtUnmapViewOfSectionFunction orig_fn = reinterpret_cast<
- NtUnmapViewOfSectionFunction>(g_originals[UNMAP_VIEW_OF_SECTION_ID]);
- return TargetNtUnmapViewOfSection(orig_fn, process, base);
-}
-
-// -----------------------------------------------------------------------
-
-NTSTATUS WINAPI TargetNtSetInformationThread64(
- HANDLE thread, NT_THREAD_INFORMATION_CLASS thread_info_class,
- PVOID thread_information, ULONG thread_information_bytes) {
- NtSetInformationThreadFunction orig_fn = reinterpret_cast<
- NtSetInformationThreadFunction>(g_originals[SET_INFORMATION_THREAD_ID]);
- return TargetNtSetInformationThread(orig_fn, thread, thread_info_class,
- thread_information,
- thread_information_bytes);
-}
-
-NTSTATUS WINAPI TargetNtOpenThreadToken64(
- HANDLE thread, ACCESS_MASK desired_access, BOOLEAN open_as_self,
- PHANDLE token) {
- NtOpenThreadTokenFunction orig_fn = reinterpret_cast<
- NtOpenThreadTokenFunction>(g_originals[OPEN_THREAD_TOKEN_ID]);
- return TargetNtOpenThreadToken(orig_fn, thread, desired_access, open_as_self,
- token);
-}
-
-NTSTATUS WINAPI TargetNtOpenThreadTokenEx64(
- HANDLE thread, ACCESS_MASK desired_access, BOOLEAN open_as_self,
- ULONG handle_attributes, PHANDLE token) {
- NtOpenThreadTokenExFunction orig_fn = reinterpret_cast<
- NtOpenThreadTokenExFunction>(g_originals[OPEN_THREAD_TOKEN_EX_ID]);
- return TargetNtOpenThreadTokenEx(orig_fn, thread, desired_access,
- open_as_self, handle_attributes, token);
-}
-
-HANDLE WINAPI TargetCreateThread64(
- LPSECURITY_ATTRIBUTES thread_attributes, SIZE_T stack_size,
- LPTHREAD_START_ROUTINE start_address, PVOID parameter, DWORD creation_flags,
- LPDWORD thread_id) {
- CreateThreadFunction orig_fn = reinterpret_cast<
- CreateThreadFunction>(g_originals[CREATE_THREAD_ID]);
- return TargetCreateThread(orig_fn, thread_attributes, stack_size,
- start_address, parameter, creation_flags,
- thread_id);
-}
-
-LCID WINAPI TargetGetUserDefaultLCID64(void) {
- GetUserDefaultLCIDFunction orig_fn = reinterpret_cast<
- GetUserDefaultLCIDFunction>(g_originals[GET_USER_DEFAULT_LCID_ID]);
- return TargetGetUserDefaultLCID(orig_fn);
-}
-
-// -----------------------------------------------------------------------
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtCreateFile64(
- PHANDLE file, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, PIO_STATUS_BLOCK io_status,
- PLARGE_INTEGER allocation_size, ULONG file_attributes, ULONG sharing,
- ULONG disposition, ULONG options, PVOID ea_buffer, ULONG ea_length) {
- NtCreateFileFunction orig_fn = reinterpret_cast<
- NtCreateFileFunction>(g_originals[CREATE_FILE_ID]);
- return TargetNtCreateFile(orig_fn, file, desired_access, object_attributes,
- io_status, allocation_size, file_attributes,
- sharing, disposition, options, ea_buffer,
- ea_length);
-}
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenFile64(
- PHANDLE file, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, PIO_STATUS_BLOCK io_status,
- ULONG sharing, ULONG options) {
- NtOpenFileFunction orig_fn = reinterpret_cast<
- NtOpenFileFunction>(g_originals[OPEN_FILE_ID]);
- return TargetNtOpenFile(orig_fn, file, desired_access, object_attributes,
- io_status, sharing, options);
-}
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtQueryAttributesFile64(
- POBJECT_ATTRIBUTES object_attributes,
- PFILE_BASIC_INFORMATION file_attributes) {
- NtQueryAttributesFileFunction orig_fn = reinterpret_cast<
- NtQueryAttributesFileFunction>(g_originals[QUERY_ATTRIB_FILE_ID]);
- return TargetNtQueryAttributesFile(orig_fn, object_attributes,
- file_attributes);
-}
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtQueryFullAttributesFile64(
- POBJECT_ATTRIBUTES object_attributes,
- PFILE_NETWORK_OPEN_INFORMATION file_attributes) {
- NtQueryFullAttributesFileFunction orig_fn = reinterpret_cast<
- NtQueryFullAttributesFileFunction>(
- g_originals[QUERY_FULL_ATTRIB_FILE_ID]);
- return TargetNtQueryFullAttributesFile(orig_fn, object_attributes,
- file_attributes);
-}
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtSetInformationFile64(
- HANDLE file, PIO_STATUS_BLOCK io_status, PVOID file_information,
- ULONG length, FILE_INFORMATION_CLASS file_information_class) {
- NtSetInformationFileFunction orig_fn = reinterpret_cast<
- NtSetInformationFileFunction>(g_originals[SET_INFO_FILE_ID]);
- return TargetNtSetInformationFile(orig_fn, file, io_status, file_information,
- length, file_information_class);
-}
-
-// -----------------------------------------------------------------------
-
-SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateNamedPipeW64(
- LPCWSTR pipe_name, DWORD open_mode, DWORD pipe_mode, DWORD max_instance,
- DWORD out_buffer_size, DWORD in_buffer_size, DWORD default_timeout,
- LPSECURITY_ATTRIBUTES security_attributes) {
- CreateNamedPipeWFunction orig_fn = reinterpret_cast<
- CreateNamedPipeWFunction>(g_originals[CREATE_NAMED_PIPE_ID]);
- return TargetCreateNamedPipeW(orig_fn, pipe_name, open_mode, pipe_mode,
- max_instance, out_buffer_size, in_buffer_size,
- default_timeout, security_attributes);
-}
-
-// -----------------------------------------------------------------------
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenThread64(
- PHANDLE thread, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, PCLIENT_ID client_id) {
- NtOpenThreadFunction orig_fn = reinterpret_cast<
- NtOpenThreadFunction>(g_originals[OPEN_TREAD_ID]);
- return TargetNtOpenThread(orig_fn, thread, desired_access, object_attributes,
- client_id);
-}
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenProcess64(
- PHANDLE process, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, PCLIENT_ID client_id) {
- NtOpenProcessFunction orig_fn = reinterpret_cast<
- NtOpenProcessFunction>(g_originals[OPEN_PROCESS_ID]);
- return TargetNtOpenProcess(orig_fn, process, desired_access,
- object_attributes, client_id);
-}
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenProcessToken64(
- HANDLE process, ACCESS_MASK desired_access, PHANDLE token) {
- NtOpenProcessTokenFunction orig_fn = reinterpret_cast<
- NtOpenProcessTokenFunction>(g_originals[OPEN_PROCESS_TOKEN_ID]);
- return TargetNtOpenProcessToken(orig_fn, process, desired_access, token);
-}
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenProcessTokenEx64(
- HANDLE process, ACCESS_MASK desired_access, ULONG handle_attributes,
- PHANDLE token) {
- NtOpenProcessTokenExFunction orig_fn = reinterpret_cast<
- NtOpenProcessTokenExFunction>(g_originals[OPEN_PROCESS_TOKEN_EX_ID]);
- return TargetNtOpenProcessTokenEx(orig_fn, process, desired_access,
- handle_attributes, token);
-}
-
-SANDBOX_INTERCEPT BOOL WINAPI TargetCreateProcessW64(
- LPCWSTR application_name, LPWSTR command_line,
- LPSECURITY_ATTRIBUTES process_attributes,
- LPSECURITY_ATTRIBUTES thread_attributes, BOOL inherit_handles, DWORD flags,
- LPVOID environment, LPCWSTR current_directory, LPSTARTUPINFOW startup_info,
- LPPROCESS_INFORMATION process_information) {
- CreateProcessWFunction orig_fn = reinterpret_cast<
- CreateProcessWFunction>(g_originals[CREATE_PROCESSW_ID]);
- return TargetCreateProcessW(orig_fn, application_name, command_line,
- process_attributes, thread_attributes,
- inherit_handles, flags, environment,
- current_directory, startup_info,
- process_information);
-}
-
-SANDBOX_INTERCEPT BOOL WINAPI TargetCreateProcessA64(
- LPCSTR application_name, LPSTR command_line,
- LPSECURITY_ATTRIBUTES process_attributes,
- LPSECURITY_ATTRIBUTES thread_attributes, BOOL inherit_handles, DWORD flags,
- LPVOID environment, LPCSTR current_directory, LPSTARTUPINFOA startup_info,
- LPPROCESS_INFORMATION process_information) {
- CreateProcessAFunction orig_fn = reinterpret_cast<
- CreateProcessAFunction>(g_originals[CREATE_PROCESSA_ID]);
- return TargetCreateProcessA(orig_fn, application_name, command_line,
- process_attributes, thread_attributes,
- inherit_handles, flags, environment,
- current_directory, startup_info,
- process_information);
-}
-
-// -----------------------------------------------------------------------
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtCreateKey64(
- PHANDLE key, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, ULONG title_index,
- PUNICODE_STRING class_name, ULONG create_options, PULONG disposition) {
- NtCreateKeyFunction orig_fn = reinterpret_cast<
- NtCreateKeyFunction>(g_originals[CREATE_KEY_ID]);
- return TargetNtCreateKey(orig_fn, key, desired_access, object_attributes,
- title_index, class_name, create_options,
- disposition);
-}
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenKey64(
- PHANDLE key, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes) {
- NtOpenKeyFunction orig_fn = reinterpret_cast<
- NtOpenKeyFunction>(g_originals[OPEN_KEY_ID]);
- return TargetNtOpenKey(orig_fn, key, desired_access, object_attributes);
-}
-
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenKeyEx64(
- PHANDLE key, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, ULONG open_options) {
- NtOpenKeyExFunction orig_fn = reinterpret_cast<
- NtOpenKeyExFunction>(g_originals[OPEN_KEY_EX_ID]);
- return TargetNtOpenKeyEx(orig_fn, key, desired_access, object_attributes,
- open_options);
-}
-
-// -----------------------------------------------------------------------
-
-SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateEventW64(
- LPSECURITY_ATTRIBUTES security_attributes, BOOL manual_reset,
- BOOL initial_state, LPCWSTR name) {
- CreateEventWFunction orig_fn = reinterpret_cast<
- CreateEventWFunction>(g_originals[CREATE_EVENT_ID]);
- return TargetCreateEventW(orig_fn, security_attributes, manual_reset,
- initial_state, name);
-}
-
-SANDBOX_INTERCEPT HANDLE WINAPI TargetOpenEventW64(
- ACCESS_MASK desired_access, BOOL inherit_handle, LPCWSTR name) {
- OpenEventWFunction orig_fn = reinterpret_cast<
- OpenEventWFunction>(g_originals[OPEN_EVENT_ID]);
- return TargetOpenEventW(orig_fn, desired_access, inherit_handle, name);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/interceptors_64.h b/sandbox/win/src/interceptors_64.h
deleted file mode 100644
index 87c1c50..0000000
--- a/sandbox/win/src/interceptors_64.h
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-#ifndef SANDBOX_SRC_INTERCEPTORS_64_H_
-#define SANDBOX_SRC_INTERCEPTORS_64_H_
-
-namespace sandbox {
-
-extern "C" {
-
-// Interception of NtMapViewOfSection on the child process.
-// It should never be called directly. This function provides the means to
-// detect dlls being loaded, so we can patch them if needed.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtMapViewOfSection64(
- HANDLE section, HANDLE process, PVOID *base, ULONG_PTR zero_bits,
- SIZE_T commit_size, PLARGE_INTEGER offset, PSIZE_T view_size,
- SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect);
-
-// Interception of NtUnmapViewOfSection on the child process.
-// It should never be called directly. This function provides the means to
-// detect dlls being unloaded, so we can clean up our interceptions.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtUnmapViewOfSection64(HANDLE process,
- PVOID base);
-
-// -----------------------------------------------------------------------
-// Interceptors without IPC.
-
-// Interception of NtSetInformationThread on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtSetInformationThread64(
- HANDLE thread, NT_THREAD_INFORMATION_CLASS thread_info_class,
- PVOID thread_information, ULONG thread_information_bytes);
-
-// Interception of NtOpenThreadToken on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenThreadToken64(
- HANDLE thread, ACCESS_MASK desired_access, BOOLEAN open_as_self,
- PHANDLE token);
-
-// Interception of NtOpenThreadTokenEx on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenThreadTokenEx64(
- HANDLE thread, ACCESS_MASK desired_access, BOOLEAN open_as_self,
- ULONG handle_attributes, PHANDLE token);
-
-// Interception of CreateThread on the child process.
-SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateThread64(
- LPSECURITY_ATTRIBUTES thread_attributes, SIZE_T stack_size,
- LPTHREAD_START_ROUTINE start_address, PVOID parameter,
- DWORD creation_flags, LPDWORD thread_id);
-
-// Interception of GetUserDefaultLCID on the child process.
-SANDBOX_INTERCEPT LCID WINAPI TargetGetUserDefaultLCID64();
-
-// -----------------------------------------------------------------------
-// Interceptors handled by the file system dispatcher.
-
-// Interception of NtCreateFile on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtCreateFile64(
- PHANDLE file, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, PIO_STATUS_BLOCK io_status,
- PLARGE_INTEGER allocation_size, ULONG file_attributes, ULONG sharing,
- ULONG disposition, ULONG options, PVOID ea_buffer, ULONG ea_length);
-
-// Interception of NtOpenFile on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenFile64(
- PHANDLE file, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, PIO_STATUS_BLOCK io_status,
- ULONG sharing, ULONG options);
-
-// Interception of NtQueryAtttributesFile on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtQueryAttributesFile64(
- POBJECT_ATTRIBUTES object_attributes,
- PFILE_BASIC_INFORMATION file_attributes);
-
-// Interception of NtQueryFullAtttributesFile on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtQueryFullAttributesFile64(
- POBJECT_ATTRIBUTES object_attributes,
- PFILE_NETWORK_OPEN_INFORMATION file_attributes);
-
-// Interception of NtSetInformationFile on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtSetInformationFile64(
- HANDLE file, PIO_STATUS_BLOCK io_status, PVOID file_information,
- ULONG length, FILE_INFORMATION_CLASS file_information_class);
-
-// -----------------------------------------------------------------------
-// Interceptors handled by the named pipe dispatcher.
-
-// Interception of CreateNamedPipeW in kernel32.dll
-SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateNamedPipeW64(
- LPCWSTR pipe_name, DWORD open_mode, DWORD pipe_mode, DWORD max_instance,
- DWORD out_buffer_size, DWORD in_buffer_size, DWORD default_timeout,
- LPSECURITY_ATTRIBUTES security_attributes);
-
-// -----------------------------------------------------------------------
-// Interceptors handled by the process-thread dispatcher.
-
-// Interception of NtOpenThread on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenThread64(
- PHANDLE thread, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, PCLIENT_ID client_id);
-
-// Interception of NtOpenProcess on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenProcess64(
- PHANDLE process, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, PCLIENT_ID client_id);
-
-// Interception of NtOpenProcessToken on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenProcessToken64(
- HANDLE process, ACCESS_MASK desired_access, PHANDLE token);
-
-// Interception of NtOpenProcessTokenEx on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenProcessTokenEx64(
- HANDLE process, ACCESS_MASK desired_access, ULONG handle_attributes,
- PHANDLE token);
-
-// Interception of CreateProcessW in kernel32.dll.
-SANDBOX_INTERCEPT BOOL WINAPI TargetCreateProcessW64(
- LPCWSTR application_name, LPWSTR command_line,
- LPSECURITY_ATTRIBUTES process_attributes,
- LPSECURITY_ATTRIBUTES thread_attributes, BOOL inherit_handles, DWORD flags,
- LPVOID environment, LPCWSTR current_directory, LPSTARTUPINFOW startup_info,
- LPPROCESS_INFORMATION process_information);
-
-// Interception of CreateProcessA in kernel32.dll.
-SANDBOX_INTERCEPT BOOL WINAPI TargetCreateProcessA64(
- LPCSTR application_name, LPSTR command_line,
- LPSECURITY_ATTRIBUTES process_attributes,
- LPSECURITY_ATTRIBUTES thread_attributes, BOOL inherit_handles, DWORD flags,
- LPVOID environment, LPCSTR current_directory, LPSTARTUPINFOA startup_info,
- LPPROCESS_INFORMATION process_information);
-
-// -----------------------------------------------------------------------
-// Interceptors handled by the registry dispatcher.
-
-// Interception of NtCreateKey on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtCreateKey64(
- PHANDLE key, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, ULONG title_index,
- PUNICODE_STRING class_name, ULONG create_options, PULONG disposition);
-
-// Interception of NtOpenKey on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenKey64(
- PHANDLE key, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes);
-
-// Interception of NtOpenKeyEx on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenKeyEx64(
- PHANDLE key, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, ULONG open_options);
-
-// -----------------------------------------------------------------------
-// Interceptors handled by the sync dispatcher.
-
-// Interception of CreateEventW on the child process.
-SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateEventW64(
- LPSECURITY_ATTRIBUTES security_attributes, BOOL manual_reset,
- BOOL initial_state, LPCWSTR name);
-
-// Interception of OpenEventW on the child process.
-SANDBOX_INTERCEPT HANDLE WINAPI TargetOpenEventW64(
- ACCESS_MASK desired_access, BOOL inherit_handle, LPCWSTR name);
-
-} // extern "C"
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_INTERCEPTORS_64_H_
diff --git a/sandbox/win/src/internal_types.h b/sandbox/win/src/internal_types.h
deleted file mode 100644
index db969aa..0000000
--- a/sandbox/win/src/internal_types.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_INTERNAL_TYPES_H_
-#define SANDBOX_SRC_INTERNAL_TYPES_H_
-
-namespace sandbox {
-
-const wchar_t kNtdllName[] = L"ntdll.dll";
-const wchar_t kKerneldllName[] = L"kernel32.dll";
-
-// Defines the supported C++ types encoding to numeric id. Like a poor's man
-// RTTI. Note that true C++ RTTI will not work because the types are not
-// polymorphic anyway.
-enum ArgType {
- INVALID_TYPE = 0,
- WCHAR_TYPE,
- ULONG_TYPE,
- UNISTR_TYPE,
- VOIDPTR_TYPE,
- INPTR_TYPE,
- INOUTPTR_TYPE,
- LAST_TYPE
-};
-
-// Encapsulates a pointer to a buffer and the size of the buffer.
-class CountedBuffer {
- public:
- CountedBuffer(void* buffer, uint32 size) : size_(size), buffer_(buffer) {}
-
- uint32 Size() const {
- return size_;
- }
-
- void* Buffer() const {
- return buffer_;
- }
-
- private:
- uint32 size_;
- void* buffer_;
-};
-
-// Helper class to convert void-pointer packed ints for both
-// 32 and 64 bit builds. This construct is non-portable.
-class IPCInt {
- public:
- explicit IPCInt(void* buffer) {
- buffer_.vp = buffer;
- }
-
- explicit IPCInt(unsigned __int32 i32) {
- buffer_.vp = NULL;
- buffer_.i32 = i32;
- }
-
- unsigned __int32 As32Bit() const {
- return buffer_.i32;
- }
-
- void* AsVoidPtr() const {
- return buffer_.vp;
- }
-
- private:
- union U {
- void* vp;
- unsigned __int32 i32;
- } buffer_;
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_INTERNAL_TYPES_H_
diff --git a/sandbox/win/src/ipc_ping_test.cc b/sandbox/win/src/ipc_ping_test.cc
deleted file mode 100644
index 64e3de6..0000000
--- a/sandbox/win/src/ipc_ping_test.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/target_services.h"
-#include "sandbox/win/tests/common/controller.h"
-
-namespace sandbox {
-
-// Tests that the IPC is working by issuing a special IPC that is not exposed
-// in the public API.
-SBOX_TESTS_COMMAND int IPC_Ping(int argc, wchar_t **argv) {
- if (argc != 1)
- return SBOX_TEST_FAILED;
-
- TargetServices* ts = SandboxFactory::GetTargetServices();
- if (NULL == ts)
- return SBOX_TEST_FAILED;
-
- // Downcast because we have internal knowledge of the object returned.
- TargetServicesBase* ts_base = reinterpret_cast<TargetServicesBase*>(ts);
-
- int version = 0;
- if (L'1' == argv[0][0])
- version = 1;
- else
- version = 2;
-
- if (!ts_base->TestIPCPing(version))
- return SBOX_TEST_FAILED;
-
- ::Sleep(1);
- if (!ts_base->TestIPCPing(version))
- return SBOX_TEST_FAILED;
-
- return SBOX_TEST_SUCCEEDED;
-}
-
-// The IPC ping test should work before and after the token drop.
-TEST(IPCTest, IPCPingTestSimple) {
- TestRunner runner;
- runner.SetTimeout(2000);
- runner.SetTestState(EVERY_STATE);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"IPC_Ping 1"));
-}
-
-TEST(IPCTest, IPCPingTestWithOutput) {
- TestRunner runner;
- runner.SetTimeout(2000);
- runner.SetTestState(EVERY_STATE);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"IPC_Ping 2"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"IPC_Ping 2"));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/ipc_tags.h b/sandbox/win/src/ipc_tags.h
deleted file mode 100644
index 4e3a806..0000000
--- a/sandbox/win/src/ipc_tags.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_IPC_TAGS_H__
-#define SANDBOX_SRC_IPC_TAGS_H__
-
-namespace sandbox {
-
-enum {
- IPC_UNUSED_TAG = 0,
- IPC_PING1_TAG, // Takes a cookie in parameters and returns the cookie
- // multiplied by 2 and the tick_count. Used for testing only.
- IPC_PING2_TAG, // Takes an in/out cookie in parameters and modify the cookie
- // to be multiplied by 3. Used for testing only.
- IPC_NTCREATEFILE_TAG,
- IPC_NTOPENFILE_TAG,
- IPC_NTQUERYATTRIBUTESFILE_TAG,
- IPC_NTQUERYFULLATTRIBUTESFILE_TAG,
- IPC_NTSETINFO_RENAME_TAG,
- IPC_CREATENAMEDPIPEW_TAG,
- IPC_NTOPENTHREAD_TAG,
- IPC_NTOPENPROCESS_TAG,
- IPC_NTOPENPROCESSTOKEN_TAG,
- IPC_NTOPENPROCESSTOKENEX_TAG,
- IPC_CREATEPROCESSW_TAG,
- IPC_CREATEEVENT_TAG,
- IPC_OPENEVENT_TAG,
- IPC_NTCREATEKEY_TAG,
- IPC_NTOPENKEY_TAG,
- IPC_DUPLICATEHANDLEPROXY_TAG,
- IPC_LAST_TAG
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_IPC_TAGS_H__
diff --git a/sandbox/win/src/ipc_unittest.cc b/sandbox/win/src/ipc_unittest.cc
deleted file mode 100644
index daca7bb..0000000
--- a/sandbox/win/src/ipc_unittest.cc
+++ /dev/null
@@ -1,641 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "sandbox/win/src/sharedmem_ipc_server.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace sandbox {
-
-// Helper function to make the fake shared memory with some
-// basic elements initialized.
-IPCControl* MakeChannels(size_t channel_size, size_t total_shared_size,
- size_t* base_start) {
- // Allocate memory
- char* mem = new char[total_shared_size];
- memset(mem, 0, total_shared_size);
- // Calculate how many channels we can fit in the shared memory.
- total_shared_size -= offsetof(IPCControl, channels);
- size_t channel_count =
- total_shared_size / (sizeof(ChannelControl) + channel_size);
- // Calculate the start of the first channel.
- *base_start = (sizeof(ChannelControl)* channel_count) +
- offsetof(IPCControl, channels);
- // Setup client structure.
- IPCControl* client_control = reinterpret_cast<IPCControl*>(mem);
- client_control->channels_count = channel_count;
- return client_control;
-}
-
-enum TestFixMode {
- FIX_NO_EVENTS,
- FIX_PONG_READY,
- FIX_PONG_NOT_READY
-};
-
-void FixChannels(IPCControl* client_control, size_t base_start,
- size_t channel_size, TestFixMode mode) {
- for (size_t ix = 0; ix != client_control->channels_count; ++ix) {
- ChannelControl& channel = client_control->channels[ix];
- channel.channel_base = base_start;
- channel.state = kFreeChannel;
- if (mode != FIX_NO_EVENTS) {
- BOOL signaled = (FIX_PONG_READY == mode)? TRUE : FALSE;
- channel.ping_event = ::CreateEventW(NULL, FALSE, FALSE, NULL);
- channel.pong_event = ::CreateEventW(NULL, FALSE, signaled, NULL);
- }
- base_start += channel_size;
- }
-}
-
-void CloseChannelEvents(IPCControl* client_control) {
- for (size_t ix = 0; ix != client_control->channels_count; ++ix) {
- ChannelControl& channel = client_control->channels[ix];
- ::CloseHandle(channel.ping_event);
- ::CloseHandle(channel.pong_event);
- }
-}
-
-TEST(IPCTest, ChannelMaker) {
- // Test that our testing rig is computing offsets properly. We should have
- // 5 channnels and the offset to the first channel is 108 bytes in 32 bits
- // and 216 in 64 bits.
- size_t channel_start = 0;
- IPCControl* client_control = MakeChannels(12 * 64, 4096, &channel_start);
- ASSERT_TRUE(NULL != client_control);
- EXPECT_EQ(5, client_control->channels_count);
-#if defined(_WIN64)
- EXPECT_EQ(216, channel_start);
-#else
- EXPECT_EQ(108, channel_start);
-#endif
- delete[] reinterpret_cast<char*>(client_control);
-}
-
-TEST(IPCTest, ClientLockUnlock) {
- // Make 7 channels of kIPCChannelSize (1kb) each. Test that we lock and
- // unlock channels properly.
- size_t base_start = 0;
- IPCControl* client_control =
- MakeChannels(kIPCChannelSize, 4096 * 2, &base_start);
- FixChannels(client_control, base_start, kIPCChannelSize, FIX_NO_EVENTS);
-
- char* mem = reinterpret_cast<char*>(client_control);
- SharedMemIPCClient client(mem);
-
- // Test that we lock the first 3 channels in sequence.
- void* buff0 = client.GetBuffer();
- EXPECT_TRUE(mem + client_control->channels[0].channel_base == buff0);
- EXPECT_EQ(kBusyChannel, client_control->channels[0].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[1].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[2].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[3].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[4].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[5].state);
-
- void* buff1 = client.GetBuffer();
- EXPECT_TRUE(mem + client_control->channels[1].channel_base == buff1);
- EXPECT_EQ(kBusyChannel, client_control->channels[0].state);
- EXPECT_EQ(kBusyChannel, client_control->channels[1].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[2].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[3].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[4].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[5].state);
-
- void* buff2 = client.GetBuffer();
- EXPECT_TRUE(mem + client_control->channels[2].channel_base == buff2);
- EXPECT_EQ(kBusyChannel, client_control->channels[0].state);
- EXPECT_EQ(kBusyChannel, client_control->channels[1].state);
- EXPECT_EQ(kBusyChannel, client_control->channels[2].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[3].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[4].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[5].state);
-
- // Test that we unlock and re-lock the right channel.
- client.FreeBuffer(buff1);
- EXPECT_EQ(kBusyChannel, client_control->channels[0].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[1].state);
- EXPECT_EQ(kBusyChannel, client_control->channels[2].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[3].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[4].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[5].state);
-
- void* buff2b = client.GetBuffer();
- EXPECT_TRUE(mem + client_control->channels[1].channel_base == buff2b);
- EXPECT_EQ(kBusyChannel, client_control->channels[0].state);
- EXPECT_EQ(kBusyChannel, client_control->channels[1].state);
- EXPECT_EQ(kBusyChannel, client_control->channels[2].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[3].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[4].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[5].state);
-
- client.FreeBuffer(buff0);
- EXPECT_EQ(kFreeChannel, client_control->channels[0].state);
- EXPECT_EQ(kBusyChannel, client_control->channels[1].state);
- EXPECT_EQ(kBusyChannel, client_control->channels[2].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[3].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[4].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[5].state);
-
- delete[] reinterpret_cast<char*>(client_control);
-}
-
-TEST(IPCTest, CrossCallStrPacking) {
- // This test tries the CrossCall object with null and non-null string
- // combination of parameters, integer types and verifies that the unpacker
- // can read them properly.
- size_t base_start = 0;
- IPCControl* client_control =
- MakeChannels(kIPCChannelSize, 4096 * 4, &base_start);
- client_control->server_alive = HANDLE(1);
- FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_READY);
-
- char* mem = reinterpret_cast<char*>(client_control);
- SharedMemIPCClient client(mem);
-
- CrossCallReturn answer;
- uint32 tag1 = 666;
- const wchar_t text[] = L"98765 - 43210";
- std::wstring copied_text;
- CrossCallParamsEx* actual_params;
-
- CrossCall(client, tag1, text, &answer);
- actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer());
- EXPECT_EQ(1, actual_params->GetParamsCount());
- EXPECT_EQ(tag1, actual_params->GetTag());
- EXPECT_TRUE(actual_params->GetParameterStr(0, &copied_text));
- EXPECT_STREQ(text, copied_text.c_str());
-
- // Check with an empty string.
- uint32 tag2 = 777;
- const wchar_t* null_text = NULL;
- CrossCall(client, tag2, null_text, &answer);
- actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer());
- EXPECT_EQ(1, actual_params->GetParamsCount());
- EXPECT_EQ(tag2, actual_params->GetTag());
- uint32 param_size = 1;
- ArgType type = INVALID_TYPE;
- void* param_addr = actual_params->GetRawParameter(0, &param_size, &type);
- EXPECT_TRUE(NULL != param_addr);
- EXPECT_EQ(0, param_size);
- EXPECT_EQ(WCHAR_TYPE, type);
- EXPECT_TRUE(actual_params->GetParameterStr(0, &copied_text));
-
- uint32 tag3 = 888;
- param_size = 1;
- copied_text.clear();
-
- // Check with an empty string and a non-empty string.
- CrossCall(client, tag3, null_text, text, &answer);
- actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer());
- EXPECT_EQ(2, actual_params->GetParamsCount());
- EXPECT_EQ(tag3, actual_params->GetTag());
- type = INVALID_TYPE;
- param_addr = actual_params->GetRawParameter(0, &param_size, &type);
- EXPECT_TRUE(NULL != param_addr);
- EXPECT_EQ(0, param_size);
- EXPECT_EQ(WCHAR_TYPE, type);
- EXPECT_TRUE(actual_params->GetParameterStr(0, &copied_text));
- EXPECT_TRUE(actual_params->GetParameterStr(1, &copied_text));
- EXPECT_STREQ(text, copied_text.c_str());
-
- param_size = 1;
- std::wstring copied_text_p0, copied_text_p2;
-
- const wchar_t text2[] = L"AeFG";
- CrossCall(client, tag1, text2, null_text, text, &answer);
- actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer());
- EXPECT_EQ(3, actual_params->GetParamsCount());
- EXPECT_EQ(tag1, actual_params->GetTag());
- EXPECT_TRUE(actual_params->GetParameterStr(0, &copied_text_p0));
- EXPECT_STREQ(text2, copied_text_p0.c_str());
- EXPECT_TRUE(actual_params->GetParameterStr(2, &copied_text_p2));
- EXPECT_STREQ(text, copied_text_p2.c_str());
- type = INVALID_TYPE;
- param_addr = actual_params->GetRawParameter(1, &param_size, &type);
- EXPECT_TRUE(NULL != param_addr);
- EXPECT_EQ(0, param_size);
- EXPECT_EQ(WCHAR_TYPE, type);
-
- CloseChannelEvents(client_control);
- delete[] reinterpret_cast<char*>(client_control);
-}
-
-TEST(IPCTest, CrossCallIntPacking) {
- // Check handling for regular 32 bit integers used in Windows.
- size_t base_start = 0;
- IPCControl* client_control =
- MakeChannels(kIPCChannelSize, 4096 * 4, &base_start);
- client_control->server_alive = HANDLE(1);
- FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_READY);
-
- uint32 tag1 = 999;
- uint32 tag2 = 111;
- const wchar_t text[] = L"godzilla";
- CrossCallParamsEx* actual_params;
-
- char* mem = reinterpret_cast<char*>(client_control);
- SharedMemIPCClient client(mem);
-
- CrossCallReturn answer;
- DWORD dw = 0xE6578;
- CrossCall(client, tag2, dw, &answer);
- actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer());
- EXPECT_EQ(1, actual_params->GetParamsCount());
- EXPECT_EQ(tag2, actual_params->GetTag());
- ArgType type = INVALID_TYPE;
- uint32 param_size = 1;
- void* param_addr = actual_params->GetRawParameter(0, &param_size, &type);
- ASSERT_EQ(sizeof(dw), param_size);
- EXPECT_EQ(ULONG_TYPE, type);
- ASSERT_TRUE(NULL != param_addr);
- EXPECT_EQ(0, memcmp(&dw, param_addr, param_size));
-
- // Check handling for windows HANDLES.
- HANDLE h = HANDLE(0x70000500);
- CrossCall(client, tag1, text, h, &answer);
- actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer());
- EXPECT_EQ(2, actual_params->GetParamsCount());
- EXPECT_EQ(tag1, actual_params->GetTag());
- type = INVALID_TYPE;
- param_addr = actual_params->GetRawParameter(1, &param_size, &type);
- ASSERT_EQ(sizeof(h), param_size);
- EXPECT_EQ(VOIDPTR_TYPE, type);
- ASSERT_TRUE(NULL != param_addr);
- EXPECT_EQ(0, memcmp(&h, param_addr, param_size));
-
- // Check combination of 32 and 64 bits.
- CrossCall(client, tag2, h, dw, h, &answer);
- actual_params = reinterpret_cast<CrossCallParamsEx*>(client.GetBuffer());
- EXPECT_EQ(3, actual_params->GetParamsCount());
- EXPECT_EQ(tag2, actual_params->GetTag());
- type = INVALID_TYPE;
- param_addr = actual_params->GetRawParameter(0, &param_size, &type);
- ASSERT_EQ(sizeof(h), param_size);
- EXPECT_EQ(VOIDPTR_TYPE, type);
- ASSERT_TRUE(NULL != param_addr);
- EXPECT_EQ(0, memcmp(&h, param_addr, param_size));
- type = INVALID_TYPE;
- param_addr = actual_params->GetRawParameter(1, &param_size, &type);
- ASSERT_EQ(sizeof(dw), param_size);
- EXPECT_EQ(ULONG_TYPE, type);
- ASSERT_TRUE(NULL != param_addr);
- EXPECT_EQ(0, memcmp(&dw, param_addr, param_size));
- type = INVALID_TYPE;
- param_addr = actual_params->GetRawParameter(2, &param_size, &type);
- ASSERT_EQ(sizeof(h), param_size);
- EXPECT_EQ(VOIDPTR_TYPE, type);
- ASSERT_TRUE(NULL != param_addr);
- EXPECT_EQ(0, memcmp(&h, param_addr, param_size));
-
- CloseChannelEvents(client_control);
- delete[] reinterpret_cast<char*>(client_control);
-}
-
-TEST(IPCTest, CrossCallValidation) {
- // First a sanity test with a well formed parameter object.
- unsigned long value = 124816;
- const uint32 kTag = 33;
- const uint32 kBufferSize = 256;
- ActualCallParams<1, kBufferSize> params_1(kTag);
- params_1.CopyParamIn(0, &value, sizeof(value), false, ULONG_TYPE);
- void* buffer = const_cast<void*>(params_1.GetBuffer());
-
- uint32 out_size = 0;
- CrossCallParamsEx* ccp = 0;
- ccp = CrossCallParamsEx::CreateFromBuffer(buffer, params_1.GetSize(),
- &out_size);
- ASSERT_TRUE(NULL != ccp);
- EXPECT_TRUE(ccp->GetBuffer() != buffer);
- EXPECT_EQ(kTag, ccp->GetTag());
- EXPECT_EQ(1, ccp->GetParamsCount());
- delete[] (reinterpret_cast<char*>(ccp));
-
-#if defined(NDEBUG)
- // Test hat we handle integer overflow on the number of params
- // correctly. We use a test-only ctor for ActualCallParams that
- // allows to create malformed cross-call buffers.
- const int32 kPtrDiffSz = sizeof(ptrdiff_t);
- for (int32 ix = -1; ix != 3; ++ix) {
- uint32 fake_num_params = (kuint32max / kPtrDiffSz) + ix;
- ActualCallParams<1, kBufferSize> params_2(kTag, fake_num_params);
- params_2.CopyParamIn(0, &value, sizeof(value), false, ULONG_TYPE);
- buffer = const_cast<void*>(params_2.GetBuffer());
-
- EXPECT_TRUE(NULL != buffer);
- ccp = CrossCallParamsEx::CreateFromBuffer(buffer, params_1.GetSize(),
- &out_size);
- // If the buffer is malformed the return is NULL.
- EXPECT_TRUE(NULL == ccp);
- }
-#endif // defined(NDEBUG)
-
- ActualCallParams<1, kBufferSize> params_3(kTag, 1);
- params_3.CopyParamIn(0, &value, sizeof(value), false, ULONG_TYPE);
- buffer = const_cast<void*>(params_3.GetBuffer());
- EXPECT_TRUE(NULL != buffer);
-
- uint32 correct_size = params_3.OverrideSize(1);
- ccp = CrossCallParamsEx::CreateFromBuffer(buffer, kBufferSize, &out_size);
- EXPECT_TRUE(NULL == ccp);
-
- // The correct_size is 8 bytes aligned.
- params_3.OverrideSize(correct_size - 7);
- ccp = CrossCallParamsEx::CreateFromBuffer(buffer, kBufferSize, &out_size);
- EXPECT_TRUE(NULL == ccp);
-
- params_3.OverrideSize(correct_size);
- ccp = CrossCallParamsEx::CreateFromBuffer(buffer, kBufferSize, &out_size);
- EXPECT_TRUE(NULL != ccp);
-
- // Make sure that two parameters work as expected.
- ActualCallParams<2, kBufferSize> params_4(kTag, 2);
- params_4.CopyParamIn(0, &value, sizeof(value), false, ULONG_TYPE);
- params_4.CopyParamIn(1, buffer, sizeof(buffer), false, VOIDPTR_TYPE);
- buffer = const_cast<void*>(params_4.GetBuffer());
- EXPECT_TRUE(NULL != buffer);
-
- ccp = CrossCallParamsEx::CreateFromBuffer(buffer, kBufferSize, &out_size);
- EXPECT_TRUE(NULL != ccp);
-
-#if defined(_WIN64)
- correct_size = params_4.OverrideSize(1);
- params_4.OverrideSize(correct_size - 1);
- ccp = CrossCallParamsEx::CreateFromBuffer(buffer, kBufferSize, &out_size);
- EXPECT_TRUE(NULL == ccp);
-#endif
-}
-
-// This structure is passed to the mock server threads to simulate
-// the server side IPC so it has the required kernel objects.
-struct ServerEvents {
- HANDLE ping;
- HANDLE pong;
- volatile LONG* state;
- HANDLE mutex;
-};
-
-// This is the server thread that quicky answers an IPC and exits.
-DWORD WINAPI QuickResponseServer(PVOID param) {
- ServerEvents* events = reinterpret_cast<ServerEvents*>(param);
- DWORD wait_result = 0;
- wait_result = ::WaitForSingleObject(events->ping, INFINITE);
- ::InterlockedExchange(events->state, kAckChannel);
- ::SetEvent(events->pong);
- return wait_result;
-}
-
-class CrossCallParamsMock : public CrossCallParams {
- public:
- CrossCallParamsMock(uint32 tag, uint32 params_count)
- : CrossCallParams(tag, params_count) {
- }
- private:
- void* params[4];
-};
-
-void FakeOkAnswerInChannel(void* channel) {
- CrossCallReturn* answer = reinterpret_cast<CrossCallReturn*>(channel);
- answer->call_outcome = SBOX_ALL_OK;
-}
-
-// Create two threads that will quickly answer IPCs; the first one
-// using channel 1 (channel 0 is busy) and one using channel 0. No time-out
-// should occur.
-TEST(IPCTest, ClientFastServer) {
- const size_t channel_size = kIPCChannelSize;
- size_t base_start = 0;
- IPCControl* client_control =
- MakeChannels(channel_size, 4096 * 2, &base_start);
- FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_NOT_READY);
- client_control->server_alive = ::CreateMutex(NULL, FALSE, NULL);
-
- char* mem = reinterpret_cast<char*>(client_control);
- SharedMemIPCClient client(mem);
-
- ServerEvents events = {0};
- events.ping = client_control->channels[1].ping_event;
- events.pong = client_control->channels[1].pong_event;
- events.state = &client_control->channels[1].state;
-
- HANDLE t1 = ::CreateThread(NULL, 0, QuickResponseServer, &events, 0, NULL);
- ASSERT_TRUE(NULL != t1);
- ::CloseHandle(t1);
-
- void* buff0 = client.GetBuffer();
- EXPECT_TRUE(mem + client_control->channels[0].channel_base == buff0);
- EXPECT_EQ(kBusyChannel, client_control->channels[0].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[1].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[2].state);
-
- void* buff1 = client.GetBuffer();
- EXPECT_TRUE(mem + client_control->channels[1].channel_base == buff1);
- EXPECT_EQ(kBusyChannel, client_control->channels[0].state);
- EXPECT_EQ(kBusyChannel, client_control->channels[1].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[2].state);
-
- EXPECT_EQ(0, client_control->channels[1].ipc_tag);
-
- uint32 tag = 7654;
- CrossCallReturn answer;
- CrossCallParamsMock* params1 = new(buff1) CrossCallParamsMock(tag, 1);
- FakeOkAnswerInChannel(buff1);
-
- ResultCode result = client.DoCall(params1, &answer);
- if (SBOX_ERROR_CHANNEL_ERROR != result)
- client.FreeBuffer(buff1);
-
- EXPECT_TRUE(SBOX_ALL_OK == result);
- EXPECT_EQ(tag, client_control->channels[1].ipc_tag);
- EXPECT_EQ(kBusyChannel, client_control->channels[0].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[1].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[2].state);
-
- HANDLE t2 = ::CreateThread(NULL, 0, QuickResponseServer, &events, 0, NULL);
- ASSERT_TRUE(NULL != t2);
- ::CloseHandle(t2);
-
- client.FreeBuffer(buff0);
- events.ping = client_control->channels[0].ping_event;
- events.pong = client_control->channels[0].pong_event;
- events.state = &client_control->channels[0].state;
-
- tag = 4567;
- CrossCallParamsMock* params2 = new(buff0) CrossCallParamsMock(tag, 1);
- FakeOkAnswerInChannel(buff0);
-
- result = client.DoCall(params2, &answer);
- if (SBOX_ERROR_CHANNEL_ERROR != result)
- client.FreeBuffer(buff0);
-
- EXPECT_TRUE(SBOX_ALL_OK == result);
- EXPECT_EQ(tag, client_control->channels[0].ipc_tag);
- EXPECT_EQ(kFreeChannel, client_control->channels[0].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[1].state);
- EXPECT_EQ(kFreeChannel, client_control->channels[2].state);
-
- CloseChannelEvents(client_control);
- ::CloseHandle(client_control->server_alive);
-
- delete[] reinterpret_cast<char*>(client_control);
-}
-
-// This is the server thread that very slowly answers an IPC and exits. Note
-// that the pong event needs to be signaled twice.
-DWORD WINAPI SlowResponseServer(PVOID param) {
- ServerEvents* events = reinterpret_cast<ServerEvents*>(param);
- DWORD wait_result = 0;
- wait_result = ::WaitForSingleObject(events->ping, INFINITE);
- ::Sleep(kIPCWaitTimeOut1 + kIPCWaitTimeOut2 + 200);
- ::InterlockedExchange(events->state, kAckChannel);
- ::SetEvent(events->pong);
- return wait_result;
-}
-
-// This thread's job is to keep the mutex locked.
-DWORD WINAPI MainServerThread(PVOID param) {
- ServerEvents* events = reinterpret_cast<ServerEvents*>(param);
- DWORD wait_result = 0;
- wait_result = ::WaitForSingleObject(events->mutex, INFINITE);
- Sleep(kIPCWaitTimeOut1 * 20);
- return wait_result;
-}
-
-// Creates a server thread that answers the IPC so slow that is guaranteed to
-// trigger the time-out code path in the client. A second thread is created
-// to hold locked the server_alive mutex: this signals the client that the
-// server is not dead and it retries the wait.
-TEST(IPCTest, ClientSlowServer) {
- size_t base_start = 0;
- IPCControl* client_control =
- MakeChannels(kIPCChannelSize, 4096*2, &base_start);
- FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_NOT_READY);
- client_control->server_alive = ::CreateMutex(NULL, FALSE, NULL);
-
- char* mem = reinterpret_cast<char*>(client_control);
- SharedMemIPCClient client(mem);
-
- ServerEvents events = {0};
- events.ping = client_control->channels[0].ping_event;
- events.pong = client_control->channels[0].pong_event;
- events.state = &client_control->channels[0].state;
-
- HANDLE t1 = ::CreateThread(NULL, 0, SlowResponseServer, &events, 0, NULL);
- ASSERT_TRUE(NULL != t1);
- ::CloseHandle(t1);
-
- ServerEvents events2 = {0};
- events2.pong = events.pong;
- events2.mutex = client_control->server_alive;
-
- HANDLE t2 = ::CreateThread(NULL, 0, MainServerThread, &events2, 0, NULL);
- ASSERT_TRUE(NULL != t2);
- ::CloseHandle(t2);
-
- ::Sleep(1);
-
- void* buff0 = client.GetBuffer();
- uint32 tag = 4321;
- CrossCallReturn answer;
- CrossCallParamsMock* params1 = new(buff0) CrossCallParamsMock(tag, 1);
- FakeOkAnswerInChannel(buff0);
-
- ResultCode result = client.DoCall(params1, &answer);
- if (SBOX_ERROR_CHANNEL_ERROR != result)
- client.FreeBuffer(buff0);
-
- EXPECT_TRUE(SBOX_ALL_OK == result);
- EXPECT_EQ(tag, client_control->channels[0].ipc_tag);
- EXPECT_EQ(kFreeChannel, client_control->channels[0].state);
-
- CloseChannelEvents(client_control);
- ::CloseHandle(client_control->server_alive);
- delete[] reinterpret_cast<char*>(client_control);
-}
-
-// This test-only IPC dispatcher has two handlers with the same signature
-// but only CallOneHandler should be used.
-class UnitTestIPCDispatcher : public Dispatcher {
- public:
- enum {
- CALL_ONE_TAG = 78,
- CALL_TWO_TAG = 87
- };
-
- UnitTestIPCDispatcher();
- ~UnitTestIPCDispatcher() {};
-
- virtual bool SetupService(InterceptionManager* manager, int service) {
- return true;
- }
-
- private:
- bool CallOneHandler(IPCInfo* ipc, HANDLE p1, DWORD p2) {
- ipc->return_info.extended[0].handle = p1;
- ipc->return_info.extended[1].unsigned_int = p2;
- return true;
- }
-
- bool CallTwoHandler(IPCInfo* ipc, HANDLE p1, DWORD p2) {
- return true;
- }
-};
-
-UnitTestIPCDispatcher::UnitTestIPCDispatcher() {
- static const IPCCall call_one = {
- {CALL_ONE_TAG, VOIDPTR_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(
- &UnitTestIPCDispatcher::CallOneHandler)
- };
- static const IPCCall call_two = {
- {CALL_TWO_TAG, VOIDPTR_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(
- &UnitTestIPCDispatcher::CallTwoHandler)
- };
- ipc_calls_.push_back(call_one);
- ipc_calls_.push_back(call_two);
-}
-
-// This test does most of the shared memory IPC client-server roundtrip
-// and tests the packing, unpacking and call dispatching.
-TEST(IPCTest, SharedMemServerTests) {
- size_t base_start = 0;
- IPCControl* client_control =
- MakeChannels(kIPCChannelSize, 4096, &base_start);
- client_control->server_alive = HANDLE(1);
- FixChannels(client_control, base_start, kIPCChannelSize, FIX_PONG_READY);
-
- char* mem = reinterpret_cast<char*>(client_control);
- SharedMemIPCClient client(mem);
-
- CrossCallReturn answer;
- HANDLE bar = HANDLE(191919);
- DWORD foo = 6767676;
- CrossCall(client, UnitTestIPCDispatcher::CALL_ONE_TAG, bar, foo, &answer);
- void* buff = client.GetBuffer();
- ASSERT_TRUE(NULL != buff);
-
- UnitTestIPCDispatcher dispatcher;
- // Since we are directly calling InvokeCallback, most of this structure
- // can be set to NULL.
- sandbox::SharedMemIPCServer::ServerControl srv_control = {
- NULL, NULL, kIPCChannelSize, NULL,
- reinterpret_cast<char*>(client_control),
- NULL, &dispatcher, {0} };
-
- sandbox::CrossCallReturn call_return = {0};
- EXPECT_TRUE(SharedMemIPCServer::InvokeCallback(&srv_control, buff,
- &call_return));
- EXPECT_EQ(SBOX_ALL_OK, call_return.call_outcome);
- EXPECT_TRUE(bar == call_return.extended[0].handle);
- EXPECT_EQ(foo, call_return.extended[1].unsigned_int);
-
- CloseChannelEvents(client_control);
- delete[] reinterpret_cast<char*>(client_control);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/job.cc b/sandbox/win/src/job.cc
deleted file mode 100644
index 060ffa52..0000000
--- a/sandbox/win/src/job.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/job.h"
-
-#include "base/win/windows_version.h"
-#include "sandbox/win/src/restricted_token.h"
-
-namespace sandbox {
-
-Job::~Job() {
- if (job_handle_)
- ::CloseHandle(job_handle_);
-};
-
-DWORD Job::Init(JobLevel security_level, wchar_t *job_name,
- DWORD ui_exceptions) {
- if (job_handle_)
- return ERROR_ALREADY_INITIALIZED;
-
- job_handle_ = ::CreateJobObject(NULL, // No security attribute
- job_name);
- if (!job_handle_)
- return ::GetLastError();
-
- JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {0};
- JOBOBJECT_BASIC_UI_RESTRICTIONS jbur = {0};
-
- // Set the settings for the different security levels. Note: The higher levels
- // inherit from the lower levels.
- switch (security_level) {
- case JOB_LOCKDOWN: {
- jeli.BasicLimitInformation.LimitFlags |=
- JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION;
- }
- case JOB_RESTRICTED: {
- jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
- jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_READCLIPBOARD;
- jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
- jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_GLOBALATOMS;
- }
- case JOB_LIMITED_USER: {
- jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DISPLAYSETTINGS;
- jeli.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
- jeli.BasicLimitInformation.ActiveProcessLimit = 1;
- }
- case JOB_INTERACTIVE: {
- jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS;
- jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DESKTOP;
- jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS;
- }
- case JOB_UNPROTECTED: {
- // The JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE flag is not supported on
- // Windows 2000. We need a mechanism on Windows 2000 to ensure
- // that processes in the job are terminated when the job is closed
- if (base::win::GetVersion() == base::win::VERSION_PRE_XP)
- break;
-
- jeli.BasicLimitInformation.LimitFlags |=
- JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
- break;
- }
- default: {
- return ERROR_BAD_ARGUMENTS;
- }
- }
-
- if (FALSE == ::SetInformationJobObject(job_handle_,
- JobObjectExtendedLimitInformation,
- &jeli,
- sizeof(jeli))) {
- return ::GetLastError();
- }
-
- jbur.UIRestrictionsClass = jbur.UIRestrictionsClass & (~ui_exceptions);
- if (FALSE == ::SetInformationJobObject(job_handle_,
- JobObjectBasicUIRestrictions,
- &jbur,
- sizeof(jbur))) {
- return ::GetLastError();
- }
-
- return ERROR_SUCCESS;
-}
-
-DWORD Job::UserHandleGrantAccess(HANDLE handle) {
- if (!job_handle_)
- return ERROR_NO_DATA;
-
- if (!::UserHandleGrantAccess(handle,
- job_handle_,
- TRUE)) { // Access allowed.
- return ::GetLastError();
- }
-
- return ERROR_SUCCESS;
-}
-
-HANDLE Job::Detach() {
- HANDLE handle_temp = job_handle_;
- job_handle_ = NULL;
- return handle_temp;
-}
-
-DWORD Job::AssignProcessToJob(HANDLE process_handle) {
- if (!job_handle_)
- return ERROR_NO_DATA;
-
- if (FALSE == ::AssignProcessToJobObject(job_handle_, process_handle))
- return ::GetLastError();
-
- return ERROR_SUCCESS;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/job.h b/sandbox/win/src/job.h
deleted file mode 100644
index 487722f..0000000
--- a/sandbox/win/src/job.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_JOB_H_
-#define SANDBOX_SRC_JOB_H_
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/restricted_token_utils.h"
-
-namespace sandbox {
-
-// Handles the creation of job objects based on a security profile.
-// Sample usage:
-// Job job;
-// job.Init(JOB_LOCKDOWN, NULL); //no job name
-// job.AssignProcessToJob(process_handle);
-class Job {
- public:
- Job() : job_handle_(NULL) { }
-
- ~Job();
-
- // Initializes and creates the job object. The security of the job is based
- // on the security_level parameter.
- // job_name can be NULL if the job is unnamed.
- // If the chosen profile has too many ui restrictions, you can disable some
- // by specifying them in the ui_exceptions parameters.
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- DWORD Init(JobLevel security_level, wchar_t *job_name, DWORD ui_exceptions);
-
- // Assigns the process referenced by process_handle to the job.
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- DWORD AssignProcessToJob(HANDLE process_handle);
-
- // Grants access to "handle" to the job. All processes in the job can
- // subsequently recognize and use the handle.
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- DWORD UserHandleGrantAccess(HANDLE handle);
-
- // Revokes ownership to the job handle and returns it. The destructor of the
- // class won't close the handle when called.
- // If the object is not yet initialized, it returns 0.
- HANDLE Detach();
-
- private:
- // Handle to the job referenced by the object.
- HANDLE job_handle_;
-
- DISALLOW_COPY_AND_ASSIGN(Job);
-};
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_JOB_H_
diff --git a/sandbox/win/src/job_unittest.cc b/sandbox/win/src/job_unittest.cc
deleted file mode 100644
index 8d84b78..0000000
--- a/sandbox/win/src/job_unittest.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains unit tests for the job object.
-
-#include "base/win/scoped_process_information.h"
-#include "sandbox/win/src/job.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace sandbox {
-
-// Tests the creation and destruction of the job.
-TEST(JobTest, TestCreation) {
- // Scope the creation of Job.
- {
- // Create the job.
- Job job;
- ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_LOCKDOWN, L"my_test_job_name", 0));
-
- // check if the job exists.
- HANDLE job_handle = ::OpenJobObjectW(GENERIC_ALL, FALSE,
- L"my_test_job_name");
- ASSERT_TRUE(job_handle != NULL);
-
- if (job_handle)
- CloseHandle(job_handle);
- }
-
- // Check if the job is destroyed when the object goes out of scope.
- HANDLE job_handle = ::OpenJobObjectW(GENERIC_ALL, FALSE, L"my_test_job_name");
- ASSERT_TRUE(job_handle == NULL);
- ASSERT_EQ(ERROR_FILE_NOT_FOUND, ::GetLastError());
-}
-
-// Tests the method "Detach".
-TEST(JobTest, TestDetach) {
- HANDLE job_handle;
- // Scope the creation of Job.
- {
- // Create the job.
- Job job;
- ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_LOCKDOWN, L"my_test_job_name", 0));
-
- job_handle = job.Detach();
- ASSERT_TRUE(job_handle != NULL);
- }
-
- // Check to be sure that the job is still alive even after the object is gone
- // out of scope.
- HANDLE job_handle_dup = ::OpenJobObjectW(GENERIC_ALL, FALSE,
- L"my_test_job_name");
- ASSERT_TRUE(job_handle_dup != NULL);
-
- // Remove all references.
- if (job_handle_dup)
- ::CloseHandle(job_handle_dup);
-
- if (job_handle)
- ::CloseHandle(job_handle);
-
- // Check if the jbo is really dead.
- job_handle = ::OpenJobObjectW(GENERIC_ALL, FALSE, L"my_test_job_name");
- ASSERT_TRUE(job_handle == NULL);
- ASSERT_EQ(ERROR_FILE_NOT_FOUND, ::GetLastError());
-}
-
-// Tests the ui exceptions
-TEST(JobTest, TestExceptions) {
- HANDLE job_handle;
- // Scope the creation of Job.
- {
- // Create the job.
- Job job;
- ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_LOCKDOWN, L"my_test_job_name",
- JOB_OBJECT_UILIMIT_READCLIPBOARD));
-
- job_handle = job.Detach();
- ASSERT_TRUE(job_handle != NULL);
-
- JOBOBJECT_BASIC_UI_RESTRICTIONS jbur = {0};
- DWORD size = sizeof(jbur);
- BOOL result = ::QueryInformationJobObject(job_handle,
- JobObjectBasicUIRestrictions,
- &jbur, size, &size);
- ASSERT_TRUE(result);
-
- ASSERT_EQ(jbur.UIRestrictionsClass & JOB_OBJECT_UILIMIT_READCLIPBOARD, 0);
- ::CloseHandle(job_handle);
- }
-
- // Scope the creation of Job.
- {
- // Create the job.
- Job job;
- ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_LOCKDOWN, L"my_test_job_name", 0));
-
- job_handle = job.Detach();
- ASSERT_TRUE(job_handle != NULL);
-
- JOBOBJECT_BASIC_UI_RESTRICTIONS jbur = {0};
- DWORD size = sizeof(jbur);
- BOOL result = ::QueryInformationJobObject(job_handle,
- JobObjectBasicUIRestrictions,
- &jbur, size, &size);
- ASSERT_TRUE(result);
-
- ASSERT_EQ(jbur.UIRestrictionsClass & JOB_OBJECT_UILIMIT_READCLIPBOARD,
- JOB_OBJECT_UILIMIT_READCLIPBOARD);
- ::CloseHandle(job_handle);
- }
-}
-
-// Tests the error case when the job is initialized twice.
-TEST(JobTest, DoubleInit) {
- // Create the job.
- Job job;
- ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_LOCKDOWN, L"my_test_job_name", 0));
- ASSERT_EQ(ERROR_ALREADY_INITIALIZED, job.Init(JOB_LOCKDOWN, L"test", 0));
-}
-
-// Tests the error case when we use a method and the object is not yet
-// initialized.
-TEST(JobTest, NoInit) {
- Job job;
- ASSERT_EQ(ERROR_NO_DATA, job.UserHandleGrantAccess(NULL));
- ASSERT_EQ(ERROR_NO_DATA, job.AssignProcessToJob(NULL));
- ASSERT_TRUE(job.Detach() == NULL);
-}
-
-// Tests the initialization of the job with different security level.
-TEST(JobTest, SecurityLevel) {
- Job job1;
- ASSERT_EQ(ERROR_SUCCESS, job1.Init(JOB_LOCKDOWN, L"job1", 0));
-
- Job job2;
- ASSERT_EQ(ERROR_SUCCESS, job2.Init(JOB_RESTRICTED, L"job2", 0));
-
- Job job3;
- ASSERT_EQ(ERROR_SUCCESS, job3.Init(JOB_LIMITED_USER, L"job3", 0));
-
- Job job4;
- ASSERT_EQ(ERROR_SUCCESS, job4.Init(JOB_INTERACTIVE, L"job4", 0));
-
- Job job5;
- ASSERT_EQ(ERROR_SUCCESS, job5.Init(JOB_UNPROTECTED, L"job5", 0));
-
- Job job6;
- ASSERT_EQ(ERROR_BAD_ARGUMENTS, job6.Init(
- static_cast<JobLevel>(JOB_UNPROTECTED+1), L"job6", 0));
-}
-
-// Tests the method "AssignProcessToJob".
-TEST(JobTest, ProcessInJob) {
- // Create the job.
- Job job;
- ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_UNPROTECTED, L"job_test_process", 0));
-
- BOOL result = FALSE;
-
- wchar_t notepad[] = L"notepad";
- STARTUPINFO si = { sizeof(si) };
- base::win::ScopedProcessInformation pi;
- result = ::CreateProcess(NULL, notepad, NULL, NULL, FALSE, 0, NULL, NULL, &si,
- pi.Receive());
- ASSERT_TRUE(result);
- ASSERT_EQ(ERROR_SUCCESS, job.AssignProcessToJob(pi.process_handle()));
-
- // Get the job handle.
- HANDLE job_handle = job.Detach();
-
- // Check if the process is in the job.
- JOBOBJECT_BASIC_PROCESS_ID_LIST jbpidl = {0};
- DWORD size = sizeof(jbpidl);
- result = ::QueryInformationJobObject(job_handle,
- JobObjectBasicProcessIdList,
- &jbpidl, size, &size);
- EXPECT_TRUE(result);
-
- EXPECT_EQ(1, jbpidl.NumberOfAssignedProcesses);
- EXPECT_EQ(1, jbpidl.NumberOfProcessIdsInList);
- EXPECT_EQ(pi.process_id(), jbpidl.ProcessIdList[0]);
-
- EXPECT_TRUE(::TerminateProcess(pi.process_handle(), 0));
-
- EXPECT_TRUE(::CloseHandle(job_handle));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/named_pipe_dispatcher.cc b/sandbox/win/src/named_pipe_dispatcher.cc
deleted file mode 100644
index aae1096..0000000
--- a/sandbox/win/src/named_pipe_dispatcher.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/named_pipe_dispatcher.h"
-
-#include "base/basictypes.h"
-
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/interception.h"
-#include "sandbox/win/src/interceptors.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/named_pipe_interception.h"
-#include "sandbox/win/src/named_pipe_policy.h"
-#include "sandbox/win/src/policy_broker.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox.h"
-
-
-namespace sandbox {
-
-NamedPipeDispatcher::NamedPipeDispatcher(PolicyBase* policy_base)
- : policy_base_(policy_base) {
- static const IPCCall create_params = {
- {IPC_CREATENAMEDPIPEW_TAG, WCHAR_TYPE, ULONG_TYPE, ULONG_TYPE, ULONG_TYPE,
- ULONG_TYPE, ULONG_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(&NamedPipeDispatcher::CreateNamedPipe)
- };
-
- ipc_calls_.push_back(create_params);
-}
-
-bool NamedPipeDispatcher::SetupService(InterceptionManager* manager,
- int service) {
- if (IPC_CREATENAMEDPIPEW_TAG == service)
- return INTERCEPT_EAT(manager, L"kernel32.dll", CreateNamedPipeW,
- CREATE_NAMED_PIPE_ID, 36);
-
- return false;
-}
-
-bool NamedPipeDispatcher::CreateNamedPipe(
- IPCInfo* ipc, std::wstring* name, DWORD open_mode, DWORD pipe_mode,
- DWORD max_instances, DWORD out_buffer_size, DWORD in_buffer_size,
- DWORD default_timeout) {
- const wchar_t* pipe_name = name->c_str();
- CountedParameterSet<NameBased> params;
- params[NameBased::NAME] = ParamPickerMake(pipe_name);
-
- EvalResult eval = policy_base_->EvalPolicy(IPC_CREATENAMEDPIPEW_TAG,
- params.GetBase());
-
- HANDLE pipe;
- DWORD ret = NamedPipePolicy::CreateNamedPipeAction(eval, *ipc->client_info,
- *name, open_mode,
- pipe_mode, max_instances,
- out_buffer_size,
- in_buffer_size,
- default_timeout, &pipe);
-
- ipc->return_info.win32_result = ret;
- ipc->return_info.handle = pipe;
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/named_pipe_dispatcher.h b/sandbox/win/src/named_pipe_dispatcher.h
deleted file mode 100644
index 0d03b2e..0000000
--- a/sandbox/win/src/named_pipe_dispatcher.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_NAMED_PIPE_DISPATCHER_H__
-#define SANDBOX_SRC_NAMED_PIPE_DISPATCHER_H__
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/sandbox_policy_base.h"
-
-namespace sandbox {
-
-// This class handles named pipe related IPC calls.
-class NamedPipeDispatcher : public Dispatcher {
- public:
- explicit NamedPipeDispatcher(PolicyBase* policy_base);
- ~NamedPipeDispatcher() {}
-
- // Dispatcher interface.
- virtual bool SetupService(InterceptionManager* manager, int service);
-
- private:
- // Processes IPC requests coming from calls to CreateNamedPipeW() in the
- // target.
- bool CreateNamedPipe(IPCInfo* ipc, std::wstring* name, DWORD open_mode,
- DWORD pipe_mode, DWORD max_instances,
- DWORD out_buffer_size, DWORD in_buffer_size,
- DWORD default_timeout);
-
- PolicyBase* policy_base_;
- DISALLOW_COPY_AND_ASSIGN(NamedPipeDispatcher);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_NAMED_PIPE_DISPATCHER_H__
diff --git a/sandbox/win/src/named_pipe_interception.cc b/sandbox/win/src/named_pipe_interception.cc
deleted file mode 100644
index f437b1c..0000000
--- a/sandbox/win/src/named_pipe_interception.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/named_pipe_interception.h"
-
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/policy_target.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "sandbox/win/src/target_services.h"
-
-namespace sandbox {
-
-HANDLE WINAPI TargetCreateNamedPipeW(
- CreateNamedPipeWFunction orig_CreateNamedPipeW, LPCWSTR pipe_name,
- DWORD open_mode, DWORD pipe_mode, DWORD max_instance, DWORD out_buffer_size,
- DWORD in_buffer_size, DWORD default_timeout,
- LPSECURITY_ATTRIBUTES security_attributes) {
- HANDLE pipe = orig_CreateNamedPipeW(pipe_name, open_mode, pipe_mode,
- max_instance, out_buffer_size,
- in_buffer_size, default_timeout,
- security_attributes);
- if (INVALID_HANDLE_VALUE != pipe)
- return pipe;
-
- DWORD original_error = ::GetLastError();
-
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return INVALID_HANDLE_VALUE;
-
- // We don't support specific Security Attributes.
- if (security_attributes)
- return INVALID_HANDLE_VALUE;
-
- do {
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- CountedParameterSet<NameBased> params;
- params[NameBased::NAME] = ParamPickerMake(pipe_name);
-
- if (!QueryBroker(IPC_CREATENAMEDPIPEW_TAG, params.GetBase()))
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_CREATENAMEDPIPEW_TAG, pipe_name,
- open_mode, pipe_mode, max_instance,
- out_buffer_size, in_buffer_size,
- default_timeout, &answer);
- if (SBOX_ALL_OK != code)
- break;
-
- ::SetLastError(answer.win32_result);
-
- if (ERROR_SUCCESS != answer.win32_result)
- return INVALID_HANDLE_VALUE;
-
- return answer.handle;
- } while (false);
-
- ::SetLastError(original_error);
- return INVALID_HANDLE_VALUE;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/named_pipe_interception.h b/sandbox/win/src/named_pipe_interception.h
deleted file mode 100644
index fdbee19..0000000
--- a/sandbox/win/src/named_pipe_interception.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-#ifndef SANDBOX_SRC_NAMED_PIPE_INTERCEPTION_H__
-#define SANDBOX_SRC_NAMED_PIPE_INTERCEPTION_H__
-
-namespace sandbox {
-
-extern "C" {
-
-typedef HANDLE (WINAPI *CreateNamedPipeWFunction) (
- LPCWSTR lpName,
- DWORD dwOpenMode,
- DWORD dwPipeMode,
- DWORD nMaxInstances,
- DWORD nOutBufferSize,
- DWORD nInBufferSize,
- DWORD nDefaultTimeOut,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes);
-
-// Interception of CreateNamedPipeW in kernel32.dll
-SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateNamedPipeW(
- CreateNamedPipeWFunction orig_CreateNamedPipeW, LPCWSTR pipe_name,
- DWORD open_mode, DWORD pipe_mode, DWORD max_instance, DWORD out_buffer_size,
- DWORD in_buffer_size, DWORD default_timeout,
- LPSECURITY_ATTRIBUTES security_attributes);
-
-} // extern "C"
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_NAMED_PIPE_INTERCEPTION_H__
diff --git a/sandbox/win/src/named_pipe_policy.cc b/sandbox/win/src/named_pipe_policy.cc
deleted file mode 100644
index 470e823..0000000
--- a/sandbox/win/src/named_pipe_policy.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/named_pipe_policy.h"
-
-#include <string>
-
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_engine_opcodes.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-namespace {
-
-// Creates a named pipe and duplicates the handle to 'target_process'. The
-// remaining parameters are the same as CreateNamedPipeW().
-HANDLE CreateNamedPipeHelper(HANDLE target_process, LPCWSTR pipe_name,
- DWORD open_mode, DWORD pipe_mode,
- DWORD max_instances, DWORD out_buffer_size,
- DWORD in_buffer_size, DWORD default_timeout,
- LPSECURITY_ATTRIBUTES security_attributes) {
- HANDLE pipe = ::CreateNamedPipeW(pipe_name, open_mode, pipe_mode,
- max_instances, out_buffer_size,
- in_buffer_size, default_timeout,
- security_attributes);
- if (INVALID_HANDLE_VALUE == pipe)
- return pipe;
-
- HANDLE new_pipe;
- if (!::DuplicateHandle(::GetCurrentProcess(), pipe, target_process, &new_pipe,
- 0, FALSE, DUPLICATE_CLOSE_SOURCE |
- DUPLICATE_SAME_ACCESS)) {
- ::CloseHandle(pipe);
- return INVALID_HANDLE_VALUE;
- }
-
- return new_pipe;
-}
-
-} // namespace
-
-namespace sandbox {
-
-bool NamedPipePolicy::GenerateRules(const wchar_t* name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy) {
- if (TargetPolicy::NAMEDPIPES_ALLOW_ANY != semantics) {
- return false;
- }
- PolicyRule pipe(ASK_BROKER);
- if (!pipe.AddStringMatch(IF, NameBased::NAME, name, CASE_INSENSITIVE)) {
- return false;
- }
- if (!policy->AddRule(IPC_CREATENAMEDPIPEW_TAG, &pipe)) {
- return false;
- }
- return true;
-}
-
-DWORD NamedPipePolicy::CreateNamedPipeAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &name,
- DWORD open_mode, DWORD pipe_mode,
- DWORD max_instances,
- DWORD out_buffer_size,
- DWORD in_buffer_size,
- DWORD default_timeout,
- HANDLE* pipe) {
- // The only action supported is ASK_BROKER which means create the pipe.
- if (ASK_BROKER != eval_result) {
- return ERROR_ACCESS_DENIED;
- }
-
- *pipe = CreateNamedPipeHelper(client_info.process, name.c_str(),
- open_mode, pipe_mode, max_instances,
- out_buffer_size, in_buffer_size,
- default_timeout, NULL);
-
- if (INVALID_HANDLE_VALUE == *pipe)
- return ERROR_ACCESS_DENIED;
-
- return ERROR_SUCCESS;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/named_pipe_policy.h b/sandbox/win/src/named_pipe_policy.h
deleted file mode 100644
index 1ba07b8..0000000
--- a/sandbox/win/src/named_pipe_policy.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_NAMED_PIPE_POLICY_H__
-#define SANDBOX_SRC_NAMED_PIPE_POLICY_H__
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/policy_low_level.h"
-#include "sandbox/win/src/sandbox_policy.h"
-
-namespace sandbox {
-
-enum EvalResult;
-
-// This class centralizes most of the knowledge related to named pipe creation.
-class NamedPipePolicy {
- public:
- // Creates the required low-level policy rules to evaluate a high-level.
- // policy rule for named pipe creation
- // 'name' is the named pipe to be created
- // 'semantics' is the desired semantics.
- // 'policy' is the policy generator to which the rules are going to be added.
- static bool GenerateRules(const wchar_t* name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy);
-
- // Processes a 'CreateNamedPipeW()' request from the target.
- static DWORD CreateNamedPipeAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &name,
- DWORD open_mode, DWORD pipe_mode,
- DWORD max_instances,
- DWORD out_buffer_size,
- DWORD in_buffer_size,
- DWORD default_timeout, HANDLE* pipe);
-};
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_NAMED_PIPE_POLICY_H__
diff --git a/sandbox/win/src/named_pipe_policy_test.cc b/sandbox/win/src/named_pipe_policy_test.cc
deleted file mode 100644
index b89a191..0000000
--- a/sandbox/win/src/named_pipe_policy_test.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_policy.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/tests/common/controller.h"
-
-namespace sandbox {
-
-
-SBOX_TESTS_COMMAND int NamedPipe_Create(int argc, wchar_t **argv) {
- if (argc != 1) {
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
- }
- if ((NULL == argv) || (NULL == argv[0])) {
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
- }
-
- HANDLE pipe = ::CreateNamedPipeW(argv[0],
- PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
- PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1, 4096,
- 4096, 2000, NULL);
- if (INVALID_HANDLE_VALUE == pipe)
- return SBOX_TEST_DENIED;
-
- OVERLAPPED overlapped = {0};
- overlapped.hEvent = ::CreateEvent(NULL, TRUE, TRUE, NULL);
- BOOL result = ::ConnectNamedPipe(pipe, &overlapped);
-
- if (!result) {
- DWORD error = ::GetLastError();
- if (ERROR_PIPE_CONNECTED != error &&
- ERROR_IO_PENDING != error) {
- return SBOX_TEST_FAILED;
- }
- }
-
- if (!::CloseHandle(pipe))
- return SBOX_TEST_FAILED;
-
- ::CloseHandle(overlapped.hEvent);
- return SBOX_TEST_SUCCEEDED;
-}
-
-// Tests if we can create a pipe in the sandbox. On XP, the sandbox can create
-// a pipe without any help but it fails on Vista, this is why we do not test
-// the "denied" case.
-TEST(NamedPipePolicyTest, CreatePipe) {
- TestRunner runner;
- // TODO(nsylvain): This policy is wrong because "*" is a valid char in a
- // namedpipe name. Here we apply it like a wildcard. http://b/893603
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_NAMED_PIPES,
- TargetPolicy::NAMEDPIPES_ALLOW_ANY,
- L"\\\\.\\pipe\\test*"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED,
- runner.RunTest(L"NamedPipe_Create \\\\.\\pipe\\testbleh"));
-}
-
-// The same test as CreatePipe but this time using strict interceptions.
-TEST(NamedPipePolicyTest, CreatePipeStrictInterceptions) {
- TestRunner runner;
- runner.GetPolicy()->SetStrictInterceptions();
-
- // TODO(nsylvain): This policy is wrong because "*" is a valid char in a
- // namedpipe name. Here we apply it like a wildcard. http://b/893603
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_NAMED_PIPES,
- TargetPolicy::NAMEDPIPES_ALLOW_ANY,
- L"\\\\.\\pipe\\test*"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED,
- runner.RunTest(L"NamedPipe_Create \\\\.\\pipe\\testbleh"));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/nt_internals.h b/sandbox/win/src/nt_internals.h
deleted file mode 100644
index fe4fcd6..0000000
--- a/sandbox/win/src/nt_internals.h
+++ /dev/null
@@ -1,611 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file holds definitions related to the ntdll API.
-
-#ifndef SANDBOX_SRC_NT_INTERNALS_H__
-#define SANDBOX_SRC_NT_INTERNALS_H__
-
-#include <windows.h>
-
-typedef LONG NTSTATUS;
-#define NT_SUCCESS(st) (st >= 0)
-
-#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
-#define STATUS_BUFFER_OVERFLOW ((NTSTATUS)0x80000005L)
-#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
-#define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L)
-#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
-#ifndef STATUS_INVALID_PARAMETER
-// It is now defined in Windows 2008 SDK.
-#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000DL)
-#endif
-#define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS)0xC0000018L)
-#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
-#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
-#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
-#define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS)0xC000007AL)
-#define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xC000007BL)
-#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL)
-
-#define CURRENT_PROCESS ((HANDLE) -1)
-#define CURRENT_THREAD ((HANDLE) -2)
-#define NtCurrentProcess CURRENT_PROCESS
-
-typedef struct _UNICODE_STRING {
- USHORT Length;
- USHORT MaximumLength;
- PWSTR Buffer;
-} UNICODE_STRING;
-typedef UNICODE_STRING *PUNICODE_STRING;
-typedef const UNICODE_STRING *PCUNICODE_STRING;
-
-typedef struct _STRING {
- USHORT Length;
- USHORT MaximumLength;
- PCHAR Buffer;
-} STRING;
-typedef STRING *PSTRING;
-
-typedef STRING ANSI_STRING;
-typedef PSTRING PANSI_STRING;
-typedef CONST PSTRING PCANSI_STRING;
-
-typedef STRING OEM_STRING;
-typedef PSTRING POEM_STRING;
-typedef CONST STRING* PCOEM_STRING;
-
-#define OBJ_CASE_INSENSITIVE 0x00000040L
-
-typedef struct _OBJECT_ATTRIBUTES {
- ULONG Length;
- HANDLE RootDirectory;
- PUNICODE_STRING ObjectName;
- ULONG Attributes;
- PVOID SecurityDescriptor;
- PVOID SecurityQualityOfService;
-} OBJECT_ATTRIBUTES;
-typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
-
-#define InitializeObjectAttributes(p, n, a, r, s) { \
- (p)->Length = sizeof(OBJECT_ATTRIBUTES);\
- (p)->RootDirectory = r;\
- (p)->Attributes = a;\
- (p)->ObjectName = n;\
- (p)->SecurityDescriptor = s;\
- (p)->SecurityQualityOfService = NULL;\
-}
-
-typedef struct _IO_STATUS_BLOCK {
- union {
- NTSTATUS Status;
- PVOID Pointer;
- };
- ULONG_PTR Information;
-} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
-
-// -----------------------------------------------------------------------
-// File IO
-
-// Create disposition values.
-
-#define FILE_SUPERSEDE 0x00000000
-#define FILE_OPEN 0x00000001
-#define FILE_CREATE 0x00000002
-#define FILE_OPEN_IF 0x00000003
-#define FILE_OVERWRITE 0x00000004
-#define FILE_OVERWRITE_IF 0x00000005
-#define FILE_MAXIMUM_DISPOSITION 0x00000005
-
-// Create/open option flags.
-
-#define FILE_DIRECTORY_FILE 0x00000001
-#define FILE_WRITE_THROUGH 0x00000002
-#define FILE_SEQUENTIAL_ONLY 0x00000004
-#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
-
-#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
-#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
-#define FILE_NON_DIRECTORY_FILE 0x00000040
-#define FILE_CREATE_TREE_CONNECTION 0x00000080
-
-#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
-#define FILE_NO_EA_KNOWLEDGE 0x00000200
-#define FILE_OPEN_REMOTE_INSTANCE 0x00000400
-#define FILE_RANDOM_ACCESS 0x00000800
-
-#define FILE_DELETE_ON_CLOSE 0x00001000
-#define FILE_OPEN_BY_FILE_ID 0x00002000
-#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
-#define FILE_NO_COMPRESSION 0x00008000
-
-#define FILE_RESERVE_OPFILTER 0x00100000
-#define FILE_OPEN_REPARSE_POINT 0x00200000
-#define FILE_OPEN_NO_RECALL 0x00400000
-#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
-
-typedef NTSTATUS (WINAPI *NtCreateFileFunction)(
- OUT PHANDLE FileHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN PLARGE_INTEGER AllocationSize OPTIONAL,
- IN ULONG FileAttributes,
- IN ULONG ShareAccess,
- IN ULONG CreateDisposition,
- IN ULONG CreateOptions,
- IN PVOID EaBuffer OPTIONAL,
- IN ULONG EaLength);
-
-typedef NTSTATUS (WINAPI *NtOpenFileFunction)(
- OUT PHANDLE FileHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN ULONG ShareAccess,
- IN ULONG OpenOptions);
-
-typedef NTSTATUS (WINAPI *NtCloseFunction)(
- IN HANDLE Handle);
-
-typedef enum _FILE_INFORMATION_CLASS {
- FileRenameInformation = 10
-} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
-
-typedef struct _FILE_RENAME_INFORMATION {
- BOOLEAN ReplaceIfExists;
- HANDLE RootDirectory;
- ULONG FileNameLength;
- WCHAR FileName[1];
-} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
-
-typedef NTSTATUS (WINAPI *NtSetInformationFileFunction)(
- IN HANDLE FileHandle,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN PVOID FileInformation,
- IN ULONG Length,
- IN FILE_INFORMATION_CLASS FileInformationClass);
-
-typedef struct FILE_BASIC_INFORMATION {
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- ULONG FileAttributes;
-} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
-
-typedef NTSTATUS (WINAPI *NtQueryAttributesFileFunction)(
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- OUT PFILE_BASIC_INFORMATION FileAttributes);
-
-typedef struct _FILE_NETWORK_OPEN_INFORMATION {
- LARGE_INTEGER CreationTime;
- LARGE_INTEGER LastAccessTime;
- LARGE_INTEGER LastWriteTime;
- LARGE_INTEGER ChangeTime;
- LARGE_INTEGER AllocationSize;
- LARGE_INTEGER EndOfFile;
- ULONG FileAttributes;
-} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
-
-typedef NTSTATUS (WINAPI *NtQueryFullAttributesFileFunction)(
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- OUT PFILE_NETWORK_OPEN_INFORMATION FileAttributes);
-
-// -----------------------------------------------------------------------
-// Sections
-
-typedef NTSTATUS (WINAPI *NtCreateSectionFunction)(
- OUT PHANDLE SectionHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
- IN PLARGE_INTEGER MaximumSize OPTIONAL,
- IN ULONG SectionPageProtection,
- IN ULONG AllocationAttributes,
- IN HANDLE FileHandle OPTIONAL);
-
-typedef ULONG SECTION_INHERIT;
-#define ViewShare 1
-#define ViewUnmap 2
-
-typedef NTSTATUS (WINAPI *NtMapViewOfSectionFunction)(
- IN HANDLE SectionHandle,
- IN HANDLE ProcessHandle,
- IN OUT PVOID *BaseAddress,
- IN ULONG_PTR ZeroBits,
- IN SIZE_T CommitSize,
- IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
- IN OUT PSIZE_T ViewSize,
- IN SECTION_INHERIT InheritDisposition,
- IN ULONG AllocationType,
- IN ULONG Win32Protect);
-
-typedef NTSTATUS (WINAPI *NtUnmapViewOfSectionFunction)(
- IN HANDLE ProcessHandle,
- IN PVOID BaseAddress);
-
-typedef enum _SECTION_INFORMATION_CLASS {
- SectionBasicInformation = 0,
- SectionImageInformation
-} SECTION_INFORMATION_CLASS;
-
-typedef struct _SECTION_BASIC_INFORMATION {
- PVOID BaseAddress;
- ULONG Attributes;
- LARGE_INTEGER Size;
-} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;
-
-typedef NTSTATUS (WINAPI *NtQuerySectionFunction)(
- IN HANDLE SectionHandle,
- IN SECTION_INFORMATION_CLASS SectionInformationClass,
- OUT PVOID SectionInformation,
- IN SIZE_T SectionInformationLength,
- OUT PSIZE_T ReturnLength OPTIONAL);
-
-// -----------------------------------------------------------------------
-// Process and Thread
-
-typedef struct _CLIENT_ID {
- PVOID UniqueProcess;
- PVOID UniqueThread;
-} CLIENT_ID, *PCLIENT_ID;
-
-typedef NTSTATUS (WINAPI *NtOpenThreadFunction) (
- OUT PHANDLE ThreadHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN PCLIENT_ID ClientId);
-
-typedef NTSTATUS (WINAPI *NtOpenProcessFunction) (
- OUT PHANDLE ProcessHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN PCLIENT_ID ClientId);
-
-typedef enum _NT_THREAD_INFORMATION_CLASS {
- ThreadBasicInformation,
- ThreadTimes,
- ThreadPriority,
- ThreadBasePriority,
- ThreadAffinityMask,
- ThreadImpersonationToken,
- ThreadDescriptorTableEntry,
- ThreadEnableAlignmentFaultFixup,
- ThreadEventPair,
- ThreadQuerySetWin32StartAddress,
- ThreadZeroTlsCell,
- ThreadPerformanceCount,
- ThreadAmILastThread,
- ThreadIdealProcessor,
- ThreadPriorityBoost,
- ThreadSetTlsArrayAddress,
- ThreadIsIoPending,
- ThreadHideFromDebugger
-} NT_THREAD_INFORMATION_CLASS, *PNT_THREAD_INFORMATION_CLASS;
-
-typedef NTSTATUS (WINAPI *NtSetInformationThreadFunction) (
- IN HANDLE ThreadHandle,
- IN NT_THREAD_INFORMATION_CLASS ThreadInformationClass,
- IN PVOID ThreadInformation,
- IN ULONG ThreadInformationLength);
-
-// Partial definition only:
-typedef enum _PROCESSINFOCLASS {
- ProcessBasicInformation = 0
-} PROCESSINFOCLASS;
-
-typedef PVOID PPEB;
-typedef PVOID KPRIORITY;
-
-typedef struct _PROCESS_BASIC_INFORMATION {
- NTSTATUS ExitStatus;
- PPEB PebBaseAddress;
- KAFFINITY AffinityMask;
- KPRIORITY BasePriority;
- ULONG UniqueProcessId;
- ULONG InheritedFromUniqueProcessId;
-} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
-
-typedef NTSTATUS (WINAPI *NtQueryInformationProcessFunction)(
- IN HANDLE ProcessHandle,
- IN PROCESSINFOCLASS ProcessInformationClass,
- OUT PVOID ProcessInformation,
- IN ULONG ProcessInformationLength,
- OUT PULONG ReturnLength OPTIONAL);
-
-typedef NTSTATUS (WINAPI *NtOpenThreadTokenFunction) (
- IN HANDLE ThreadHandle,
- IN ACCESS_MASK DesiredAccess,
- IN BOOLEAN OpenAsSelf,
- OUT PHANDLE TokenHandle);
-
-typedef NTSTATUS (WINAPI *NtOpenThreadTokenExFunction) (
- IN HANDLE ThreadHandle,
- IN ACCESS_MASK DesiredAccess,
- IN BOOLEAN OpenAsSelf,
- IN ULONG HandleAttributes,
- OUT PHANDLE TokenHandle);
-
-typedef NTSTATUS (WINAPI *NtOpenProcessTokenFunction) (
- IN HANDLE ProcessHandle,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE TokenHandle);
-
-typedef NTSTATUS (WINAPI *NtOpenProcessTokenExFunction) (
- IN HANDLE ProcessHandle,
- IN ACCESS_MASK DesiredAccess,
- IN ULONG HandleAttributes,
- OUT PHANDLE TokenHandle);
-
-typedef NTSTATUS (WINAPI * RtlCreateUserThreadFunction)(
- IN HANDLE Process,
- IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
- IN BOOLEAN CreateSuspended,
- IN ULONG ZeroBits,
- IN SIZE_T MaximumStackSize,
- IN SIZE_T CommittedStackSize,
- IN LPTHREAD_START_ROUTINE StartAddress,
- IN PVOID Parameter,
- OUT PHANDLE Thread,
- OUT PCLIENT_ID ClientId);
-
-// -----------------------------------------------------------------------
-// Registry
-
-typedef NTSTATUS (WINAPI *NtCreateKeyFunction)(
- OUT PHANDLE KeyHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN ULONG TitleIndex,
- IN PUNICODE_STRING Class OPTIONAL,
- IN ULONG CreateOptions,
- OUT PULONG Disposition OPTIONAL);
-
-typedef NTSTATUS (WINAPI *NtOpenKeyFunction)(
- OUT PHANDLE KeyHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes);
-
-typedef NTSTATUS (WINAPI *NtOpenKeyExFunction)(
- OUT PHANDLE KeyHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN DWORD open_options);
-
-typedef NTSTATUS (WINAPI *NtDeleteKeyFunction)(
- IN HANDLE KeyHandle);
-
-// -----------------------------------------------------------------------
-// Memory
-
-// Don't really need this structure right now.
-typedef PVOID PRTL_HEAP_PARAMETERS;
-
-typedef PVOID (WINAPI *RtlCreateHeapFunction)(
- IN ULONG Flags,
- IN PVOID HeapBase OPTIONAL,
- IN SIZE_T ReserveSize OPTIONAL,
- IN SIZE_T CommitSize OPTIONAL,
- IN PVOID Lock OPTIONAL,
- IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL);
-
-typedef PVOID (WINAPI *RtlDestroyHeapFunction)(
- IN PVOID HeapHandle);
-
-typedef PVOID (WINAPI *RtlAllocateHeapFunction)(
- IN PVOID HeapHandle,
- IN ULONG Flags,
- IN SIZE_T Size);
-
-typedef BOOLEAN (WINAPI *RtlFreeHeapFunction)(
- IN PVOID HeapHandle,
- IN ULONG Flags,
- IN PVOID HeapBase);
-
-typedef NTSTATUS (WINAPI *NtAllocateVirtualMemoryFunction) (
- IN HANDLE ProcessHandle,
- IN OUT PVOID *BaseAddress,
- IN ULONG_PTR ZeroBits,
- IN OUT PSIZE_T RegionSize,
- IN ULONG AllocationType,
- IN ULONG Protect);
-
-typedef NTSTATUS (WINAPI *NtFreeVirtualMemoryFunction) (
- IN HANDLE ProcessHandle,
- IN OUT PVOID *BaseAddress,
- IN OUT PSIZE_T RegionSize,
- IN ULONG FreeType);
-
-typedef enum _MEMORY_INFORMATION_CLASS {
- MemoryBasicInformation = 0,
- MemoryWorkingSetList,
- MemorySectionName,
- MemoryBasicVlmInformation
-} MEMORY_INFORMATION_CLASS;
-
-typedef struct _MEMORY_SECTION_NAME { // Information Class 2
- UNICODE_STRING SectionFileName;
-} MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;
-
-typedef NTSTATUS (WINAPI *NtQueryVirtualMemoryFunction)(
- IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
- OUT PVOID MemoryInformation,
- IN ULONG MemoryInformationLength,
- OUT PULONG ReturnLength OPTIONAL);
-
-typedef NTSTATUS (WINAPI *NtProtectVirtualMemoryFunction)(
- IN HANDLE ProcessHandle,
- IN OUT PVOID* BaseAddress,
- IN OUT PSIZE_T ProtectSize,
- IN ULONG NewProtect,
- OUT PULONG OldProtect);
-
-// -----------------------------------------------------------------------
-// Objects
-
-typedef enum _OBJECT_INFORMATION_CLASS {
- ObjectBasicInformation,
- ObjectNameInformation,
- ObjectTypeInformation,
- ObjectAllInformation,
- ObjectDataInformation
-} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
-
-typedef struct _OBJDIR_INFORMATION {
- UNICODE_STRING ObjectName;
- UNICODE_STRING ObjectTypeName;
- BYTE Data[1];
-} OBJDIR_INFORMATION;
-
-typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION {
- ULONG Attributes;
- ACCESS_MASK GrantedAccess;
- ULONG HandleCount;
- ULONG PointerCount;
- ULONG Reserved[10]; // reserved for internal use
-} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION;
-
-typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION {
- UNICODE_STRING TypeName;
- ULONG Reserved[22]; // reserved for internal use
-} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;
-
-typedef enum _POOL_TYPE {
- NonPagedPool,
- PagedPool,
- NonPagedPoolMustSucceed,
- ReservedType,
- NonPagedPoolCacheAligned,
- PagedPoolCacheAligned,
- NonPagedPoolCacheAlignedMustS
-} POOL_TYPE;
-
-typedef struct _OBJECT_BASIC_INFORMATION {
- ULONG Attributes;
- ACCESS_MASK GrantedAccess;
- ULONG HandleCount;
- ULONG PointerCount;
- ULONG PagedPoolUsage;
- ULONG NonPagedPoolUsage;
- ULONG Reserved[3];
- ULONG NameInformationLength;
- ULONG TypeInformationLength;
- ULONG SecurityDescriptorLength;
- LARGE_INTEGER CreateTime;
-} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
-
-typedef struct _OBJECT_TYPE_INFORMATION {
- UNICODE_STRING Name;
- ULONG TotalNumberOfObjects;
- ULONG TotalNumberOfHandles;
- ULONG TotalPagedPoolUsage;
- ULONG TotalNonPagedPoolUsage;
- ULONG TotalNamePoolUsage;
- ULONG TotalHandleTableUsage;
- ULONG HighWaterNumberOfObjects;
- ULONG HighWaterNumberOfHandles;
- ULONG HighWaterPagedPoolUsage;
- ULONG HighWaterNonPagedPoolUsage;
- ULONG HighWaterNamePoolUsage;
- ULONG HighWaterHandleTableUsage;
- ULONG InvalidAttributes;
- GENERIC_MAPPING GenericMapping;
- ULONG ValidAccess;
- BOOLEAN SecurityRequired;
- BOOLEAN MaintainHandleCount;
- USHORT MaintainTypeList;
- POOL_TYPE PoolType;
- ULONG PagedPoolUsage;
- ULONG NonPagedPoolUsage;
-} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
-
-typedef enum _SYSTEM_INFORMATION_CLASS {
- SystemHandleInformation = 16
-} SYSTEM_INFORMATION_CLASS;
-
-typedef struct _SYSTEM_HANDLE_INFORMATION {
- USHORT ProcessId;
- USHORT CreatorBackTraceIndex;
- UCHAR ObjectTypeNumber;
- UCHAR Flags;
- USHORT Handle;
- PVOID Object;
- ACCESS_MASK GrantedAccess;
-} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
-
-typedef struct _SYSTEM_HANDLE_INFORMATION_EX {
- ULONG NumberOfHandles;
- SYSTEM_HANDLE_INFORMATION Information[1];
-} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
-
-typedef struct _OBJECT_NAME_INFORMATION {
- UNICODE_STRING ObjectName;
-} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
-
-typedef NTSTATUS (WINAPI *NtQueryObjectFunction)(
- IN HANDLE Handle,
- IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
- OUT PVOID ObjectInformation OPTIONAL,
- IN ULONG ObjectInformationLength,
- OUT PULONG ReturnLength OPTIONAL);
-
-typedef NTSTATUS (WINAPI *NtDuplicateObjectFunction)(
- IN HANDLE SourceProcess,
- IN HANDLE SourceHandle,
- IN HANDLE TargetProcess,
- OUT PHANDLE TargetHandle,
- IN ACCESS_MASK DesiredAccess,
- IN ULONG Attributes,
- IN ULONG Options);
-
-typedef NTSTATUS (WINAPI *NtSignalAndWaitForSingleObjectFunction)(
- IN HANDLE HandleToSignal,
- IN HANDLE HandleToWait,
- IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Timeout OPTIONAL);
-
-typedef NTSTATUS (WINAPI *NtQuerySystemInformation)(
- IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
- OUT PVOID SystemInformation,
- IN ULONG SystemInformationLength,
- OUT PULONG ReturnLength);
-
-typedef NTSTATUS (WINAPI *NtQueryObject)(
- IN HANDLE Handle,
- IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
- OUT PVOID ObjectInformation,
- IN ULONG ObjectInformationLength,
- OUT PULONG ReturnLength);
-
-// -----------------------------------------------------------------------
-// Strings
-
-typedef int (__cdecl *_strnicmpFunction)(
- IN const char* _Str1,
- IN const char* _Str2,
- IN size_t _MaxCount);
-
-typedef size_t (__cdecl *strlenFunction)(
- IN const char * _Str);
-
-typedef size_t (__cdecl *wcslenFunction)(
- IN const wchar_t* _Str);
-
-typedef NTSTATUS (WINAPI *RtlAnsiStringToUnicodeStringFunction)(
- IN OUT PUNICODE_STRING DestinationString,
- IN PANSI_STRING SourceString,
- IN BOOLEAN AllocateDestinationString);
-
-typedef LONG (WINAPI *RtlCompareUnicodeStringFunction)(
- IN PCUNICODE_STRING String1,
- IN PCUNICODE_STRING String2,
- IN BOOLEAN CaseInSensitive);
-
-typedef VOID (WINAPI *RtlInitUnicodeStringFunction) (
- IN OUT PUNICODE_STRING DestinationString,
- IN PCWSTR SourceString);
-
-#endif // SANDBOX_SRC_NT_INTERNALS_H__
diff --git a/sandbox/win/src/policy_broker.cc b/sandbox/win/src/policy_broker.cc
deleted file mode 100644
index 210eb47..0000000
--- a/sandbox/win/src/policy_broker.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <map>
-
-#include "sandbox/win/src/policy_broker.h"
-
-#include "base/logging.h"
-#include "base/win/pe_image.h"
-#include "base/win/windows_version.h"
-#include "sandbox/win/src/interception.h"
-#include "sandbox/win/src/interceptors.h"
-#include "sandbox/win/src/policy_target.h"
-#include "sandbox/win/src/process_thread_interception.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_nt_types.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/sandbox_utils.h"
-#include "sandbox/win/src/target_process.h"
-
-// This code executes on the broker side, as a callback from the policy on the
-// target side (the child).
-
-namespace sandbox {
-
-// This is the list of all imported symbols from ntdll.dll.
-SANDBOX_INTERCEPT NtExports g_nt;
-
-#define INIT_GLOBAL_NT(member) \
- g_nt.member = reinterpret_cast<Nt##member##Function>( \
- ntdll_image.GetProcAddress("Nt" #member)); \
- if (NULL == g_nt.member) \
- return false
-
-#define INIT_GLOBAL_RTL(member) \
- g_nt.member = reinterpret_cast<member##Function>( \
- ntdll_image.GetProcAddress(#member)); \
- if (NULL == g_nt.member) \
- return false
-
-bool SetupNtdllImports(TargetProcess *child) {
- HMODULE ntdll = ::GetModuleHandle(kNtdllName);
- base::win::PEImage ntdll_image(ntdll);
-
- // Bypass purify's interception.
- wchar_t* loader_get = reinterpret_cast<wchar_t*>(
- ntdll_image.GetProcAddress("LdrGetDllHandle"));
- if (loader_get) {
- GetModuleHandleHelper(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
- GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- loader_get, &ntdll);
- }
-
- INIT_GLOBAL_NT(AllocateVirtualMemory);
- INIT_GLOBAL_NT(Close);
- INIT_GLOBAL_NT(DuplicateObject);
- INIT_GLOBAL_NT(FreeVirtualMemory);
- INIT_GLOBAL_NT(MapViewOfSection);
- INIT_GLOBAL_NT(ProtectVirtualMemory);
- INIT_GLOBAL_NT(QueryInformationProcess);
- INIT_GLOBAL_NT(QueryObject);
- INIT_GLOBAL_NT(QuerySection);
- INIT_GLOBAL_NT(QueryVirtualMemory);
- INIT_GLOBAL_NT(UnmapViewOfSection);
-
- INIT_GLOBAL_RTL(RtlAllocateHeap);
- INIT_GLOBAL_RTL(RtlAnsiStringToUnicodeString);
- INIT_GLOBAL_RTL(RtlCompareUnicodeString);
- INIT_GLOBAL_RTL(RtlCreateHeap);
- INIT_GLOBAL_RTL(RtlCreateUserThread);
- INIT_GLOBAL_RTL(RtlDestroyHeap);
- INIT_GLOBAL_RTL(RtlFreeHeap);
- INIT_GLOBAL_RTL(_strnicmp);
- INIT_GLOBAL_RTL(strlen);
- INIT_GLOBAL_RTL(wcslen);
-
-#ifndef NDEBUG
- // Verify that the structure is fully initialized.
- for (size_t i = 0; i < sizeof(g_nt)/sizeof(void*); i++)
- DCHECK(reinterpret_cast<char**>(&g_nt)[i]);
-#endif
- ResultCode ret = child->TransferVariable("g_nt", &g_nt, sizeof(g_nt));
-
- return SBOX_ALL_OK == ret ? true : false;
-}
-
-#undef INIT_GLOBAL_NT
-#undef INIT_GLOBAL_RTL
-
-bool SetupBasicInterceptions(InterceptionManager* manager) {
- // Interceptions provided by process_thread_policy, without actual policy.
- if (!INTERCEPT_NT(manager, NtOpenThread, OPEN_TREAD_ID, 20) ||
- !INTERCEPT_NT(manager, NtOpenProcess, OPEN_PROCESS_ID, 20) ||
- !INTERCEPT_NT(manager, NtOpenProcessToken, OPEN_PROCESS_TOKEN_ID, 16))
- return false;
-
- // Interceptions with neither policy nor IPC.
- if (!INTERCEPT_NT(manager, NtSetInformationThread, SET_INFORMATION_THREAD_ID,
- 20) ||
- !INTERCEPT_NT(manager, NtOpenThreadToken, OPEN_THREAD_TOKEN_ID, 20))
- return false;
-
- if (base::win::GetVersion() >= base::win::VERSION_XP) {
- // Bug 27218: We don't have dispatch for some x64 syscalls.
- // This one is also provided by process_thread_policy.
- if (!INTERCEPT_NT(manager, NtOpenProcessTokenEx, OPEN_PROCESS_TOKEN_EX_ID,
- 20))
- return false;
-
- return INTERCEPT_NT(manager, NtOpenThreadTokenEx, OPEN_THREAD_TOKEN_EX_ID,
- 24);
- }
-
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/policy_broker.h b/sandbox/win/src/policy_broker.h
deleted file mode 100644
index 1c5cc26..0000000
--- a/sandbox/win/src/policy_broker.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_POLICY_BROKER_H_
-#define SANDBOX_SRC_POLICY_BROKER_H_
-
-#include "sandbox/win/src/interception.h"
-
-namespace sandbox {
-
-class TargetProcess;
-
-// Sets up interceptions not controlled by explicit policies.
-bool SetupBasicInterceptions(InterceptionManager* manager);
-
-// Sets up imports from NTDLL for the given target process so the interceptions
-// can work.
-bool SetupNtdllImports(TargetProcess *child);
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_POLICY_BROKER_H_
diff --git a/sandbox/win/src/policy_engine_opcodes.cc b/sandbox/win/src/policy_engine_opcodes.cc
deleted file mode 100644
index e8a39ed..0000000
--- a/sandbox/win/src/policy_engine_opcodes.cc
+++ /dev/null
@@ -1,454 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/policy_engine_opcodes.h"
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/sandbox_nt_types.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-namespace {
-const unsigned short kMaxUniStrSize = 0xfffc;
-
-bool InitStringUnicode(const wchar_t* source, size_t length,
- UNICODE_STRING* ustring) {
- ustring->Buffer = const_cast<wchar_t*>(source);
- ustring->Length = static_cast<USHORT>(length) * sizeof(wchar_t);
- if (length > kMaxUniStrSize) {
- return false;
- }
- ustring->MaximumLength = (NULL != source) ?
- ustring->Length + sizeof(wchar_t) : 0;
- return true;
-}
-
-} // namespace
-
-namespace sandbox {
-
-SANDBOX_INTERCEPT NtExports g_nt;
-
-// Note: The opcodes are implemented as functions (as opposed to classes derived
-// from PolicyOpcode) because you should not add more member variables to the
-// PolicyOpcode class since it would cause object slicing on the target. So to
-// enforce that (instead of just trusting the developer) the opcodes became
-// just functions.
-//
-// In the code that follows I have keep the evaluation function and the factory
-// function together to stress the close relationship between both. For example,
-// only the factory method and the evaluation function know the stored argument
-// order and meaning.
-
-template <int>
-EvalResult OpcodeEval(PolicyOpcode* opcode, const ParameterSet* pp,
- MatchContext* match);
-
-//////////////////////////////////////////////////////////////////////////////
-// Opcode OpAlwaysFalse:
-// Does not require input parameter.
-
-PolicyOpcode* OpcodeFactory::MakeOpAlwaysFalse(uint32 options) {
- return MakeBase(OP_ALWAYS_FALSE, options, -1);
-}
-
-template <>
-EvalResult OpcodeEval<OP_ALWAYS_FALSE>(PolicyOpcode* opcode,
- const ParameterSet* param,
- MatchContext* context) {
- UNREFERENCED_PARAMETER(opcode);
- UNREFERENCED_PARAMETER(param);
- UNREFERENCED_PARAMETER(context);
- return EVAL_FALSE;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Opcode OpAlwaysTrue:
-// Does not require input parameter.
-
-PolicyOpcode* OpcodeFactory::MakeOpAlwaysTrue(uint32 options) {
- return MakeBase(OP_ALWAYS_TRUE, options, -1);
-}
-
-template <>
-EvalResult OpcodeEval<OP_ALWAYS_TRUE>(PolicyOpcode* opcode,
- const ParameterSet* param,
- MatchContext* context) {
- UNREFERENCED_PARAMETER(opcode);
- UNREFERENCED_PARAMETER(param);
- UNREFERENCED_PARAMETER(context);
- return EVAL_TRUE;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Opcode OpAction:
-// Does not require input parameter.
-// Argument 0 contains the actual action to return.
-
-PolicyOpcode* OpcodeFactory::MakeOpAction(EvalResult action,
- uint32 options) {
- PolicyOpcode* opcode = MakeBase(OP_ACTION, options, 0);
- if (NULL == opcode) return NULL;
- opcode->SetArgument(0, action);
- return opcode;
-}
-
-template <>
-EvalResult OpcodeEval<OP_ACTION>(PolicyOpcode* opcode,
- const ParameterSet* param,
- MatchContext* context) {
- UNREFERENCED_PARAMETER(param);
- UNREFERENCED_PARAMETER(context);
- int action = 0;
- opcode->GetArgument(0, &action);
- return static_cast<EvalResult>(action);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Opcode OpNumberMatch:
-// Requires a unsigned long or void* in selected_param
-// Argument 0 is the stored number to match.
-// Argument 1 is the C++ type of the 0th argument.
-
-PolicyOpcode* OpcodeFactory::MakeOpNumberMatch(int16 selected_param,
- unsigned long match,
- uint32 options) {
- PolicyOpcode* opcode = MakeBase(OP_NUMBER_MATCH, options, selected_param);
- if (NULL == opcode) return NULL;
- opcode->SetArgument(0, match);
- opcode->SetArgument(1, ULONG_TYPE);
- return opcode;
-}
-
-PolicyOpcode* OpcodeFactory::MakeOpVoidPtrMatch(int16 selected_param,
- const void* match,
- uint32 options) {
- PolicyOpcode* opcode = MakeBase(OP_NUMBER_MATCH, options, selected_param);
- if (NULL == opcode) return NULL;
- opcode->SetArgument(0, match);
- opcode->SetArgument(1, VOIDPTR_TYPE);
- return opcode;
-}
-
-template <>
-EvalResult OpcodeEval<OP_NUMBER_MATCH>(PolicyOpcode* opcode,
- const ParameterSet* param,
- MatchContext* context) {
- UNREFERENCED_PARAMETER(context);
- unsigned long value_ulong = 0;
- if (param->Get(&value_ulong)) {
- unsigned long match_ulong = 0;
- opcode->GetArgument(0, &match_ulong);
- return (match_ulong != value_ulong)? EVAL_FALSE : EVAL_TRUE;
- } else {
- const void* value_ptr = NULL;
- if (param->Get(&value_ptr)) {
- const void* match_ptr = NULL;
- opcode->GetArgument(0, &match_ptr);
- return (match_ptr != value_ptr)? EVAL_FALSE : EVAL_TRUE;
- }
- }
- return EVAL_ERROR;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Opcode OpUlongMatchRange
-// Requires a unsigned long in selected_param.
-// Argument 0 is the stored lower bound to match.
-// Argument 1 is the stored upper bound to match.
-
-PolicyOpcode* OpcodeFactory::MakeOpUlongMatchRange(int16 selected_param,
- unsigned long lower_bound,
- unsigned long upper_bound,
- uint32 options) {
- if (lower_bound > upper_bound) {
- return false;
- }
- PolicyOpcode* opcode = MakeBase(OP_ULONG_MATCH_RANGE, options,
- selected_param);
- if (NULL == opcode) return NULL;
- opcode->SetArgument(0, lower_bound);
- opcode->SetArgument(1, upper_bound);
- return opcode;
-}
-
-template <>
-EvalResult OpcodeEval<OP_ULONG_MATCH_RANGE>(PolicyOpcode* opcode,
- const ParameterSet* param,
- MatchContext* context) {
- UNREFERENCED_PARAMETER(context);
- unsigned long value = 0;
- if (!param->Get(&value)) return EVAL_ERROR;
-
- unsigned long lower_bound = 0;
- unsigned long upper_bound = 0;
- opcode->GetArgument(0, &lower_bound);
- opcode->GetArgument(1, &upper_bound);
- return((lower_bound <= value) && (upper_bound >= value))?
- EVAL_TRUE : EVAL_FALSE;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Opcode OpUlongAndMatch:
-// Requires a unsigned long in selected_param.
-// Argument 0 is the stored number to match.
-
-PolicyOpcode* OpcodeFactory::MakeOpUlongAndMatch(int16 selected_param,
- unsigned long match,
- uint32 options) {
- PolicyOpcode* opcode = MakeBase(OP_ULONG_AND_MATCH, options, selected_param);
- if (NULL == opcode) return NULL;
- opcode->SetArgument(0, match);
- return opcode;
-}
-
-template <>
-EvalResult OpcodeEval<OP_ULONG_AND_MATCH>(PolicyOpcode* opcode,
- const ParameterSet* param,
- MatchContext* context) {
- UNREFERENCED_PARAMETER(context);
- unsigned long value = 0;
- if (!param->Get(&value)) return EVAL_ERROR;
-
- unsigned long number = 0;
- opcode->GetArgument(0, &number);
- return (number & value)? EVAL_TRUE : EVAL_FALSE;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Opcode OpWStringMatch:
-// Requires a wchar_t* in selected_param.
-// Argument 0 is the byte displacement of the stored string.
-// Argument 1 is the lenght in chars of the stored string.
-// Argument 2 is the offset to apply on the input string. It has special values.
-// as noted in the header file.
-// Argument 3 is the string matching options.
-
-PolicyOpcode* OpcodeFactory::MakeOpWStringMatch(int16 selected_param,
- const wchar_t* match_str,
- int start_position,
- StringMatchOptions match_opts,
- uint32 options) {
- if (NULL == match_str) {
- return NULL;
- }
- if ('\0' == match_str[0]) {
- return NULL;
- }
-
- int lenght = lstrlenW(match_str);
-
- PolicyOpcode* opcode = MakeBase(OP_WSTRING_MATCH, options, selected_param);
- if (NULL == opcode) {
- return NULL;
- }
- ptrdiff_t delta_str = AllocRelative(opcode, match_str, wcslen(match_str)+1);
- if (0 == delta_str) {
- return NULL;
- }
- opcode->SetArgument(0, delta_str);
- opcode->SetArgument(1, lenght);
- opcode->SetArgument(2, start_position);
- opcode->SetArgument(3, match_opts);
- return opcode;
-}
-
-template<>
-EvalResult OpcodeEval<OP_WSTRING_MATCH>(PolicyOpcode* opcode,
- const ParameterSet* param,
- MatchContext* context) {
- if (NULL == context) {
- return EVAL_ERROR;
- }
- const wchar_t* source_str = NULL;
- if (!param->Get(&source_str)) return EVAL_ERROR;
-
- int start_position = 0;
- int match_len = 0;
- unsigned int match_opts = 0;
- opcode->GetArgument(1, &match_len);
- opcode->GetArgument(2, &start_position);
- opcode->GetArgument(3, &match_opts);
-
- const wchar_t* match_str = opcode->GetRelativeString(0);
- // Advance the source string to the last successfully evaluated position
- // according to the match context.
- source_str = &source_str[context->position];
- int source_len = static_cast<int>(g_nt.wcslen(source_str));
-
- if (0 == source_len) {
- // If we reached the end of the source string there is nothing we can
- // match against.
- return EVAL_FALSE;
- }
- if (match_len > source_len) {
- // There can't be a positive match when the target string is bigger than
- // the source string
- return EVAL_FALSE;
- }
-
- BOOL case_sensitive = (match_opts & CASE_INSENSITIVE) ? TRUE : FALSE;
-
- // We have three cases, depending on the value of start_pos:
- // Case 1. We skip N characters and compare once.
- // Case 2: We skip to the end and compare once.
- // Case 3: We match the first substring (if we find any).
- if (start_position >= 0) {
- if (kSeekToEnd == start_position) {
- start_position = source_len - match_len;
- } else if (match_opts & EXACT_LENGHT) {
- // A sub-case of case 3 is when the EXACT_LENGHT flag is on
- // the match needs to be not just substring but full match.
- if ((match_len + start_position) != source_len) {
- return EVAL_FALSE;
- }
- }
-
- // Advance start_pos characters. Warning! this does not consider
- // utf16 encodings (surrogate pairs) or other Unicode 'features'.
- source_str += start_position;
-
- // Since we skipped, lets reevaluate just the lengths again.
- if ((match_len + start_position) > source_len) {
- return EVAL_FALSE;
- }
-
- UNICODE_STRING match_ustr;
- InitStringUnicode(match_str, match_len, &match_ustr);
- UNICODE_STRING source_ustr;
- InitStringUnicode(source_str, match_len, &source_ustr);
-
- if (0 == g_nt.RtlCompareUnicodeString(&match_ustr, &source_ustr,
- case_sensitive)) {
- // Match! update the match context.
- context->position += start_position + match_len;
- return EVAL_TRUE;
- } else {
- return EVAL_FALSE;
- }
- } else if (start_position < 0) {
- UNICODE_STRING match_ustr;
- InitStringUnicode(match_str, match_len, &match_ustr);
- UNICODE_STRING source_ustr;
- InitStringUnicode(source_str, match_len, &source_ustr);
-
- do {
- if (0 == g_nt.RtlCompareUnicodeString(&match_ustr, &source_ustr,
- case_sensitive)) {
- // Match! update the match context.
- context->position += (source_ustr.Buffer - source_str) + match_len;
- return EVAL_TRUE;
- }
- ++source_ustr.Buffer;
- --source_len;
- } while (source_len >= match_len);
- }
- return EVAL_FALSE;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// OpcodeMaker (other member functions).
-
-PolicyOpcode* OpcodeFactory::MakeBase(OpcodeID opcode_id,
- uint32 options,
- int16 selected_param) {
- if (memory_size() < sizeof(PolicyOpcode)) {
- return NULL;
- }
-
- // Create opcode using placement-new on the buffer memory.
- PolicyOpcode* opcode = new(memory_top_) PolicyOpcode();
-
- // Fill in the standard fields, that every opcode has.
- memory_top_ += sizeof(PolicyOpcode);
- opcode->opcode_id_ = opcode_id;
- opcode->options_ = static_cast<int16>(options);
- opcode->parameter_ = selected_param;
- return opcode;
-}
-
-ptrdiff_t OpcodeFactory::AllocRelative(void* start, const wchar_t* str,
- size_t lenght) {
- size_t bytes = lenght * sizeof(wchar_t);
- if (memory_size() < bytes) {
- return 0;
- }
- memory_bottom_ -= bytes;
- if (reinterpret_cast<UINT_PTR>(memory_bottom_) & 1) {
- // TODO(cpu) replace this for something better.
- ::DebugBreak();
- }
- memcpy(memory_bottom_, str, bytes);
- ptrdiff_t delta = memory_bottom_ - reinterpret_cast<char*>(start);
- return delta;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Opcode evaluation dispatchers.
-
-// This function is the one and only entry for evaluating any opcode. It is
-// in charge of applying any relevant opcode options and calling EvaluateInner
-// were the actual dispatch-by-id is made. It would seem at first glance that
-// the dispatch should be done by virtual function (vtable) calls but you have
-// to remember that the opcodes are made in the broker process and copied as
-// raw memory to the target process.
-
-EvalResult PolicyOpcode::Evaluate(const ParameterSet* call_params,
- size_t param_count, MatchContext* match) {
- if (NULL == call_params) {
- return EVAL_ERROR;
- }
- const ParameterSet* selected_param = NULL;
- if (parameter_ >= 0) {
- if (static_cast<size_t>(parameter_) >= param_count) {
- return EVAL_ERROR;
- }
- selected_param = &call_params[parameter_];
- }
- EvalResult result = EvaluateHelper(selected_param, match);
-
- // Apply the general options regardless of the particular type of opcode.
- if (kPolNone == options_) {
- return result;
- }
-
- if (options_ & kPolNegateEval) {
- if (EVAL_TRUE == result) {
- result = EVAL_FALSE;
- } else if (EVAL_FALSE == result) {
- result = EVAL_TRUE;
- } else if (EVAL_ERROR != result) {
- result = EVAL_ERROR;
- }
- }
- if (NULL != match) {
- if (options_ & kPolClearContext) {
- match->Clear();
- }
- if (options_ & kPolUseOREval) {
- match->options = kPolUseOREval;
- }
- }
- return result;
-}
-
-#define OPCODE_EVAL(op, x, y, z) case op: return OpcodeEval<op>(x, y, z)
-
-EvalResult PolicyOpcode::EvaluateHelper(const ParameterSet* parameters,
- MatchContext* match) {
- switch (opcode_id_) {
- OPCODE_EVAL(OP_ALWAYS_FALSE, this, parameters, match);
- OPCODE_EVAL(OP_ALWAYS_TRUE, this, parameters, match);
- OPCODE_EVAL(OP_NUMBER_MATCH, this, parameters, match);
- OPCODE_EVAL(OP_ULONG_MATCH_RANGE, this, parameters, match);
- OPCODE_EVAL(OP_WSTRING_MATCH, this, parameters, match);
- OPCODE_EVAL(OP_ULONG_AND_MATCH, this, parameters, match);
- OPCODE_EVAL(OP_ACTION, this, parameters, match);
- default:
- return EVAL_ERROR;
- }
-}
-
-#undef OPCODE_EVAL
-
-} // namespace sandbox
diff --git a/sandbox/win/src/policy_engine_opcodes.h b/sandbox/win/src/policy_engine_opcodes.h
deleted file mode 100644
index f74ce31..0000000
--- a/sandbox/win/src/policy_engine_opcodes.h
+++ /dev/null
@@ -1,380 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_POLICY_ENGINE_OPCODES_H__
-#define SANDBOX_SRC_POLICY_ENGINE_OPCODES_H__
-
-#include "sandbox/win/src/policy_engine_params.h"
-#include "base/basictypes.h"
-
-// The low-level policy is implemented using the concept of policy 'opcodes'.
-// An opcode is a structure that contains enough information to perform one
-// comparison against one single input parameter. For example, an opcode can
-// encode just one of the following comparison:
-//
-// - Is input parameter 3 not equal to NULL?
-// - Does input parameter 2 start with L"c:\\"?
-// - Is input parameter 5, bit 3 is equal 1?
-//
-// Each opcode is in fact equivalent to a function invocation where all
-// the parameters are known by the opcode except one. So say you have a
-// function of this form:
-// bool fn(a, b, c, d) with 4 arguments
-//
-// Then an opcode is:
-// op(fn, b, c, d)
-// Which stores the function to call and its 3 last arguments
-//
-// Then and opcode evaluation is:
-// op.eval(a) ------------------------> fn(a,b,c,d)
-// internally calls
-//
-// The idea is that complex policy rules can be split into streams of
-// opcodes which are evaluated in sequence. The evaluation is done in
-// groups of opcodes that have N comparison opcodes plus 1 action opcode:
-//
-// [comparison 1][comparison 2]...[comparison N][action][comparison 1]...
-// ----- evaluation order----------->
-//
-// Each opcode group encodes one high-level policy rule. The rule applies
-// only if all the conditions on the group evaluate to true. The action
-// opcode contains the policy outcome for that particular rule.
-//
-// Note that this header contains the main building blocks of low-level policy
-// but not the low level policy class.
-namespace sandbox {
-
-// These are the possible policy outcomes. Note that some of them might
-// not apply and can be removed. Also note that The following values only
-// specify what to do, not how to do it and it is acceptable given specific
-// cases to ignore the policy outcome.
-enum EvalResult {
- // Comparison opcode values:
- EVAL_TRUE, // Opcode condition evaluated true.
- EVAL_FALSE, // Opcode condition evaluated false.
- EVAL_ERROR, // Opcode condition generated an error while evaluating.
- // Action opcode values:
- ASK_BROKER, // The target must generate an IPC to the broker. On the broker
- // side, this means grant access to the resource.
- DENY_ACCESS, // No access granted to the resource.
- GIVE_READONLY, // Give readonly access to the resource.
- GIVE_ALLACCESS, // Give full access to the resource.
- GIVE_CACHED, // IPC is not required. Target can return a cached handle.
- GIVE_FIRST, // TODO(cpu)
- SIGNAL_ALARM, // Unusual activity. Generate an alarm.
- FAKE_SUCCESS, // Do not call original function. Just return 'success'.
- FAKE_ACCESS_DENIED, // Do not call original function. Just return 'denied'
- // and do not do IPC.
- TERMINATE_PROCESS, // Destroy target process. Do IPC as well.
-};
-
-// The following are the implemented opcodes.
-enum OpcodeID {
- OP_ALWAYS_FALSE, // Evaluates to false (EVAL_FALSE).
- OP_ALWAYS_TRUE, // Evaluates to true (EVAL_TRUE).
- OP_NUMBER_MATCH, // Match a 32-bit integer as n == a.
- OP_ULONG_MATCH_RANGE, // Match an ulong integer as a <= n <= b.
- OP_ULONG_AND_MATCH, // Match using bitwise AND; as in: n & a != 0.
- OP_WSTRING_MATCH, // Match a string for equality.
- OP_ACTION // Evaluates to an action opcode.
-};
-
-// Options that apply to every opcode. They are specified when creating
-// each opcode using OpcodeFactory::MakeOpXXXXX() family of functions
-// Do nothing special.
-const uint32 kPolNone = 0;
-
-// Convert EVAL_TRUE into EVAL_FALSE and vice-versa. This allows to express
-// negated conditions such as if ( a && !b).
-const uint32 kPolNegateEval = 1;
-
-// Zero the MatchContext context structure. This happens after the opcode
-// is evaluated.
-const uint32 kPolClearContext = 2;
-
-// Use OR when evaluating this set of opcodes. The policy evaluator by default
-// uses AND when evaluating. Very helpful when
-// used with kPolNegateEval. For example if you have a condition best expressed
-// as if(! (a && b && c)), the use of this flags allows it to be expressed as
-// if ((!a) || (!b) || (!c)).
-const uint32 kPolUseOREval = 4;
-
-// Keeps the evaluation state between opcode evaluations. This is used
-// for string matching where the next opcode needs to continue matching
-// from the last character position from the current opcode. The match
-// context is preserved across opcode evaluation unless an opcode specifies
-// as an option kPolClearContext.
-struct MatchContext {
- size_t position;
- uint32 options;
-
- MatchContext() {
- Clear();
- }
-
- void Clear() {
- position = 0;
- options = 0;
- }
-};
-
-// Models a policy opcode; that is a condition evaluation were all the
-// arguments but one are stored in objects of this class. Use OpcodeFactory
-// to create objects of this type.
-// This class is just an implementation artifact and not exposed to the
-// API clients or visible in the intercepted service. Internally, an
-// opcode is just:
-// - An integer that identifies the actual opcode.
-// - An index to indicate which one is the input argument
-// - An array of arguments.
-// While an OO hierarchy of objects would have been a natural choice, the fact
-// that 1) this code can execute before the CRT is loaded, presents serious
-// problems in terms of guarantees about the actual state of the vtables and
-// 2) because the opcode objects are generated in the broker process, we need to
-// use plain objects. To preserve some minimal type safety templates are used
-// when possible.
-class PolicyOpcode {
- friend class OpcodeFactory;
- public:
- // Evaluates the opcode. For a typical comparison opcode the return value
- // is EVAL_TRUE or EVAL_FALSE. If there was an error in the evaluation the
- // the return is EVAL_ERROR. If the opcode is an action opcode then the
- // return can take other values such as ASK_BROKER.
- // parameters: An array of all input parameters. This argument is normally
- // created by the macros POLPARAMS_BEGIN() POLPARAMS_END.
- // count: The number of parameters passed as first argument.
- // match: The match context that is persisted across the opcode evaluation
- // sequence.
- EvalResult Evaluate(const ParameterSet* parameters, size_t count,
- MatchContext* match);
-
- // Retrieves a stored argument by index. Valid index values are
- // from 0 to < kArgumentCount.
- template <typename T>
- void GetArgument(size_t index, T* argument) const {
- COMPILE_ASSERT(sizeof(T) <= sizeof(arguments_[0]), invalid_size);
- *argument = *reinterpret_cast<const T*>(&arguments_[index].mem);
- }
-
- // Sets a stored argument by index. Valid index values are
- // from 0 to < kArgumentCount.
- template <typename T>
- void SetArgument(size_t index, const T& argument) {
- COMPILE_ASSERT(sizeof(T) <= sizeof(arguments_[0]), invalid_size);
- *reinterpret_cast<T*>(&arguments_[index].mem) = argument;
- }
-
- // Retrieves the actual address of an string argument. When using
- // GetArgument() to retrieve an index that contains a string, the returned
- // value is just an offset to the actual string.
- // index: the stored string index. Valid values are from 0
- // to < kArgumentCount.
- const wchar_t* GetRelativeString(size_t index) const {
- ptrdiff_t str_delta = 0;
- GetArgument(index, &str_delta);
- const char* delta = reinterpret_cast<const char*>(this) + str_delta;
- return reinterpret_cast<const wchar_t*>(delta);
- }
-
- // Returns true if this opcode is an action opcode without actually
- // evaluating it. Used to do a quick scan forward to the next opcode group.
- bool IsAction() const {
- return (OP_ACTION == opcode_id_);
- };
-
- // Returns the opcode type.
- OpcodeID GetID() const {
- return opcode_id_;
- }
-
- // Returns the stored options such as kPolNegateEval and others.
- uint32 GetOptions() const {
- return options_;
- }
-
- // Sets the stored options such as kPolNegateEval.
- void SetOptions(int16 options) {
- options_ = options;
- }
-
- private:
-
- static const size_t kArgumentCount = 4; // The number of supported argument.
-
- struct OpcodeArgument {
- UINT_PTR mem;
- };
-
- // Better define placement new in the class instead of relying on the
- // global definition which seems to be fubared.
- void* operator new(size_t, void* location) {
- return location;
- }
-
- // Helper function to evaluate the opcode. The parameters have the same
- // meaning that in Evaluate().
- EvalResult EvaluateHelper(const ParameterSet* parameters,
- MatchContext* match);
- OpcodeID opcode_id_;
- int16 parameter_;
- int16 options_;
- OpcodeArgument arguments_[PolicyOpcode::kArgumentCount];
-};
-
-enum StringMatchOptions {
- CASE_SENSITIVE = 0, // Pay or Not attention to the case as defined by
- CASE_INSENSITIVE = 1, // RtlCompareUnicodeString windows API.
- EXACT_LENGHT = 2 // Don't do substring match. Do full string match.
-};
-
-// Opcodes that do string comparisons take a parameter that is the starting
-// position to perform the comparison so we can do substring matching. There
-// are two special values:
-//
-// Start from the current position and compare strings advancing forward until
-// a match is found if any. Similar to CRT strstr().
-const int kSeekForward = -1;
-// Perform a match with the end of the string. It only does a single comparison.
-const int kSeekToEnd = 0xfffff;
-
-
-// A PolicyBuffer is a variable size structure that contains all the opcodes
-// that are to be created or evaluated in sequence.
-struct PolicyBuffer {
- size_t opcode_count;
- PolicyOpcode opcodes[1];
-};
-
-// Helper class to create any opcode sequence. This class is normally invoked
-// only by the high level policy module or when you need to handcraft a special
-// policy.
-// The factory works by creating the opcodes using a chunk of memory given
-// in the constructor. The opcodes themselves are allocated from the beginning
-// (top) of the memory, while any string that an opcode needs is allocated from
-// the end (bottom) of the memory.
-//
-// In essence:
-//
-// low address ---> [opcode 1]
-// [opcode 2]
-// [opcode 3]
-// | | <--- memory_top_
-// | free |
-// | |
-// | | <--- memory_bottom_
-// [string 1]
-// high address --> [string 2]
-//
-// Note that this class does not keep track of the number of opcodes made and
-// it is designed to be a building block for low-level policy.
-//
-// Note that any of the MakeOpXXXXX member functions below can return NULL on
-// failure. When that happens opcode sequence creation must be aborted.
-class OpcodeFactory {
- public:
- // memory: base pointer to a chunk of memory where the opcodes are created.
- // memory_size: the size in bytes of the memory chunk.
- OpcodeFactory(char* memory, size_t memory_size)
- : memory_top_(memory) {
- memory_bottom_ = &memory_top_[memory_size];
- }
-
- // policy: contains the raw memory where the opcodes are created.
- // memory_size: contains the actual size of the policy argument.
- OpcodeFactory(PolicyBuffer* policy, size_t memory_size) {
- memory_top_ = reinterpret_cast<char*>(&policy->opcodes[0]);
- memory_bottom_ = &memory_top_[memory_size];
- }
-
- // Creates an OpAlwaysFalse opcode.
- PolicyOpcode* MakeOpAlwaysFalse(uint32 options);
-
- // Creates an OpAlwaysFalse opcode.
- PolicyOpcode* MakeOpAlwaysTrue(uint32 options);
-
- // Creates an OpAction opcode.
- // action: The action to return when Evaluate() is called.
- PolicyOpcode* MakeOpAction(EvalResult action, uint32 options);
-
- // Creates an OpNumberMatch opcode.
- // selected_param: index of the input argument. It must be a ulong or the
- // evaluation result will generate a EVAL_ERROR.
- // match: the number to compare against the selected_param.
- PolicyOpcode* MakeOpNumberMatch(int16 selected_param, unsigned long match,
- uint32 options);
-
- // Creates an OpNumberMatch opcode (void pointers are cast to numbers).
- // selected_param: index of the input argument. It must be an void* or the
- // evaluation result will generate a EVAL_ERROR.
- // match: the pointer numeric value to compare against selected_param.
- PolicyOpcode* MakeOpVoidPtrMatch(int16 selected_param, const void* match,
- uint32 options);
-
- // Creates an OpUlongMatchRange opcode using the memory passed in the ctor.
- // selected_param: index of the input argument. It must be a ulong or the
- // evaluation result will generate a EVAL_ERROR.
- // lower_bound, upper_bound: the range to compare against selected_param.
- PolicyOpcode* MakeOpUlongMatchRange(int16 selected_param,
- unsigned long lower_bound,
- unsigned long upper_bound,
- uint32 options);
-
- // Creates an OpWStringMatch opcode using the raw memory passed in the ctor.
- // selected_param: index of the input argument. It must be a wide string
- // pointer or the evaluation result will generate a EVAL_ERROR.
- // match_str: string to compare against selected_param.
- // start_position: when its value is from 0 to < 0x7fff it indicates an
- // offset from the selected_param string where to perform the comparison. If
- // the value is SeekForward then a substring search is performed. If the
- // value is SeekToEnd the comparison is performed against the last part of
- // the selected_param string.
- // Note that the range in the position (0 to 0x7fff) is dictated by the
- // current implementation.
- // match_opts: Indicates additional matching flags. Currently CaseInsensitive
- // is supported.
- PolicyOpcode* MakeOpWStringMatch(int16 selected_param,
- const wchar_t* match_str,
- int start_position,
- StringMatchOptions match_opts,
- uint32 options);
-
- // Creates an OpUlongAndMatch opcode using the raw memory passed in the ctor.
- // selected_param: index of the input argument. It must be ulong or the
- // evaluation result will generate a EVAL_ERROR.
- // match: the value to bitwise AND against selected_param.
- PolicyOpcode* MakeOpUlongAndMatch(int16 selected_param,
- unsigned long match,
- uint32 options);
-
- private:
- // Constructs the common part of every opcode. selected_param is the index
- // of the input param to use when evaluating the opcode. Pass -1 in
- // selected_param to indicate that no input parameter is required.
- PolicyOpcode* MakeBase(OpcodeID opcode_id, uint32 options,
- int16 selected_param);
-
- // Allocates (and copies) a string (of size length) inside the buffer and
- // returns the displacement with respect to start.
- ptrdiff_t AllocRelative(void* start, const wchar_t* str, size_t lenght);
-
- // Returns the available memory to make opcodes.
- size_t memory_size() const {
- return memory_bottom_ - memory_top_;
- }
-
- // Points to the lowest currently available address of the memory
- // used to make the opcodes. This pointer increments as opcodes are made.
- char* memory_top_;
-
- // Points to the highest currently available address of the memory
- // used to make the opcodes. This pointer decrements as opcode strings are
- // allocated.
- char* memory_bottom_;
-
- DISALLOW_COPY_AND_ASSIGN(OpcodeFactory);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_POLICY_ENGINE_OPCODES_H__
diff --git a/sandbox/win/src/policy_engine_params.h b/sandbox/win/src/policy_engine_params.h
deleted file mode 100644
index a1566f3..0000000
--- a/sandbox/win/src/policy_engine_params.h
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__
-#define SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/internal_types.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-
-// This header defines the classes that allow the low level policy to select
-// the input parameters. In order to better make sense of this header is
-// recommended that you check policy_engine_opcodes.h first.
-
-namespace sandbox {
-
-// Models the set of interesting parameters of an intercepted system call
-// normally you don't create objects of this class directly, instead you
-// use the POLPARAMS_XXX macros.
-// For example, if an intercepted function has the following signature:
-//
-// NTSTATUS NtOpenFileFunction (PHANDLE FileHandle,
-// ACCESS_MASK DesiredAccess,
-// POBJECT_ATTRIBUTES ObjectAttributes,
-// PIO_STATUS_BLOCK IoStatusBlock,
-// ULONG ShareAccess,
-// ULONG OpenOptions);
-//
-// You could say that the following parameters are of interest to policy:
-//
-// POLPARAMS_BEGIN(open_params)
-// POLPARAM(DESIRED_ACCESS)
-// POLPARAM(OBJECT_NAME)
-// POLPARAM(SECURITY_DESCRIPTOR)
-// POLPARAM(IO_STATUS)
-// POLPARAM(OPEN_OPTIONS)
-// POLPARAMS_END;
-//
-// and the actual code will use this for defining the parameters:
-//
-// CountedParameterSet<open_params> p;
-// p[open_params::DESIRED_ACCESS] = ParamPickerMake(DesiredAccess);
-// p[open_params::OBJECT_NAME] =
-// ParamPickerMake(ObjectAttributes->ObjectName);
-// p[open_params::SECURITY_DESCRIPTOR] =
-// ParamPickerMake(ObjectAttributes->SecurityDescriptor);
-// p[open_params::IO_STATUS] = ParamPickerMake(IoStatusBlock);
-// p[open_params::OPEN_OPTIONS] = ParamPickerMake(OpenOptions);
-//
-// These will create an stack-allocated array of ParameterSet objects which
-// have each 1) the address of the parameter 2) a numeric id that encodes the
-// original C++ type. This allows the policy to treat any set of supported
-// argument types uniformily and with some type safety.
-//
-// TODO(cpu): support not fully implemented yet for unicode string and will
-// probably add other types as well.
-class ParameterSet {
- public:
- ParameterSet() : real_type_(INVALID_TYPE), address_(NULL) {}
-
- // Retrieve the stored parameter. If the type does not match ulong fail.
- bool Get(unsigned long* destination) const {
- if (ULONG_TYPE != real_type_) {
- return false;
- }
- *destination = Void2TypePointerCopy<unsigned long>();
- return true;
- }
-
- // Retrieve the stored parameter. If the type does not match void* fail.
- bool Get(const void** destination) const {
- if (VOIDPTR_TYPE != real_type_) {
- return false;
- }
- *destination = Void2TypePointerCopy<void*>();
- return true;
- }
-
- // Retrieve the stored parameter. If the type does not match wchar_t* fail.
- bool Get(const wchar_t** destination) const {
- if (WCHAR_TYPE != real_type_) {
- return false;
- }
- *destination = Void2TypePointerCopy<const wchar_t*>();
- return true;
- }
-
- // False if the parameter is not properly initialized.
- bool IsValid() const {
- return INVALID_TYPE != real_type_;
- }
-
- protected:
- // The constructor can only be called by derived types, which should
- // safely provide the real_type and the address of the argument.
- ParameterSet(ArgType real_type, const void* address)
- : real_type_(real_type), address_(address) {
- }
-
- private:
- // This template provides the same functionality as bits_cast but
- // it works with pointer while the former works only with references.
- template <typename T>
- T Void2TypePointerCopy() const {
- return *(reinterpret_cast<const T*>(address_));
- }
-
- ArgType real_type_;
- const void* address_;
-};
-
-// To safely infer the type, we use a set of template specializations
-// in ParameterSetEx with a template function ParamPickerMake to do the
-// parameter type deduction.
-
-// Base template class. Not implemented so using unsupported types should
-// fail to compile.
-template <typename T>
-class ParameterSetEx : public ParameterSet {
- public:
- ParameterSetEx(const void* address);
-};
-
-template<>
-class ParameterSetEx<void const*> : public ParameterSet {
- public:
- ParameterSetEx(const void* address)
- : ParameterSet(VOIDPTR_TYPE, address) {}
-};
-
-template<>
-class ParameterSetEx<void*> : public ParameterSet {
- public:
- ParameterSetEx(const void* address)
- : ParameterSet(VOIDPTR_TYPE, address) {}
-};
-
-
-template<>
-class ParameterSetEx<wchar_t*> : public ParameterSet {
- public:
- ParameterSetEx(const void* address)
- : ParameterSet(WCHAR_TYPE, address) {}
-};
-
-template<>
-class ParameterSetEx<wchar_t const*> : public ParameterSet {
- public:
- ParameterSetEx(const void* address)
- : ParameterSet(WCHAR_TYPE, address) {}
-};
-
-
-template<>
-class ParameterSetEx<unsigned long> : public ParameterSet {
- public:
- ParameterSetEx(const void* address)
- : ParameterSet(ULONG_TYPE, address) {}
-};
-
-template<>
-class ParameterSetEx<UNICODE_STRING> : public ParameterSet {
- public:
- ParameterSetEx(const void* address)
- : ParameterSet(UNISTR_TYPE, address) {}
-};
-
-template <typename T>
-ParameterSet ParamPickerMake(T& parameter) {
- return ParameterSetEx<T>(&parameter);
-};
-
-struct CountedParameterSetBase {
- int count;
- ParameterSet parameters[1];
-};
-
-// This template defines the actual list of policy parameters for a given
-// interception.
-// Warning: This template stores the address to the actual variables, in
-// other words, the values are not copied.
-template <typename T>
-struct CountedParameterSet {
- CountedParameterSet() : count(T::PolParamLast) {}
-
- ParameterSet& operator[](typename T::Args n) {
- return parameters[n];
- }
-
- CountedParameterSetBase* GetBase() {
- return reinterpret_cast<CountedParameterSetBase*>(this);
- }
-
- int count;
- ParameterSet parameters[T::PolParamLast];
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__
diff --git a/sandbox/win/src/policy_engine_processor.cc b/sandbox/win/src/policy_engine_processor.cc
deleted file mode 100644
index a35eabf..0000000
--- a/sandbox/win/src/policy_engine_processor.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/policy_engine_processor.h"
-
-namespace sandbox {
-
-void PolicyProcessor::SetInternalState(size_t index, EvalResult result) {
- state_.current_index_ = index;
- state_.current_result_ = result;
-}
-
-EvalResult PolicyProcessor::GetAction() const {
- return state_.current_result_;
-}
-
-// Decides if an opcode can be skipped (not evaluated) or not. The function
-// takes as inputs the opcode and the current evaluation context and returns
-// true if the opcode should be skipped or not and also can set keep_skipping
-// to false to signal that the current instruction should be skipped but not
-// the next after the current one.
-bool SkipOpcode(PolicyOpcode& opcode, MatchContext* context,
- bool* keep_skipping) {
- if (opcode.IsAction()) {
- uint32 options = context->options;
- context->Clear();
- *keep_skipping = false;
- return (kPolUseOREval == options)? false : true;
- }
- *keep_skipping = true;
- return true;
-}
-
-PolicyResult PolicyProcessor::Evaluate(uint32 options,
- ParameterSet* parameters,
- size_t param_count) {
- if (NULL == policy_) {
- return NO_POLICY_MATCH;
- }
- if (0 == policy_->opcode_count) {
- return NO_POLICY_MATCH;
- }
- if (!(kShortEval & options)) {
- return POLICY_ERROR;
- }
-
- MatchContext context;
- bool evaluation = false;
- bool skip_group = false;
- SetInternalState(0, EVAL_FALSE);
- size_t count = policy_->opcode_count;
-
- // Loop over all the opcodes Evaluating in sequence. Since we only support
- // short circuit evaluation, we stop as soon as we find an 'action' opcode
- // and the current evaluation is true.
- //
- // Skipping opcodes can happen when we are in AND mode (!kPolUseOREval) and
- // have got EVAL_FALSE or when we are in OR mode (kPolUseOREval) and got
- // EVAL_TRUE. Skipping will stop at the next action opcode or at the opcode
- // after the action depending on kPolUseOREval.
-
- for (size_t ix = 0; ix != count; ++ix) {
- PolicyOpcode& opcode = policy_->opcodes[ix];
- // Skipping block.
- if (skip_group) {
- if (SkipOpcode(opcode, &context, &skip_group)) {
- continue;
- }
- }
- // Evaluation block.
- EvalResult result = opcode.Evaluate(parameters, param_count, &context);
- switch (result) {
- case EVAL_FALSE:
- evaluation = false;
- if (kPolUseOREval != context.options) {
- skip_group = true;
- }
- break;
- case EVAL_ERROR:
- if (kStopOnErrors & options) {
- return POLICY_ERROR;
- }
- break;
- case EVAL_TRUE:
- evaluation = true;
- if (kPolUseOREval == context.options) {
- skip_group = true;
- }
- break;
- default:
- // We have evaluated an action.
- SetInternalState(ix, result);
- return POLICY_MATCH;
- }
- }
-
- if (evaluation) {
- // Reaching the end of the policy with a positive evaluation is probably
- // an error: we did not find a final action opcode?
- return POLICY_ERROR;
- }
- return NO_POLICY_MATCH;
-}
-
-
-} // namespace sandbox
diff --git a/sandbox/win/src/policy_engine_processor.h b/sandbox/win/src/policy_engine_processor.h
deleted file mode 100644
index 85c999e..0000000
--- a/sandbox/win/src/policy_engine_processor.h
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__
-#define SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/policy_engine_params.h"
-#include "sandbox/win/src/policy_engine_opcodes.h"
-
-namespace sandbox {
-
-// This header contains the core policy evaluator. In its simplest form
-// it evaluates a stream of opcodes assuming that they are laid out in
-// memory as opcode groups.
-//
-// An opcode group has N comparison opcodes plus 1 action opcode. For
-// example here we have 3 opcode groups (A, B,C):
-//
-// [comparison 1] <-- group A start
-// [comparison 2]
-// [comparison 3]
-// [action A ]
-// [comparison 1] <-- group B start
-// [action B ]
-// [comparison 1] <-- group C start
-// [comparison 2]
-// [action C ]
-//
-// The opcode evaluator proceeds from the top, evaluating each opcode in
-// sequence. An opcode group is evaluated until the first comparison that
-// returns false. At that point the rest of the group is skipped and evaluation
-// resumes with the first comparison of the next group. When all the comparisons
-// in a group have evaluated to true and the action is reached. The group is
-// considered a matching group.
-//
-// In the 'ShortEval' mode evaluation stops when it reaches the end or the first
-// matching group. The action opcode from this group is the resulting policy
-// action.
-//
-// In the 'RankedEval' mode evaluation stops only when it reaches the end of the
-// the opcode stream. In the process all matching groups are saved and at the
-// end the 'best' group is selected (what makes the best is TBD) and the action
-// from this group is the resulting policy action.
-//
-// As explained above, the policy evaluation of a group is a logical AND of
-// the evaluation of each opcode. However an opcode can request kPolUseOREval
-// which makes the evaluation to use logical OR. Given that each opcode can
-// request its evaluation result to be negated with kPolNegateEval you can
-// achieve the negation of the total group evaluation. This means that if you
-// need to express:
-// if (!(c1 && c2 && c3))
-// You can do it by:
-// if ((!c1) || (!c2) || (!c3))
-//
-
-// Possible outcomes of policy evaluation.
-enum PolicyResult {
- NO_POLICY_MATCH,
- POLICY_MATCH,
- POLICY_ERROR
-};
-
-// Policy evaluation flags
-// TODO(cpu): implement the options 0 & 4.
-//
-// Stop evaluating as soon as an error is encountered.
-const uint32 kStopOnErrors = 0;
-// Ignore all non fatal opcode evaluation errors.
-const uint32 kIgnoreErrors = 1;
-// Short-circuit evaluation: Only evaluate until opcode group that
-// evaluated to true has been found.
-const uint32 kShortEval = 2;
-// Discussed briefly at the policy design meeting. It will evaluate
-// all rules and then return the 'best' rule that evaluated true.
-const uint32 kRankedEval = 4;
-
-// This class evaluates a policy-opcode stream given the memory where the
-// opcodes are and an input 'parameter set'.
-//
-// This class is designed to be callable from interception points
-// as low as the NtXXXX service level (it is not currently safe, but
-// it is designed to be made safe).
-//
-// Its usage in an interception is:
-//
-// POLPARAMS_BEGIN(eval_params)
-// POLPARAM(param1)
-// POLPARAM(param2)
-// POLPARAM(param3)
-// POLPARAM(param4)
-// POLPARAM(param5)
-// POLPARAMS_END;
-//
-// PolicyProcessor pol_evaluator(policy_memory);
-// PolicyResult pr = pol_evaluator.Evaluate(ShortEval, eval_params,
-// _countof(eval_params));
-// if (NO_POLICY_MATCH == pr) {
-// EvalResult policy_action = pol_evaluator.GetAction();
-// // apply policy here...
-// }
-//
-// Where the POLPARAM() arguments are derived from the intercepted function
-// arguments, and represent all the 'interesting' policy inputs, and
-// policy_memory is a memory buffer containing the opcode stream that is the
-// relevant policy for this intercept.
-class PolicyProcessor {
- public:
- // policy_buffer contains opcodes made with OpcodeFactory. They are usually
- // created in the broker process and evaluated in the target process.
-
- // This constructor is just a variant of the previous constructor.
- explicit PolicyProcessor(PolicyBuffer* policy)
- : policy_(policy) {
- SetInternalState(0, EVAL_FALSE);
- }
-
- // Evaluates a policy-opcode stream. See the comments at the top of this
- // class for more info. Returns POLICY_MATCH if a rule set was found that
- // matches an active policy.
- PolicyResult Evaluate(uint32 options,
- ParameterSet* parameters,
- size_t parameter_count);
-
- // If the result of Evaluate() was POLICY_MATCH, calling this function returns
- // the recommended policy action.
- EvalResult GetAction() const;
-
- private:
- struct {
- size_t current_index_;
- EvalResult current_result_;
- } state_;
-
- // Sets the currently matching action result.
- void SetInternalState(size_t index, EvalResult result);
-
- PolicyBuffer* policy_;
- DISALLOW_COPY_AND_ASSIGN(PolicyProcessor);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__
diff --git a/sandbox/win/src/policy_engine_unittest.cc b/sandbox/win/src/policy_engine_unittest.cc
deleted file mode 100644
index e6c3435..0000000
--- a/sandbox/win/src/policy_engine_unittest.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/policy_engine_params.h"
-#include "sandbox/win/src/policy_engine_processor.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#define POLPARAMS_BEGIN(x) sandbox::ParameterSet x[] = {
-#define POLPARAM(p) sandbox::ParamPickerMake(p),
-#define POLPARAMS_END }
-
-namespace sandbox {
-
-bool SetupNtdllImports();
-
-TEST(PolicyEngineTest, Rules1) {
- SetupNtdllImports();
-
- // Construct two policy rules that say:
- //
- // #1
- // If the path is c:\\documents and settings\\* AND
- // If the creation mode is 'open existing' AND
- // If the security descriptor is null THEN
- // Ask the broker.
- //
- // #2
- // If the security descriptor is null AND
- // If the path ends with *.txt AND
- // If the creation mode is not 'create new' THEN
- // return Access Denied.
-
- enum FileCreateArgs {
- FileNameArg,
- CreationDispositionArg,
- FlagsAndAttributesArg,
- SecurityAttributes
- };
-
- const size_t policy_sz = 1024;
- PolicyBuffer* policy = reinterpret_cast<PolicyBuffer*>(new char[policy_sz]);
- OpcodeFactory opcode_maker(policy, policy_sz - 0x40);
-
- // Add rule set #1
- opcode_maker.MakeOpWStringMatch(FileNameArg,
- L"c:\\documents and settings\\",
- 0, CASE_INSENSITIVE, kPolNone);
- opcode_maker.MakeOpNumberMatch(CreationDispositionArg, OPEN_EXISTING,
- kPolNone);
- opcode_maker.MakeOpVoidPtrMatch(SecurityAttributes, (void*)NULL,
- kPolNone);
- opcode_maker.MakeOpAction(ASK_BROKER, kPolNone);
-
- // Add rule set #2
- opcode_maker.MakeOpWStringMatch(FileNameArg, L".TXT",
- kSeekToEnd, CASE_INSENSITIVE, kPolNone);
- opcode_maker.MakeOpNumberMatch(CreationDispositionArg, CREATE_NEW,
- kPolNegateEval);
- opcode_maker.MakeOpAction(FAKE_ACCESS_DENIED, kPolNone);
- policy->opcode_count = 7;
-
- wchar_t* filename = L"c:\\Documents and Settings\\Microsoft\\BLAH.txt";
- unsigned long creation_mode = OPEN_EXISTING;
- unsigned long flags = FILE_ATTRIBUTE_NORMAL;
- void* security_descriptor = NULL;
-
- POLPARAMS_BEGIN(eval_params)
- POLPARAM(filename)
- POLPARAM(creation_mode)
- POLPARAM(flags)
- POLPARAM(security_descriptor)
- POLPARAMS_END;
-
- PolicyResult pr;
- PolicyProcessor pol_ev(policy);
-
- // Test should match the first rule set.
- pr = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, pr);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- // Test should still match the first rule set.
- pr = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, pr);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- // Changing creation_mode such that evaluation should not match any rule.
- creation_mode = CREATE_NEW;
- pr = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, pr);
-
- // Changing creation_mode such that evaluation should match rule #2.
- creation_mode = OPEN_ALWAYS;
- pr = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, pr);
- EXPECT_EQ(FAKE_ACCESS_DENIED, pol_ev.GetAction());
-
- delete [] reinterpret_cast<char*>(policy);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/policy_low_level.cc b/sandbox/win/src/policy_low_level.cc
deleted file mode 100644
index 8431bc0..0000000
--- a/sandbox/win/src/policy_low_level.cc
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-#include <map>
-
-#include "sandbox/win/src/policy_low_level.h"
-#include "base/basictypes.h"
-
-namespace {
-
- // A single rule can use at most this amount of memory.
- const size_t kRuleBufferSize = 1024*4;
-
- // The possible states of the string matching opcode generator.
- enum {
- PENDING_NONE,
- PENDING_ASTERISK, // Have seen an '*' but have not generated an opcode.
- PENDING_QMARK, // Have seen an '?' but have not generated an opcode.
- };
-
- // The category of the last character seen by the string matching opcode
- // generator.
- const uint32 kLastCharIsNone = 0;
- const uint32 kLastCharIsAlpha = 1;
- const uint32 kLastCharIsWild = 2;
- const uint32 kLastCharIsAsterisk = kLastCharIsWild + 4;
- const uint32 kLastCharIsQuestionM = kLastCharIsWild + 8;
-}
-
-namespace sandbox {
-
-// Adding a rule is nothing more than pushing it into an stl container. Done()
-// is called for the rule in case the code that made the rule in the first
-// place has not done it.
-bool LowLevelPolicy::AddRule(int service, PolicyRule* rule) {
- if (!rule->Done()) {
- return false;
- }
-
- PolicyRule* local_rule = new PolicyRule(*rule);
- RuleNode node = {local_rule, service};
- rules_.push_back(node);
- return true;
-}
-
-LowLevelPolicy::~LowLevelPolicy() {
- // Delete all the rules.
- typedef std::list<RuleNode> RuleNodes;
- for (RuleNodes::iterator it = rules_.begin(); it != rules_.end(); ++it) {
- delete it->rule;
- }
-}
-
-// Here is where the heavy byte shuffling is done. We take all the rules and
-// 'compile' them into a single memory region. Now, the rules are in random
-// order so the first step is to reorganize them into a stl map that is keyed
-// by the service id and as a value contains a list with all the rules that
-// belong to that service. Then we enter the big for-loop where we carve a
-// memory zone for the opcodes and the data and call RebindCopy on each rule
-// so they all end up nicely packed in the policy_store_.
-bool LowLevelPolicy::Done() {
- typedef std::list<RuleNode> RuleNodes;
- typedef std::list<const PolicyRule*> RuleList;
- typedef std::map<uint32, RuleList> Mmap;
- Mmap mmap;
-
- for (RuleNodes::iterator it = rules_.begin(); it != rules_.end(); ++it) {
- mmap[it->service].push_back(it->rule);
- }
-
- PolicyBuffer* current_buffer = &policy_store_->data[0];
- char* buffer_end = reinterpret_cast<char*>(current_buffer) +
- policy_store_->data_size;
- size_t avail_size = policy_store_->data_size;
-
- for (Mmap::iterator it = mmap.begin(); it != mmap.end(); ++it) {
- uint32 service = (*it).first;
- if (service >= kMaxServiceCount) {
- return false;
- }
- policy_store_->entry[service] = current_buffer;
-
- RuleList::iterator rules_it = (*it).second.begin();
- RuleList::iterator rules_it_end = (*it).second.end();
-
- size_t svc_opcode_count = 0;
-
- for (; rules_it != rules_it_end; ++rules_it) {
- const PolicyRule* rule = (*rules_it);
- size_t op_count = rule->GetOpcodeCount();
-
- size_t opcodes_size = op_count * sizeof(PolicyOpcode);
- if (avail_size < opcodes_size) {
- return false;
- }
- size_t data_size = avail_size - opcodes_size;
- PolicyOpcode* opcodes_start = &current_buffer->opcodes[svc_opcode_count];
- if (!rule->RebindCopy(opcodes_start, opcodes_size,
- buffer_end, &data_size)) {
- return false;
- }
- size_t used = avail_size - data_size;
- buffer_end -= used;
- avail_size -= used;
- svc_opcode_count += op_count;
- }
-
- current_buffer->opcode_count += svc_opcode_count;
- size_t policy_byte_count = (svc_opcode_count * sizeof(PolicyOpcode))
- / sizeof(current_buffer[0]);
- current_buffer = &current_buffer[policy_byte_count + 1];
- }
-
- return true;
-}
-
-PolicyRule::PolicyRule(EvalResult action)
- : action_(action), done_(false) {
- char* memory = new char[sizeof(PolicyBuffer) + kRuleBufferSize];
- buffer_ = reinterpret_cast<PolicyBuffer*>(memory);
- buffer_->opcode_count = 0;
- opcode_factory_ = new OpcodeFactory(buffer_,
- kRuleBufferSize + sizeof(PolicyOpcode));
-}
-
-PolicyRule::PolicyRule(const PolicyRule& other) {
- if (this == &other)
- return;
- action_ = other.action_;
- done_ = other.done_;
- size_t buffer_size = sizeof(PolicyBuffer) + kRuleBufferSize;
- char* memory = new char[buffer_size];
- buffer_ = reinterpret_cast<PolicyBuffer*>(memory);
- memcpy(buffer_, other.buffer_, buffer_size);
-
- char* opcode_buffer = reinterpret_cast<char*>(&buffer_->opcodes[0]);
- char* buffer_end = &opcode_buffer[kRuleBufferSize + sizeof(PolicyOpcode)];
- char* next_opcode = &opcode_buffer[GetOpcodeCount() * sizeof(PolicyOpcode)];
- opcode_factory_ = new OpcodeFactory(next_opcode, buffer_end - next_opcode);
-}
-
-// This function get called from a simple state machine implemented in
-// AddStringMatch() which passes the current state (in state) and it passes
-// true in last_call if AddStringMatch() has finished processing the input
-// pattern string and this would be the last call to generate any pending
-// opcode. The skip_count is the currently accumulated number of '?' seen so
-// far and once the associated opcode is generated this function sets it back
-// to zero.
-bool PolicyRule::GenStringOpcode(RuleType rule_type,
- StringMatchOptions match_opts,
- uint16 parameter, int state, bool last_call,
- int* skip_count, std::wstring* fragment) {
-
- // The last opcode must:
- // 1) Always clear the context.
- // 2) Preserve the negation.
- // 3) Remove the 'OR' mode flag.
- uint32 options = kPolNone;
- if (last_call) {
- if (IF_NOT == rule_type) {
- options = kPolClearContext | kPolNegateEval;
- } else {
- options = kPolClearContext;
- }
- } else if (IF_NOT == rule_type) {
- options = kPolUseOREval | kPolNegateEval;
- }
-
- PolicyOpcode* op = NULL;
-
- // The fragment string contains the accumulated characters to match with, it
- // never contains wildcards (unless they have been escaped) and while there
- // is no fragment there is no new string match opcode to generate.
- if (fragment->empty()) {
- // There is no new opcode to generate but in the last call we have to fix
- // the previous opcode because it was really the last but we did not know
- // it at that time.
- if (last_call && (buffer_->opcode_count > 0)) {
- op = &buffer_->opcodes[buffer_->opcode_count - 1];
- op->SetOptions(options);
- }
- return true;
- }
-
- if (PENDING_ASTERISK == state) {
- if (last_call) {
- op = opcode_factory_->MakeOpWStringMatch(parameter, fragment->c_str(),
- kSeekToEnd, match_opts,
- options);
- } else {
- op = opcode_factory_->MakeOpWStringMatch(parameter, fragment->c_str(),
- kSeekForward, match_opts,
- options);
- }
-
- } else if (PENDING_QMARK == state) {
- op = opcode_factory_->MakeOpWStringMatch(parameter, fragment->c_str(),
- *skip_count, match_opts, options);
- *skip_count = 0;
- } else {
- if (last_call) {
- match_opts = static_cast<StringMatchOptions>(EXACT_LENGHT | match_opts);
- }
- op = opcode_factory_->MakeOpWStringMatch(parameter, fragment->c_str(), 0,
- match_opts, options);
- }
- if (NULL == op) {
- return false;
- }
- ++buffer_->opcode_count;
- fragment->clear();
- return true;
-}
-
-bool PolicyRule::AddStringMatch(RuleType rule_type, int16 parameter,
- const wchar_t* string,
- StringMatchOptions match_opts) {
- if (done_) {
- // Do not allow to add more rules after generating the action opcode.
- return false;
- }
-
- const wchar_t* current_char = string;
- uint32 last_char = kLastCharIsNone;
- int state = PENDING_NONE;
- int skip_count = 0; // counts how many '?' we have seen in a row.
- std::wstring fragment; // accumulates the non-wildcard part of the string.
-
- while (L'\0' != *current_char) {
- switch (*current_char) {
- case L'*':
- if (kLastCharIsWild & last_char) {
- // '**' and '&*' is an error.
- return false;
- }
- if (!GenStringOpcode(rule_type, match_opts, parameter,
- state, false, &skip_count, &fragment)) {
- return false;
- }
- last_char = kLastCharIsAsterisk;
- state = PENDING_ASTERISK;
- break;
- case L'?':
- if (kLastCharIsAsterisk == last_char) {
- // '*?' is an error.
- return false;
- }
- if (!GenStringOpcode(rule_type, match_opts, parameter,
- state, false, &skip_count, &fragment)) {
- return false;
- }
- ++skip_count;
- last_char = kLastCharIsQuestionM;
- state = PENDING_QMARK;
- break;
- case L'/':
- // Note: "/?" is an escaped '?'. Eat the slash and fall through.
- if (L'?' == current_char[1]) {
- ++current_char;
- }
- default:
- fragment += *current_char;
- last_char = kLastCharIsAlpha;
- }
- ++current_char;
- }
-
- if (!GenStringOpcode(rule_type, match_opts, parameter,
- state, true, &skip_count, &fragment)) {
- return false;
- }
- return true;
-}
-
-bool PolicyRule::AddNumberMatch(RuleType rule_type, int16 parameter,
- unsigned long number, RuleOp comparison_op) {
- if (done_) {
- // Do not allow to add more rules after generating the action opcode.
- return false;
- }
- uint32 opts = (rule_type == IF_NOT)? kPolNegateEval : kPolNone;
-
- if (EQUAL == comparison_op) {
- if (NULL == opcode_factory_->MakeOpNumberMatch(parameter, number, opts)) {
- return false;
- }
- } else if (AND == comparison_op) {
- if (NULL == opcode_factory_->MakeOpUlongAndMatch(parameter, number, opts)) {
- return false;
- }
- }
- ++buffer_->opcode_count;
- return true;
-}
-
-bool PolicyRule::Done() {
- if (done_) {
- return true;
- }
- if (NULL == opcode_factory_->MakeOpAction(action_, kPolNone)) {
- return false;
- }
- ++buffer_->opcode_count;
- done_ = true;
- return true;
-}
-
-bool PolicyRule::RebindCopy(PolicyOpcode* opcode_start, size_t opcode_size,
- char* data_start, size_t* data_size) const {
- size_t count = buffer_->opcode_count;
- for (size_t ix = 0; ix != count; ++ix) {
- if (opcode_size < sizeof(PolicyOpcode)) {
- return false;
- }
- PolicyOpcode& opcode = buffer_->opcodes[ix];
- *opcode_start = opcode;
- if (OP_WSTRING_MATCH == opcode.GetID()) {
- // For this opcode argument 0 is a delta to the string and argument 1
- // is the length (in chars) of the string.
- const wchar_t* str = opcode.GetRelativeString(0);
- size_t str_len;
- opcode.GetArgument(1, &str_len);
- str_len = str_len * sizeof(wchar_t);
- if ((*data_size) < str_len) {
- return false;
- }
- *data_size -= str_len;
- data_start -= str_len;
- memcpy(data_start, str, str_len);
- // Recompute the string displacement
- ptrdiff_t delta = data_start - reinterpret_cast<char*>(opcode_start);
- opcode_start->SetArgument(0, delta);
- }
- ++opcode_start;
- opcode_size -= sizeof(PolicyOpcode);
- }
-
- return true;
-}
-
-PolicyRule::~PolicyRule() {
- delete [] reinterpret_cast<char*>(buffer_);
- delete opcode_factory_;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/policy_low_level.h b/sandbox/win/src/policy_low_level.h
deleted file mode 100644
index 025a133..0000000
--- a/sandbox/win/src/policy_low_level.h
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_POLICY_LOW_LEVEL_H__
-#define SANDBOX_SRC_POLICY_LOW_LEVEL_H__
-
-#include <list>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_engine_params.h"
-#include "sandbox/win/src/policy_engine_opcodes.h"
-
-// Low level policy classes.
-// Built on top of the PolicyOpcode and OpcodeFatory, the low level policy
-// provides a way to define rules on strings and numbers but it is unaware
-// of Windows specific details or how the Interceptions must be set up.
-// To use these classes you construct one or more rules and add them to the
-// LowLevelPolicy object like this:
-//
-// PolicyRule rule1(ASK_BROKER);
-// rule1.AddStringMatch(IF, 0, L"\\\\/?/?\\c:\\*Microsoft*\\*.exe", true);
-// rule1.AddNumberMatch(IF_NOT, 1, CREATE_ALWAYS, EQUAL);
-// rule1.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL);
-//
-// PolicyRule rule2(FAKE_SUCCESS);
-// rule2.AddStringMatch(IF, 0, L"\\\\/?/?\\Pipe\\Chrome.*", false));
-// rule2.AddNumberMatch(IF, 1, OPEN_EXISTING, EQUAL));
-//
-// LowLevelPolicy policyGen(*policy_memory);
-// policyGen.AddRule(kNtCreateFileSvc, &rule1);
-// policyGen.AddRule(kNtCreateFileSvc, &rule2);
-// policyGen.Done();
-//
-// At this point (error checking omitted) the policy_memory can be copied
-// to the target process where it can be evaluated.
-
-namespace sandbox {
-
-// TODO(cpu): Move this constant to crosscall_client.h.
-const size_t kMaxServiceCount = 32;
-COMPILE_ASSERT(IPC_LAST_TAG <= kMaxServiceCount, kMaxServiceCount_is_too_low);
-
-// Defines the memory layout of the policy. This memory is filled by
-// LowLevelPolicy object.
-// For example:
-//
-// [Service 0] --points to---\
-// [Service 1] --------------|-----\
-// ...... | |
-// [Service N] | |
-// [data_size] | |
-// [Policy Buffer 0] <-------/ |
-// [opcodes of] |
-// ....... |
-// [Policy Buffer 1] <-------------/
-// [opcodes]
-// .......
-// .......
-// [Policy Buffer N]
-// [opcodes]
-// .......
-// <possibly unused space here>
-// .......
-// [opcode string ]
-// [opcode string ]
-// .......
-// [opcode string ]
-struct PolicyGlobal {
- PolicyBuffer* entry[kMaxServiceCount];
- size_t data_size;
- PolicyBuffer data[1];
-};
-
-class PolicyRule;
-
-// Provides the means to collect rules into a policy store (memory)
-class LowLevelPolicy {
- public:
- // policy_store: must contain allocated memory and the internal
- // size fields set to correct values.
- explicit LowLevelPolicy(PolicyGlobal* policy_store)
- : policy_store_(policy_store) {
- }
-
- // Destroys all the policy rules.
- ~LowLevelPolicy();
-
- // Adds a rule to be generated when Done() is called.
- // service: The id of the service that this rule is associated with,
- // for example the 'Open Thread' service or the "Create File" service.
- // returns false on error.
- bool AddRule(int service, PolicyRule* rule);
-
- // Generates all the rules added with AddRule() into the memory area
- // passed on the constructor. Returns false on error.
- bool Done();
-
- private:
- struct RuleNode {
- const PolicyRule* rule;
- int service;
- };
- std::list<RuleNode> rules_;
- PolicyGlobal* policy_store_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(LowLevelPolicy);
-};
-
-// There are 'if' rules and 'if not' comparisons
-enum RuleType {
- IF = 0,
- IF_NOT = 1,
-};
-
-// Possible comparisons for numbers
-enum RuleOp {
- EQUAL,
- AND,
- RANGE // TODO(cpu): Implement this option.
-};
-
-// Provides the means to collect a set of comparisons into a single
-// rule and its associated action.
-class PolicyRule {
- friend class LowLevelPolicy;
-
- public:
- explicit PolicyRule(EvalResult action);
- PolicyRule(const PolicyRule& other);
- ~PolicyRule();
-
- // Adds a string comparison to the rule.
- // rule_type: possible values are IF and IF_NOT.
- // parameter: the expected index of the argument for this rule. For example
- // in a 'create file' service the file name argument can be at index 0.
- // string: is the desired matching pattern.
- // match_opts: if the pattern matching is case sensitive or not.
- bool AddStringMatch(RuleType rule_type, int16 parameter,
- const wchar_t* string, StringMatchOptions match_opts);
-
- // Adds a number match comparison to the rule.
- // rule_type: possible values are IF and IF_NOT.
- // parameter: the expected index of the argument for this rule.
- // number: the value to compare the input to.
- // comparison_op: the comparison kind (equal, logical and, etc).
- bool AddNumberMatch(RuleType rule_type, int16 parameter,
- unsigned long number, RuleOp comparison_op);
-
- // Returns the number of opcodes generated so far.
- size_t GetOpcodeCount() const {
- return buffer_->opcode_count;
- }
-
- // Called when there is no more comparisons to add. Internally it generates
- // the last opcode (the action opcode). Returns false if this operation fails.
- bool Done();
-
- private:
- void operator=(const PolicyRule&);
- // Called in a loop from AddStringMatch to generate the required string
- // match opcodes. rule_type, match_opts and parameter are the same as
- // in AddStringMatch.
- bool GenStringOpcode(RuleType rule_type, StringMatchOptions match_opts,
- uint16 parameter, int state, bool last_call,
- int* skip_count, std::wstring* fragment);
-
- // Loop over all generated opcodes and copy them to increasing memory
- // addresses from opcode_start and copy the extra data (strings usually) into
- // decreasing addresses from data_start. Extra data is only present in the
- // string evaluation opcodes.
- bool RebindCopy(PolicyOpcode* opcode_start, size_t opcode_size,
- char* data_start, size_t* data_size) const;
- PolicyBuffer* buffer_;
- OpcodeFactory* opcode_factory_;
- EvalResult action_;
- bool done_;
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_POLICY_LOW_LEVEL_H__
diff --git a/sandbox/win/src/policy_low_level_unittest.cc b/sandbox/win/src/policy_low_level_unittest.cc
deleted file mode 100644
index 4a2cf4b..0000000
--- a/sandbox/win/src/policy_low_level_unittest.cc
+++ /dev/null
@@ -1,575 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/policy_engine_params.h"
-#include "sandbox/win/src/policy_engine_processor.h"
-#include "sandbox/win/src/policy_low_level.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#define POLPARAMS_BEGIN(x) sandbox::ParameterSet x[] = {
-#define POLPARAM(p) sandbox::ParamPickerMake(p),
-#define POLPARAMS_END }
-
-namespace sandbox {
-
-bool SetupNtdllImports();
-
-// Testing that we allow opcode generation on valid string patterns.
-TEST(PolicyEngineTest, StringPatternsOK) {
- SetupNtdllImports();
- PolicyRule pr(ASK_BROKER);
- EXPECT_TRUE(pr.AddStringMatch(IF, 0, L"c:\\adobe\\ver??\\", CASE_SENSITIVE));
- EXPECT_TRUE(pr.AddStringMatch(IF, 0, L"*.tmp", CASE_SENSITIVE));
- EXPECT_TRUE(pr.AddStringMatch(IF, 0, L"c:\\*.doc", CASE_SENSITIVE));
- EXPECT_TRUE(pr.AddStringMatch(IF, 0, L"c:\\windows\\*", CASE_SENSITIVE));
- EXPECT_TRUE(pr.AddStringMatch(IF, 0, L"d:\\adobe\\acrobat.exe",
- CASE_SENSITIVE));
-}
-
-// Testing that we signal invalid string patterns.
-TEST(PolicyEngineTest, StringPatternsBAD) {
- SetupNtdllImports();
- PolicyRule pr(ASK_BROKER);
- EXPECT_FALSE(pr.AddStringMatch(IF, 0, L"one**two", CASE_SENSITIVE));
- EXPECT_FALSE(pr.AddStringMatch(IF, 0, L"**three", CASE_SENSITIVE));
- EXPECT_FALSE(pr.AddStringMatch(IF, 0, L"five?six*?seven", CASE_SENSITIVE));
- EXPECT_FALSE(pr.AddStringMatch(IF, 0, L"eight?*nine", CASE_SENSITIVE));
-}
-
-// Helper function to allocate space (on the heap) for policy.
-PolicyGlobal* MakePolicyMemory() {
- const size_t kTotalPolicySz = 4096*8;
- char* mem = new char[kTotalPolicySz];
- memset(mem, 0, kTotalPolicySz);
- PolicyGlobal* policy = reinterpret_cast<PolicyGlobal*>(mem);
- policy->data_size = kTotalPolicySz - sizeof(PolicyGlobal);
- return policy;
-}
-
-// The simplest test using LowLevelPolicy it should test a single opcode which
-// does a exact string comparison.
-TEST(PolicyEngineTest, SimpleStrMatch) {
- SetupNtdllImports();
- PolicyRule pr(ASK_BROKER);
- EXPECT_TRUE(pr.AddStringMatch(IF, 0, L"z:\\Directory\\domo.txt",
- CASE_INSENSITIVE));
-
- PolicyGlobal* policy = MakePolicyMemory();
- const uint32 kFakeService = 2;
-
- LowLevelPolicy policyGen(policy);
- EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
- EXPECT_TRUE(policyGen.Done());
-
- wchar_t* filename = L"Z:\\Directory\\domo.txt";
-
- POLPARAMS_BEGIN(eval_params)
- POLPARAM(filename) // Argument 0
- POLPARAMS_END;
-
- PolicyResult result;
- PolicyProcessor pol_ev(policy->entry[kFakeService]);
-
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- filename = L"Z:\\Directory\\domo.txt.tmp";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- delete [] reinterpret_cast<char*>(policy);
-}
-
-TEST(PolicyEngineTest, SimpleIfNotStrMatch) {
- SetupNtdllImports();
- PolicyRule pr(ASK_BROKER);
- EXPECT_TRUE(pr.AddStringMatch(IF_NOT, 0, L"c:\\Microsoft\\",
- CASE_SENSITIVE));
-
- PolicyGlobal* policy = MakePolicyMemory();
- const uint32 kFakeService = 2;
- LowLevelPolicy policyGen(policy);
-
- EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
- EXPECT_TRUE(policyGen.Done());
-
- wchar_t* filename = NULL;
- POLPARAMS_BEGIN(eval_params)
- POLPARAM(filename) // Argument 0
- POLPARAMS_END;
-
- PolicyResult result;
- PolicyProcessor pol_ev(policy->entry[kFakeService]);
-
- filename = L"c:\\Microsoft\\";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"c:\\MicroNerd\\";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- filename = L"c:\\Microsoft\\domo.txt";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- delete [] reinterpret_cast<char*>(policy);
-}
-
-TEST(PolicyEngineTest, SimpleIfNotStrMatchWild1) {
- SetupNtdllImports();
- PolicyRule pr(ASK_BROKER);
- EXPECT_TRUE(pr.AddStringMatch(IF_NOT, 0, L"c:\\Microsoft\\*",
- CASE_SENSITIVE));
-
- PolicyGlobal* policy = MakePolicyMemory();
- const uint32 kFakeService = 3;
- LowLevelPolicy policyGen(policy);
-
- EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
- EXPECT_TRUE(policyGen.Done());
-
- wchar_t* filename = NULL;
- POLPARAMS_BEGIN(eval_params)
- POLPARAM(filename) // Argument 0
- POLPARAMS_END;
-
- PolicyResult result;
- PolicyProcessor pol_ev(policy->entry[kFakeService]);
-
- filename = L"c:\\Microsoft\\domo.txt";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"c:\\MicroNerd\\domo.txt";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- delete [] reinterpret_cast<char*>(policy);
-}
-
-TEST(PolicyEngineTest, SimpleIfNotStrMatchWild2) {
- SetupNtdllImports();
- PolicyRule pr(ASK_BROKER);
- EXPECT_TRUE(pr.AddStringMatch(IF_NOT, 0, L"c:\\Microsoft\\*.txt",
- CASE_SENSITIVE));
-
- PolicyGlobal* policy = MakePolicyMemory();
- const uint32 kFakeService = 3;
- LowLevelPolicy policyGen(policy);
-
- EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
- EXPECT_TRUE(policyGen.Done());
-
- wchar_t* filename = NULL;
- POLPARAMS_BEGIN(eval_params)
- POLPARAM(filename) // Argument 0
- POLPARAMS_END;
-
- PolicyResult result;
- PolicyProcessor pol_ev(policy->entry[kFakeService]);
-
- filename = L"c:\\Microsoft\\domo.txt";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"c:\\MicroNerd\\domo.txt";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- filename = L"c:\\Microsoft\\domo.bmp";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- delete [] reinterpret_cast<char*>(policy);
-}
-
-TEST(PolicyEngineTest, IfNotStrMatchTwoRulesWild1) {
- SetupNtdllImports();
- PolicyRule pr(ASK_BROKER);
- EXPECT_TRUE(pr.AddStringMatch(IF_NOT, 0, L"c:\\Microsoft\\*",
- CASE_SENSITIVE));
- EXPECT_TRUE(pr.AddNumberMatch(IF, 1, 24, EQUAL));
-
- PolicyGlobal* policy = MakePolicyMemory();
- const uint32 kFakeService = 3;
- LowLevelPolicy policyGen(policy);
-
- EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
- EXPECT_TRUE(policyGen.Done());
-
- wchar_t* filename = NULL;
- unsigned long access = 0;
- POLPARAMS_BEGIN(eval_params)
- POLPARAM(filename) // Argument 0
- POLPARAM(access) // Argument 1
- POLPARAMS_END;
-
- PolicyResult result;
- PolicyProcessor pol_ev(policy->entry[kFakeService]);
-
- filename = L"c:\\Microsoft\\domo.txt";
- access = 24;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"c:\\Microsoft\\domo.txt";
- access = 42;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"c:\\MicroNerd\\domo.txt";
- access = 24;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- filename = L"c:\\Micronesia\\domo.txt";
- access = 42;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- delete [] reinterpret_cast<char*>(policy);
-}
-
-TEST(PolicyEngineTest, IfNotStrMatchTwoRulesWild2) {
- SetupNtdllImports();
- PolicyRule pr(ASK_BROKER);
- EXPECT_TRUE(pr.AddNumberMatch(IF, 1, 24, EQUAL));
- EXPECT_TRUE(pr.AddStringMatch(IF_NOT, 0, L"c:\\GoogleV?\\*.txt",
- CASE_SENSITIVE));
- EXPECT_TRUE(pr.AddNumberMatch(IF, 2, 66, EQUAL));
-
- PolicyGlobal* policy = MakePolicyMemory();
- const uint32 kFakeService = 3;
- LowLevelPolicy policyGen(policy);
-
- EXPECT_TRUE(policyGen.AddRule(kFakeService, &pr));
- EXPECT_TRUE(policyGen.Done());
-
- wchar_t* filename = NULL;
- unsigned long access = 0;
- unsigned long sharing = 66;
-
- POLPARAMS_BEGIN(eval_params)
- POLPARAM(filename) // Argument 0
- POLPARAM(access) // Argument 1
- POLPARAM(sharing) // Argument 2
- POLPARAMS_END;
-
- PolicyResult result;
- PolicyProcessor pol_ev(policy->entry[kFakeService]);
-
- filename = L"c:\\GoogleV2\\domo.txt";
- access = 24;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"c:\\GoogleV2\\domo.bmp";
- access = 24;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- filename = L"c:\\GoogleV23\\domo.txt";
- access = 24;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
-
- filename = L"c:\\GoogleV2\\domo.txt";
- access = 42;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"c:\\Google\\domo.txt";
- access = 24;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- filename = L"c:\\Micronesia\\domo.txt";
- access = 42;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"c:\\GoogleV2\\domo.bmp";
- access = 24;
- sharing = 0;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- delete [] reinterpret_cast<char*>(policy);
-}
-
-// Testing one single rule in one single service. The service is made to
-// resemble NtCreateFile.
-TEST(PolicyEngineTest, OneRuleTest) {
- SetupNtdllImports();
- PolicyRule pr(ASK_BROKER);
- EXPECT_TRUE(pr.AddStringMatch(IF, 0, L"c:\\*Microsoft*\\*.txt",
- CASE_SENSITIVE));
- EXPECT_TRUE(pr.AddNumberMatch(IF_NOT, 1, CREATE_ALWAYS, EQUAL));
- EXPECT_TRUE(pr.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL));
-
- PolicyGlobal* policy = MakePolicyMemory();
-
- const uint32 kNtFakeCreateFile = 7;
-
- LowLevelPolicy policyGen(policy);
- EXPECT_TRUE(policyGen.AddRule(kNtFakeCreateFile, &pr));
- EXPECT_TRUE(policyGen.Done());
-
- wchar_t* filename = L"c:\\Documents and Settings\\Microsoft\\BLAH.txt";
- unsigned long creation_mode = OPEN_EXISTING;
- unsigned long flags = FILE_ATTRIBUTE_NORMAL;
- void* security_descriptor = NULL;
-
- POLPARAMS_BEGIN(eval_params)
- POLPARAM(filename) // Argument 0
- POLPARAM(creation_mode) // Argument 1
- POLPARAM(flags) // Argument 2
- POLPARAM(security_descriptor)
- POLPARAMS_END;
-
- PolicyResult result;
- PolicyProcessor pol_ev(policy->entry[kNtFakeCreateFile]);
-
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- creation_mode = CREATE_ALWAYS;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- creation_mode = OPEN_EXISTING;
- filename = L"c:\\Other\\Path\\Microsoft\\Another file.txt";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- filename = L"c:\\Other\\Path\\Microsoft\\Another file.txt.tmp";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- flags = FILE_ATTRIBUTE_DEVICE;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"c:\\Other\\Macrosoft\\Another file.txt";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"c:\\Microsoft\\1.txt";
- flags = FILE_ATTRIBUTE_NORMAL;
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, pol_ev.GetAction());
-
- filename = L"c:\\Microsoft\\1.ttt";
- result = pol_ev.Evaluate(kShortEval, eval_params, _countof(eval_params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- delete [] reinterpret_cast<char*>(policy);
-}
-
-// Testing 3 rules in 3 services. Two of the services resemble File services.
-TEST(PolicyEngineTest, ThreeRulesTest) {
- SetupNtdllImports();
- PolicyRule pr_pipe(FAKE_SUCCESS);
- EXPECT_TRUE(pr_pipe.AddStringMatch(IF, 0, L"\\\\/?/?\\Pipe\\Chrome.*",
- CASE_INSENSITIVE));
- EXPECT_TRUE(pr_pipe.AddNumberMatch(IF, 1, OPEN_EXISTING, EQUAL));
- EXPECT_TRUE(pr_pipe.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL));
-
- size_t opc1 = pr_pipe.GetOpcodeCount();
- EXPECT_EQ(3, opc1);
-
- PolicyRule pr_dump(ASK_BROKER);
- EXPECT_TRUE(pr_dump.AddStringMatch(IF, 0, L"\\\\/?/?\\*\\Crash Reports\\*",
- CASE_INSENSITIVE));
- EXPECT_TRUE(pr_dump.AddNumberMatch(IF, 1, CREATE_ALWAYS, EQUAL));
- EXPECT_TRUE(pr_dump.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL));
-
- size_t opc2 = pr_dump.GetOpcodeCount();
- EXPECT_EQ(4, opc2);
-
- PolicyRule pr_winexe(SIGNAL_ALARM);
- EXPECT_TRUE(pr_winexe.AddStringMatch(IF, 0, L"\\\\/?/?\\C:\\Windows\\*.exe",
- CASE_INSENSITIVE));
- EXPECT_TRUE(pr_winexe.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL));
-
- size_t opc3 = pr_winexe.GetOpcodeCount();
- EXPECT_EQ(3, opc3);
-
- PolicyRule pr_adobe(GIVE_CACHED);
- EXPECT_TRUE(pr_adobe.AddStringMatch(IF, 0, L"c:\\adobe\\ver?.?\\",
- CASE_SENSITIVE));
- EXPECT_TRUE(pr_adobe.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL));
-
- size_t opc4 = pr_adobe.GetOpcodeCount();
- EXPECT_EQ(4, opc4);
-
- PolicyRule pr_none(GIVE_FIRST);
- EXPECT_TRUE(pr_none.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_READONLY, AND));
- EXPECT_TRUE(pr_none.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_SYSTEM, AND));
-
- size_t opc5 = pr_none.GetOpcodeCount();
- EXPECT_EQ(2, opc5);
-
- PolicyGlobal* policy = MakePolicyMemory();
-
- const uint32 kNtFakeNone = 4;
- const uint32 kNtFakeCreateFile = 5;
- const uint32 kNtFakeOpenFile = 6;
-
- LowLevelPolicy policyGen(policy);
- EXPECT_TRUE(policyGen.AddRule(kNtFakeCreateFile, &pr_pipe));
- EXPECT_TRUE(policyGen.AddRule(kNtFakeCreateFile, &pr_dump));
- EXPECT_TRUE(policyGen.AddRule(kNtFakeCreateFile, &pr_winexe));
-
- EXPECT_TRUE(policyGen.AddRule(kNtFakeOpenFile, &pr_adobe));
- EXPECT_TRUE(policyGen.AddRule(kNtFakeOpenFile, &pr_pipe));
-
- EXPECT_TRUE(policyGen.AddRule(kNtFakeNone, &pr_none));
-
- EXPECT_TRUE(policyGen.Done());
-
- // Inspect the policy structure manually.
- EXPECT_TRUE(NULL == policy->entry[0]);
- EXPECT_TRUE(NULL == policy->entry[1]);
- EXPECT_TRUE(NULL == policy->entry[2]);
- EXPECT_TRUE(NULL == policy->entry[3]);
- EXPECT_TRUE(NULL != policy->entry[4]); // kNtFakeNone.
- EXPECT_TRUE(NULL != policy->entry[5]); // kNtFakeCreateFile.
- EXPECT_TRUE(NULL != policy->entry[6]); // kNtFakeOpenFile.
- EXPECT_TRUE(NULL == policy->entry[7]);
-
- // The total per service opcode counts now must take in account one
- // extra opcode (action opcode) per rule.
- ++opc1;
- ++opc2;
- ++opc3;
- ++opc4;
- ++opc5;
-
- size_t tc1 = policy->entry[kNtFakeNone]->opcode_count;
- size_t tc2 = policy->entry[kNtFakeCreateFile]->opcode_count;
- size_t tc3 = policy->entry[kNtFakeOpenFile]->opcode_count;
-
- EXPECT_EQ(opc5, tc1);
- EXPECT_EQ((opc1 + opc2 + opc3), tc2);
- EXPECT_EQ((opc1 + opc4), tc3);
-
- // Check the type of the first and last opcode of each service.
-
- EXPECT_EQ(OP_ULONG_AND_MATCH, policy->entry[kNtFakeNone]->opcodes[0].GetID());
- EXPECT_EQ(OP_ACTION, policy->entry[kNtFakeNone]->opcodes[tc1-1].GetID());
- EXPECT_EQ(OP_WSTRING_MATCH,
- policy->entry[kNtFakeCreateFile]->opcodes[0].GetID());
- EXPECT_EQ(OP_ACTION,
- policy->entry[kNtFakeCreateFile]->opcodes[tc2-1].GetID());
- EXPECT_EQ(OP_WSTRING_MATCH,
- policy->entry[kNtFakeOpenFile]->opcodes[0].GetID());
- EXPECT_EQ(OP_ACTION, policy->entry[kNtFakeOpenFile]->opcodes[tc3-1].GetID());
-
- // Test the policy evaluation.
-
- wchar_t* filename = L"";
- unsigned long creation_mode = OPEN_EXISTING;
- unsigned long flags = FILE_ATTRIBUTE_NORMAL;
- void* security_descriptor = NULL;
-
- POLPARAMS_BEGIN(params)
- POLPARAM(filename) // Argument 0
- POLPARAM(creation_mode) // Argument 1
- POLPARAM(flags) // Argument 2
- POLPARAM(security_descriptor)
- POLPARAMS_END;
-
- PolicyResult result;
- PolicyProcessor eval_CreateFile(policy->entry[kNtFakeCreateFile]);
- PolicyProcessor eval_OpenFile(policy->entry[kNtFakeOpenFile]);
- PolicyProcessor eval_None(policy->entry[kNtFakeNone]);
-
- result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
- result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
- result = eval_None.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"\\\\??\\c:\\Windows\\System32\\calc.exe";
- flags = FILE_ATTRIBUTE_SYSTEM;
- result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
- result = eval_None.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
- result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- flags += FILE_ATTRIBUTE_READONLY;
- result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
- result = eval_None.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(GIVE_FIRST, eval_None.GetAction());
- result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- flags = FILE_ATTRIBUTE_NORMAL;
- result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(SIGNAL_ALARM, eval_CreateFile.GetAction());
- result = eval_None.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
- result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"c:\\adobe\\ver3.2\\temp";
- result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
- result = eval_None.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
- result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(GIVE_CACHED, eval_OpenFile.GetAction());
-
- filename = L"c:\\adobe\\ver3.22\\temp";
- result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"\\\\??\\c:\\some path\\other path\\crash reports\\some path";
- creation_mode = CREATE_ALWAYS;
- result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(ASK_BROKER, eval_CreateFile.GetAction());
- result = eval_None.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
- result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
-
- filename = L"\\\\??\\Pipe\\Chrome.12345";
- creation_mode = OPEN_EXISTING;
- result = eval_CreateFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(FAKE_SUCCESS, eval_CreateFile.GetAction());
- result = eval_None.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(NO_POLICY_MATCH, result);
- result = eval_OpenFile.Evaluate(kShortEval, params, _countof(params));
- EXPECT_EQ(POLICY_MATCH, result);
- EXPECT_EQ(FAKE_SUCCESS, eval_OpenFile.GetAction());
-
- delete [] reinterpret_cast<char*>(policy);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/policy_opcodes_unittest.cc b/sandbox/win/src/policy_opcodes_unittest.cc
deleted file mode 100644
index e1a7ad6..0000000
--- a/sandbox/win/src/policy_opcodes_unittest.cc
+++ /dev/null
@@ -1,344 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/sandbox_nt_types.h"
-#include "sandbox/win/src/policy_engine_params.h"
-#include "sandbox/win/src/policy_engine_opcodes.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-
-#define INIT_GLOBAL_RTL(member) \
- g_nt.##member = reinterpret_cast<##member##Function>( \
- ::GetProcAddress(ntdll, #member)); \
- if (NULL == g_nt.##member) \
- return false
-
-namespace sandbox {
-
-SANDBOX_INTERCEPT NtExports g_nt;
-
-bool SetupNtdllImports() {
- HMODULE ntdll = ::GetModuleHandle(kNtdllName);
-
- INIT_GLOBAL_RTL(RtlAllocateHeap);
- INIT_GLOBAL_RTL(RtlAnsiStringToUnicodeString);
- INIT_GLOBAL_RTL(RtlCompareUnicodeString);
- INIT_GLOBAL_RTL(RtlCreateHeap);
- INIT_GLOBAL_RTL(RtlDestroyHeap);
- INIT_GLOBAL_RTL(RtlFreeHeap);
- INIT_GLOBAL_RTL(_strnicmp);
- INIT_GLOBAL_RTL(strlen);
- INIT_GLOBAL_RTL(wcslen);
-
- return true;
-}
-
-TEST(PolicyEngineTest, ParameterSetTest) {
- void* pv1 = reinterpret_cast<void*>(0x477EAA5);
- const void* pv2 = reinterpret_cast<void*>(0x987654);
- ParameterSet pset1 = ParamPickerMake(pv1);
- ParameterSet pset2 = ParamPickerMake(pv2);
-
- // Test that we can store and retrieve a void pointer:
- const void* result1 =0;
- unsigned long result2 = 0;
- EXPECT_TRUE(pset1.Get(&result1));
- EXPECT_TRUE(pv1 == result1);
- EXPECT_FALSE(pset1.Get(&result2));
- EXPECT_TRUE(pset2.Get(&result1));
- EXPECT_TRUE(pv2 == result1);
- EXPECT_FALSE(pset2.Get(&result2));
-
- // Test that we can store and retrieve a ulong:
- unsigned long number = 12747;
- ParameterSet pset3 = ParamPickerMake(number);
- EXPECT_FALSE(pset3.Get(&result1));
- EXPECT_TRUE(pset3.Get(&result2));
- EXPECT_EQ(number, result2);
-
- // Test that we can store and retrieve a string:
- const wchar_t* txt = L"S231L";
- ParameterSet pset4 = ParamPickerMake(txt);
- const wchar_t* result3 = NULL;
- EXPECT_TRUE(pset4.Get(&result3));
- EXPECT_EQ(0, wcscmp(txt, result3));
-}
-
-TEST(PolicyEngineTest, OpcodeConstraints) {
- // Test that PolicyOpcode has no virtual functions
- // because these objects are copied over to other processes
- // so they cannot have vtables.
- EXPECT_FALSE(__is_polymorphic(PolicyOpcode));
- // Keep developers from adding smarts to the opcodes which should
- // be pretty much a bag of bytes with a OO interface.
- EXPECT_TRUE(__has_trivial_destructor(PolicyOpcode));
- EXPECT_TRUE(__has_trivial_constructor(PolicyOpcode));
- EXPECT_TRUE(__has_trivial_copy(PolicyOpcode));
-}
-
-TEST(PolicyEngineTest, TrueFalseOpcodes) {
- void* dummy = NULL;
- ParameterSet ppb1 = ParamPickerMake(dummy);
- char memory[1024];
- OpcodeFactory opcode_maker(memory, sizeof(memory));
-
- // This opcode always evaluates to true.
- PolicyOpcode* op1 = opcode_maker.MakeOpAlwaysFalse(kPolNone);
- EXPECT_EQ(EVAL_FALSE, op1->Evaluate(&ppb1, 1, NULL));
- EXPECT_FALSE(op1->IsAction());
-
- // This opcode always evaluates to false.
- PolicyOpcode* op2 = opcode_maker.MakeOpAlwaysTrue(kPolNone);
- EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 1, NULL));
-
- // Nulls not allowed on the params.
- EXPECT_EQ(EVAL_ERROR, op2->Evaluate(NULL, 0, NULL));
- EXPECT_EQ(EVAL_ERROR, op2->Evaluate(NULL, 1, NULL));
-
- // True and False opcodes do not 'require' a number of parameters
- EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 0, NULL));
- EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 1, NULL));
-
- // Test Inverting the logic. Note that inversion is done outside
- // any particular opcode evaluation so no need to repeat for all
- // opcodes.
- PolicyOpcode* op3 = opcode_maker.MakeOpAlwaysFalse(kPolNegateEval);
- EXPECT_EQ(EVAL_TRUE, op3->Evaluate(&ppb1, 1, NULL));
- PolicyOpcode* op4 = opcode_maker.MakeOpAlwaysTrue(kPolNegateEval);
- EXPECT_EQ(EVAL_FALSE, op4->Evaluate(&ppb1, 1, NULL));
-
- // Test that we clear the match context
- PolicyOpcode* op5 = opcode_maker.MakeOpAlwaysTrue(kPolClearContext);
- MatchContext context;
- context.position = 1;
- context.options = kPolUseOREval;
- EXPECT_EQ(EVAL_TRUE, op5->Evaluate(&ppb1, 1, &context));
- EXPECT_EQ(0, context.position);
- MatchContext context2;
- EXPECT_EQ(context2.options, context.options);
-}
-
-TEST(PolicyEngineTest, OpcodeMakerCase1) {
- // Testing that the opcode maker does not overrun the
- // supplied buffer. It should only be able to make 'count' opcodes.
- void* dummy = NULL;
- ParameterSet ppb1 = ParamPickerMake(dummy);
-
- char memory[256];
- OpcodeFactory opcode_maker(memory, sizeof(memory));
- size_t count = sizeof(memory) / sizeof(PolicyOpcode);
-
- for (size_t ix =0; ix != count; ++ix) {
- PolicyOpcode* op = opcode_maker.MakeOpAlwaysFalse(kPolNone);
- ASSERT_TRUE(NULL != op);
- EXPECT_EQ(EVAL_FALSE, op->Evaluate(&ppb1, 1, NULL));
- }
- // There should be no room more another opcode:
- PolicyOpcode* op1 = opcode_maker.MakeOpAlwaysFalse(kPolNone);
- ASSERT_TRUE(NULL == op1);
-}
-
-TEST(PolicyEngineTest, OpcodeMakerCase2) {
- SetupNtdllImports();
- // Testing that the opcode maker does not overrun the
- // supplied buffer. It should only be able to make 'count' opcodes.
- // The difference with the previous test is that this opcodes allocate
- // the string 'txt2' inside the same buffer.
- const wchar_t* txt1 = L"1234";
- const wchar_t txt2[] = L"123";
-
- ParameterSet ppb1 = ParamPickerMake(txt1);
- MatchContext mc1;
-
- char memory[256];
- OpcodeFactory opcode_maker(memory, sizeof(memory));
- size_t count = sizeof(memory) / (sizeof(PolicyOpcode) + sizeof(txt2));
-
- // Test that it does not overrun the buffer.
- for (size_t ix =0; ix != count; ++ix) {
- PolicyOpcode* op = opcode_maker.MakeOpWStringMatch(0, txt2, 0,
- CASE_SENSITIVE,
- kPolClearContext);
- ASSERT_TRUE(NULL != op);
- EXPECT_EQ(EVAL_TRUE, op->Evaluate(&ppb1, 1, &mc1));
- }
-
- // There should be no room more another opcode:
- PolicyOpcode* op1 = opcode_maker.MakeOpWStringMatch(0, txt2, 0,
- CASE_SENSITIVE,
- kPolNone);
- ASSERT_TRUE(NULL == op1);
-}
-
-TEST(PolicyEngineTest, IntegerOpcodes) {
- const wchar_t* txt = L"abcdef";
- unsigned long num1 = 42;
- unsigned long num2 = 113377;
-
- ParameterSet pp_wrong1 = ParamPickerMake(txt);
- ParameterSet pp_num1 = ParamPickerMake(num1);
- ParameterSet pp_num2 = ParamPickerMake(num2);
-
- char memory[128];
- OpcodeFactory opcode_maker(memory, sizeof(memory));
-
- // Test basic match for unsigned longs 42 == 42 and 42 != 113377.
- PolicyOpcode* op_m42 = opcode_maker.MakeOpNumberMatch(0, unsigned long(42),
- kPolNone);
- EXPECT_EQ(EVAL_TRUE, op_m42->Evaluate(&pp_num1, 1, NULL));
- EXPECT_EQ(EVAL_FALSE, op_m42->Evaluate(&pp_num2, 1, NULL));
- EXPECT_EQ(EVAL_ERROR, op_m42->Evaluate(&pp_wrong1, 1, NULL));
-
- // Test basic match for void pointers.
- const void* vp = NULL;
- ParameterSet pp_num3 = ParamPickerMake(vp);
- PolicyOpcode* op_vp_null = opcode_maker.MakeOpVoidPtrMatch(0, NULL,
- kPolNone);
- EXPECT_EQ(EVAL_TRUE, op_vp_null->Evaluate(&pp_num3, 1, NULL));
- EXPECT_EQ(EVAL_FALSE, op_vp_null->Evaluate(&pp_num1, 1, NULL));
- EXPECT_EQ(EVAL_ERROR, op_vp_null->Evaluate(&pp_wrong1, 1, NULL));
-
- // Basic range test [41 43] (inclusive).
- PolicyOpcode* op_range1 = opcode_maker.MakeOpUlongMatchRange(0, 41, 43,
- kPolNone);
- EXPECT_EQ(EVAL_TRUE, op_range1->Evaluate(&pp_num1, 1, NULL));
- EXPECT_EQ(EVAL_FALSE, op_range1->Evaluate(&pp_num2, 1, NULL));
- EXPECT_EQ(EVAL_ERROR, op_range1->Evaluate(&pp_wrong1, 1, NULL));
-}
-
-TEST(PolicyEngineTest, LogicalOpcodes) {
- char memory[128];
- OpcodeFactory opcode_maker(memory, sizeof(memory));
-
- unsigned long num1 = 0x10100702;
- ParameterSet pp_num1 = ParamPickerMake(num1);
-
- PolicyOpcode* op_and1 = opcode_maker.MakeOpUlongAndMatch(0, 0x00100000,
- kPolNone);
- EXPECT_EQ(EVAL_TRUE, op_and1->Evaluate(&pp_num1, 1, NULL));
- PolicyOpcode* op_and2 = opcode_maker.MakeOpUlongAndMatch(0, 0x00000001,
- kPolNone);
- EXPECT_EQ(EVAL_FALSE, op_and2->Evaluate(&pp_num1, 1, NULL));
-}
-
-TEST(PolicyEngineTest, WCharOpcodes1) {
- SetupNtdllImports();
-
- const wchar_t* txt1 = L"the quick fox jumps over the lazy dog";
- const wchar_t txt2[] = L"the quick";
- const wchar_t txt3[] = L" fox jumps";
- const wchar_t txt4[] = L"the lazy dog";
- const wchar_t txt5[] = L"jumps over";
- const wchar_t txt6[] = L"g";
-
- ParameterSet pp_tc1 = ParamPickerMake(txt1);
- char memory[512];
- OpcodeFactory opcode_maker(memory, sizeof(memory));
-
- PolicyOpcode* op1 = opcode_maker.MakeOpWStringMatch(0, txt2, 0,
- CASE_SENSITIVE,
- kPolNone);
-
- // Simplest substring match from pos 0. It should be a successful match
- // and the match context should be updated.
- MatchContext mc1;
- EXPECT_EQ(EVAL_TRUE, op1->Evaluate(&pp_tc1, 1, &mc1));
- EXPECT_TRUE(_countof(txt2) == mc1.position + 1);
-
- // Matching again should fail and the context should be unmodified.
- EXPECT_EQ(EVAL_FALSE, op1->Evaluate(&pp_tc1, 1, &mc1));
- EXPECT_TRUE(_countof(txt2) == mc1.position + 1);
-
- // Using the same match context we should continue where we left
- // in the previous successful match,
- PolicyOpcode* op3 = opcode_maker.MakeOpWStringMatch(0, txt3, 0,
- CASE_SENSITIVE,
- kPolNone);
- EXPECT_EQ(EVAL_TRUE, op3->Evaluate(&pp_tc1, 1, &mc1));
- EXPECT_TRUE(_countof(txt3) + _countof(txt2) == mc1.position + 2);
-
- // We now keep on matching but now we skip 6 characters which means
- // we skip the string ' over '. And we zero the match context. This is
- // the primitive that we use to build '??'.
- PolicyOpcode* op4 = opcode_maker.MakeOpWStringMatch(0, txt4, 6,
- CASE_SENSITIVE,
- kPolClearContext);
- EXPECT_EQ(EVAL_TRUE, op4->Evaluate(&pp_tc1, 1, &mc1));
- EXPECT_EQ(0, mc1.position);
-
- // Test that we can properly match the last part of the string
- PolicyOpcode* op4b = opcode_maker.MakeOpWStringMatch(0, txt4, kSeekToEnd,
- CASE_SENSITIVE,
- kPolClearContext);
- EXPECT_EQ(EVAL_TRUE, op4b->Evaluate(&pp_tc1, 1, &mc1));
- EXPECT_EQ(0, mc1.position);
-
- // Test matching 'jumps over' over the entire string. This is the
- // primitive we build '*' from.
- PolicyOpcode* op5 = opcode_maker.MakeOpWStringMatch(0, txt5, kSeekForward,
- CASE_SENSITIVE, kPolNone);
- EXPECT_EQ(EVAL_TRUE, op5->Evaluate(&pp_tc1, 1, &mc1));
- EXPECT_EQ(24, mc1.position);
-
- // Test that we don't match because it is not at the end of the string
- PolicyOpcode* op5b = opcode_maker.MakeOpWStringMatch(0, txt5, kSeekToEnd,
- CASE_SENSITIVE,
- kPolNone);
- EXPECT_EQ(EVAL_FALSE, op5b->Evaluate(&pp_tc1, 1, &mc1));
-
- // Test that we function if the string does not fit. In this case we
- // try to match 'the lazy dog' against 'he lazy dog'.
- PolicyOpcode* op6 = opcode_maker.MakeOpWStringMatch(0, txt4, 2,
- CASE_SENSITIVE, kPolNone);
- EXPECT_EQ(24, mc1.position);
-
- // Testing matching against 'g' which should be the last char.
- MatchContext mc2;
- PolicyOpcode* op7 = opcode_maker.MakeOpWStringMatch(0, txt6, kSeekForward,
- CASE_SENSITIVE, kPolNone);
- EXPECT_EQ(EVAL_TRUE, op7->Evaluate(&pp_tc1, 1, &mc2));
-
- // Trying to match again should fail since we are in the last char.
- // This also covers a couple of boundary conditions.
- EXPECT_EQ(EVAL_FALSE, op7->Evaluate(&pp_tc1, 1, &mc2));
-}
-
-TEST(PolicyEngineTest, WCharOpcodes2) {
- SetupNtdllImports();
-
- const wchar_t* path1 = L"c:\\documents and settings\\Microsoft\\BLAH.txt";
- const wchar_t txt1[] = L"Settings\\microsoft";
- ParameterSet pp_tc1 = ParamPickerMake(path1);
-
- char memory[256];
- OpcodeFactory opcode_maker(memory, sizeof(memory));
- MatchContext mc1;
-
- // Testing case-insensitive does not buy us much since it this option
- // is just passed to the Microsoft API that we use normally, but just for
- // coverage, here it is:
- PolicyOpcode* op1s = opcode_maker.MakeOpWStringMatch(0, txt1, kSeekForward,
- CASE_SENSITIVE, kPolNone);
- PolicyOpcode* op1i = opcode_maker.MakeOpWStringMatch(0, txt1, kSeekForward,
- CASE_INSENSITIVE,
- kPolNone);
- EXPECT_EQ(EVAL_FALSE, op1s->Evaluate(&pp_tc1, 1, &mc1));
- EXPECT_EQ(EVAL_TRUE, op1i->Evaluate(&pp_tc1, 1, &mc1));
- EXPECT_EQ(35, mc1.position);
-}
-
-TEST(PolicyEngineTest, ActionOpcodes) {
- char memory[256];
- OpcodeFactory opcode_maker(memory, sizeof(memory));
- MatchContext mc1;
- void* dummy = NULL;
- ParameterSet ppb1 = ParamPickerMake(dummy);
-
- PolicyOpcode* op1 = opcode_maker.MakeOpAction(ASK_BROKER, kPolNone);
- EXPECT_TRUE(op1->IsAction());
- EXPECT_EQ(ASK_BROKER, op1->Evaluate(&ppb1, 1, &mc1));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/policy_params.h b/sandbox/win/src/policy_params.h
deleted file mode 100644
index 686d08f..0000000
--- a/sandbox/win/src/policy_params.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_POLICY_PARAMS_H__
-#define SANDBOX_SRC_POLICY_PARAMS_H__
-
-#include "sandbox/win/src/policy_engine_params.h"
-
-namespace sandbox {
-
-class ParameterSet;
-
-// Warning: The following macros store the address to the actual variables, in
-// other words, the values are not copied.
-#define POLPARAMS_BEGIN(type) class type { public: enum Args {
-#define POLPARAM(arg) arg,
-#define POLPARAMS_END(type) PolParamLast }; }; \
- typedef sandbox::ParameterSet type##Array [type::PolParamLast];
-
-// Policy parameters for file open / create.
-POLPARAMS_BEGIN(OpenFile)
- POLPARAM(NAME)
- POLPARAM(BROKER) // TRUE if called from the broker.
- POLPARAM(ACCESS)
- POLPARAM(OPTIONS)
-POLPARAMS_END(OpenFile)
-
-// Policy parameter for name-based policies.
-POLPARAMS_BEGIN(FileName)
- POLPARAM(NAME)
- POLPARAM(BROKER) // TRUE if called from the broker.
-POLPARAMS_END(FileName)
-
-COMPILE_ASSERT(OpenFile::NAME == FileName::NAME, to_simplify_fs_policies);
-COMPILE_ASSERT(OpenFile::BROKER == FileName::BROKER, to_simplify_fs_policies);
-
-// Policy parameter for name-based policies.
-POLPARAMS_BEGIN(NameBased)
- POLPARAM(NAME)
-POLPARAMS_END(NameBased)
-
-// Policy parameters for open event.
-POLPARAMS_BEGIN(OpenEventParams)
- POLPARAM(NAME)
- POLPARAM(ACCESS)
-POLPARAMS_END(OpenEventParams)
-
-// Policy Parameters for reg open / create.
-POLPARAMS_BEGIN(OpenKey)
- POLPARAM(NAME)
- POLPARAM(ACCESS)
-POLPARAMS_END(OpenKey)
-
-// Policy parameter for name-based policies.
-POLPARAMS_BEGIN(HandleTarget)
- POLPARAM(NAME)
- POLPARAM(TARGET)
-POLPARAMS_END(HandleTarget)
-
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_POLICY_PARAMS_H__
diff --git a/sandbox/win/src/policy_target.cc b/sandbox/win/src/policy_target.cc
deleted file mode 100644
index 84b7203..0000000
--- a/sandbox/win/src/policy_target.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/policy_target.h"
-
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_engine_processor.h"
-#include "sandbox/win/src/policy_low_level.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "sandbox/win/src/target_services.h"
-
-namespace sandbox {
-
-// Handle for our private heap.
-extern void* g_heap;
-
-// This is the list of all imported symbols from ntdll.dll.
-SANDBOX_INTERCEPT NtExports g_nt;
-
-// Policy data.
-extern void* volatile g_shared_policy_memory;
-SANDBOX_INTERCEPT size_t g_shared_policy_size;
-
-bool QueryBroker(int ipc_id, CountedParameterSetBase* params) {
- DCHECK_NT(static_cast<size_t>(ipc_id) < kMaxServiceCount);
- DCHECK_NT(g_shared_policy_memory);
- DCHECK_NT(g_shared_policy_size > 0);
-
- if (static_cast<size_t>(ipc_id) >= kMaxServiceCount)
- return false;
-
- PolicyGlobal* global_policy =
- reinterpret_cast<PolicyGlobal*>(g_shared_policy_memory);
-
- if (!global_policy->entry[ipc_id])
- return false;
-
- PolicyBuffer* policy = reinterpret_cast<PolicyBuffer*>(
- reinterpret_cast<char*>(g_shared_policy_memory) +
- reinterpret_cast<size_t>(global_policy->entry[ipc_id]));
-
- if ((reinterpret_cast<size_t>(global_policy->entry[ipc_id]) >
- global_policy->data_size) ||
- (g_shared_policy_size < global_policy->data_size)) {
- NOTREACHED_NT();
- return false;
- }
-
- for (int i = 0; i < params->count; i++) {
- if (!params->parameters[i].IsValid()) {
- NOTREACHED_NT();
- return false;
- }
- }
-
- PolicyProcessor processor(policy);
- PolicyResult result = processor.Evaluate(kShortEval, params->parameters,
- params->count);
- DCHECK_NT(POLICY_ERROR != result);
-
- return POLICY_MATCH == result && ASK_BROKER == processor.GetAction();
-}
-
-// -----------------------------------------------------------------------
-
-// Hooks NtSetInformationThread to block RevertToSelf from being
-// called before the actual call to LowerToken.
-NTSTATUS WINAPI TargetNtSetInformationThread(
- NtSetInformationThreadFunction orig_SetInformationThread, HANDLE thread,
- NT_THREAD_INFORMATION_CLASS thread_info_class, PVOID thread_information,
- ULONG thread_information_bytes) {
- do {
- if (SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf())
- break;
- if (ThreadImpersonationToken != thread_info_class)
- break;
- if (!thread_information)
- break;
- HANDLE token;
- if (sizeof(token) > thread_information_bytes)
- break;
-
- NTSTATUS ret = CopyData(&token, thread_information, sizeof(token));
- if (!NT_SUCCESS(ret) || NULL != token)
- break;
-
- // This is a revert to self.
- return STATUS_SUCCESS;
- } while (false);
-
- return orig_SetInformationThread(thread, thread_info_class,
- thread_information,
- thread_information_bytes);
-}
-
-// Hooks NtOpenThreadToken to force the open_as_self parameter to be set to
-// FALSE if we are still running with the impersonation token. open_as_self set
-// to TRUE means that the token will be open using the process token instead of
-// the impersonation token. This is bad because the process token does not have
-// access to open the thread token.
-NTSTATUS WINAPI TargetNtOpenThreadToken(
- NtOpenThreadTokenFunction orig_OpenThreadToken, HANDLE thread,
- ACCESS_MASK desired_access, BOOLEAN open_as_self, PHANDLE token) {
- if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf())
- open_as_self = FALSE;
-
- return orig_OpenThreadToken(thread, desired_access, open_as_self, token);
-}
-
-// See comment for TargetNtOpenThreadToken
-NTSTATUS WINAPI TargetNtOpenThreadTokenEx(
- NtOpenThreadTokenExFunction orig_OpenThreadTokenEx, HANDLE thread,
- ACCESS_MASK desired_access, BOOLEAN open_as_self, ULONG handle_attributes,
- PHANDLE token) {
- if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf())
- open_as_self = FALSE;
-
- return orig_OpenThreadTokenEx(thread, desired_access, open_as_self,
- handle_attributes, token);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/policy_target.h b/sandbox/win/src/policy_target.h
deleted file mode 100644
index 8a2b437..0000000
--- a/sandbox/win/src/policy_target.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-#ifndef SANDBOX_SRC_POLICY_TARGET_H__
-#define SANDBOX_SRC_POLICY_TARGET_H__
-
-namespace sandbox {
-
-struct CountedParameterSetBase;
-
-// Performs a policy lookup and returns true if the request should be passed to
-// the broker process.
-bool QueryBroker(int ipc_id, CountedParameterSetBase* params);
-
-extern "C" {
-
-// Interception of NtSetInformationThread on the child process.
-// It should never be called directly.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtSetInformationThread(
- NtSetInformationThreadFunction orig_SetInformationThread, HANDLE thread,
- NT_THREAD_INFORMATION_CLASS thread_info_class, PVOID thread_information,
- ULONG thread_information_bytes);
-
-// Interception of NtOpenThreadToken on the child process.
-// It should never be called directly
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenThreadToken(
- NtOpenThreadTokenFunction orig_OpenThreadToken, HANDLE thread,
- ACCESS_MASK desired_access, BOOLEAN open_as_self, PHANDLE token);
-
-// Interception of NtOpenThreadTokenEx on the child process.
-// It should never be called directly
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenThreadTokenEx(
- NtOpenThreadTokenExFunction orig_OpenThreadTokenEx, HANDLE thread,
- ACCESS_MASK desired_access, BOOLEAN open_as_self, ULONG handle_attributes,
- PHANDLE token);
-
-} // extern "C"
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_POLICY_TARGET_H__
diff --git a/sandbox/win/src/policy_target_test.cc b/sandbox/win/src/policy_target_test.cc
deleted file mode 100644
index ee28260..0000000
--- a/sandbox/win/src/policy_target_test.cc
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/win/scoped_process_information.h"
-#include "base/win/windows_version.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/sandbox_utils.h"
-#include "sandbox/win/src/target_services.h"
-#include "sandbox/win/tests/common/controller.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace sandbox {
-
-#define BINDNTDLL(name) \
- name ## Function name = reinterpret_cast<name ## Function>( \
- ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), #name))
-
-// Reverts to self and verify that SetInformationToken was faked. Returns
-// SBOX_TEST_SUCCEEDED if faked and SBOX_TEST_FAILED if not faked.
-SBOX_TESTS_COMMAND int PolicyTargetTest_token(int argc, wchar_t **argv) {
- HANDLE thread_token;
- // Get the thread token, using impersonation.
- if (!::OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE |
- TOKEN_DUPLICATE, FALSE, &thread_token))
- return ::GetLastError();
-
- ::RevertToSelf();
- ::CloseHandle(thread_token);
-
- int ret = SBOX_TEST_FAILED;
- if (::OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
- FALSE, &thread_token)) {
- ret = SBOX_TEST_SUCCEEDED;
- ::CloseHandle(thread_token);
- }
- return ret;
-}
-
-// Stores the high privilege token on a static variable, change impersonation
-// again to that one and verify that we are not interfering anymore with
-// RevertToSelf.
-SBOX_TESTS_COMMAND int PolicyTargetTest_steal(int argc, wchar_t **argv) {
- static HANDLE thread_token;
- if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf()) {
- if (!::OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE |
- TOKEN_DUPLICATE, FALSE, &thread_token))
- return ::GetLastError();
- } else {
- if (!::SetThreadToken(NULL, thread_token))
- return ::GetLastError();
-
- // See if we fake the call again.
- int ret = PolicyTargetTest_token(argc, argv);
- ::CloseHandle(thread_token);
- return ret;
- }
- return 0;
-}
-
-// Opens the thread token with and without impersonation.
-SBOX_TESTS_COMMAND int PolicyTargetTest_token2(int argc, wchar_t **argv) {
- HANDLE thread_token;
- // Get the thread token, using impersonation.
- if (!::OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE |
- TOKEN_DUPLICATE, FALSE, &thread_token))
- return ::GetLastError();
- ::CloseHandle(thread_token);
-
- // Get the thread token, without impersonation.
- if (!OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
- TRUE, &thread_token))
- return ::GetLastError();
- ::CloseHandle(thread_token);
- return SBOX_TEST_SUCCEEDED;
-}
-
-// Opens the thread token with and without impersonation, using
-// NtOpenThreadTokenEX.
-SBOX_TESTS_COMMAND int PolicyTargetTest_token3(int argc, wchar_t **argv) {
- BINDNTDLL(NtOpenThreadTokenEx);
- if (!NtOpenThreadTokenEx)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- HANDLE thread_token;
- // Get the thread token, using impersonation.
- NTSTATUS status = NtOpenThreadTokenEx(GetCurrentThread(),
- TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
- FALSE, 0, &thread_token);
- if (status == STATUS_NO_TOKEN)
- return ERROR_NO_TOKEN;
- if (!NT_SUCCESS(status))
- return SBOX_TEST_FAILED;
-
- ::CloseHandle(thread_token);
-
- // Get the thread token, without impersonation.
- status = NtOpenThreadTokenEx(GetCurrentThread(),
- TOKEN_IMPERSONATE | TOKEN_DUPLICATE, TRUE, 0,
- &thread_token);
- if (!NT_SUCCESS(status))
- return SBOX_TEST_FAILED;
-
- ::CloseHandle(thread_token);
- return SBOX_TEST_SUCCEEDED;
-}
-
-// Tests that we can open the current thread.
-SBOX_TESTS_COMMAND int PolicyTargetTest_thread(int argc, wchar_t **argv) {
- DWORD thread_id = ::GetCurrentThreadId();
- HANDLE thread = ::OpenThread(SYNCHRONIZE, FALSE, thread_id);
- if (!thread)
- return ::GetLastError();
- if (!::CloseHandle(thread))
- return ::GetLastError();
-
- return SBOX_TEST_SUCCEEDED;
-}
-
-// New thread entry point: do nothing.
-DWORD WINAPI PolicyTargetTest_thread_main(void* param) {
- ::Sleep(INFINITE);
- return 0;
-}
-
-// Tests that we can create a new thread, and open it.
-SBOX_TESTS_COMMAND int PolicyTargetTest_thread2(int argc, wchar_t **argv) {
- // Use default values to create a new thread.
- DWORD thread_id;
- HANDLE thread = ::CreateThread(NULL, 0, &PolicyTargetTest_thread_main, 0, 0,
- &thread_id);
- if (!thread)
- return ::GetLastError();
- if (!::CloseHandle(thread))
- return ::GetLastError();
-
- thread = ::OpenThread(SYNCHRONIZE, FALSE, thread_id);
- if (!thread)
- return ::GetLastError();
-
- if (!::CloseHandle(thread))
- return ::GetLastError();
-
- return SBOX_TEST_SUCCEEDED;
-}
-
-// Tests that we can call CreateProcess.
-SBOX_TESTS_COMMAND int PolicyTargetTest_process(int argc, wchar_t **argv) {
- // Use default values to create a new process.
- STARTUPINFO startup_info = {0};
- startup_info.cb = sizeof(startup_info);
- base::win::ScopedProcessInformation process_info;
- if (!::CreateProcessW(L"foo.exe", L"foo.exe", NULL, NULL, FALSE, 0,
- NULL, NULL, &startup_info, process_info.Receive()))
- return SBOX_TEST_SUCCEEDED;
- return SBOX_TEST_FAILED;
-}
-
-TEST(PolicyTargetTest, SetInformationThread) {
- TestRunner runner;
- if (base::win::GetVersion() >= base::win::VERSION_XP) {
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_token"));
- }
-
- runner.SetTestState(AFTER_REVERT);
- EXPECT_EQ(ERROR_NO_TOKEN, runner.RunTest(L"PolicyTargetTest_token"));
-
- runner.SetTestState(EVERY_STATE);
- if (base::win::GetVersion() >= base::win::VERSION_XP)
- EXPECT_EQ(SBOX_TEST_FAILED, runner.RunTest(L"PolicyTargetTest_steal"));
-}
-
-TEST(PolicyTargetTest, OpenThreadToken) {
- TestRunner runner;
- if (base::win::GetVersion() >= base::win::VERSION_XP) {
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_token2"));
- }
-
- runner.SetTestState(AFTER_REVERT);
- EXPECT_EQ(ERROR_NO_TOKEN, runner.RunTest(L"PolicyTargetTest_token2"));
-}
-
-TEST(PolicyTargetTest, OpenThreadTokenEx) {
- TestRunner runner;
- if (base::win::GetVersion() < base::win::VERSION_XP)
- return;
-
- runner.SetTestState(BEFORE_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_token3"));
-
- runner.SetTestState(AFTER_REVERT);
- EXPECT_EQ(ERROR_NO_TOKEN, runner.RunTest(L"PolicyTargetTest_token3"));
-}
-
-TEST(PolicyTargetTest, OpenThread) {
- TestRunner runner;
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_thread")) <<
- "Opens the current thread";
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_thread2")) <<
- "Creates a new thread and opens it";
-}
-
-TEST(PolicyTargetTest, OpenProcess) {
- TestRunner runner;
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"PolicyTargetTest_process")) <<
- "Opens a process";
-}
-
-// Launches the app in the sandbox and ask it to wait in an
-// infinite loop. Waits for 2 seconds and then check if the
-// desktop associated with the app thread is not the same as the
-// current desktop.
-TEST(PolicyTargetTest, DesktopPolicy) {
- BrokerServices* broker = GetBroker();
-
- // Precreate the desktop.
- TargetPolicy* temp_policy = broker->CreatePolicy();
- temp_policy->CreateAlternateDesktop(false);
- temp_policy->Release();
-
- ASSERT_TRUE(broker != NULL);
-
- // Get the path to the sandboxed app.
- wchar_t prog_name[MAX_PATH];
- GetModuleFileNameW(NULL, prog_name, MAX_PATH);
-
- std::wstring arguments(L"\"");
- arguments += prog_name;
- arguments += L"\" -child 0 wait"; // Don't care about the "state" argument.
-
- // Launch the app.
- ResultCode result = SBOX_ALL_OK;
- base::win::ScopedProcessInformation target;
-
- TargetPolicy* policy = broker->CreatePolicy();
- policy->SetAlternateDesktop(false);
- policy->SetTokenLevel(USER_INTERACTIVE, USER_LOCKDOWN);
- result = broker->SpawnTarget(prog_name, arguments.c_str(), policy,
- target.Receive());
- policy->Release();
-
- EXPECT_EQ(SBOX_ALL_OK, result);
-
- EXPECT_EQ(1, ::ResumeThread(target.thread_handle()));
-
- EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(target.process_handle(), 2000));
-
- EXPECT_NE(::GetThreadDesktop(target.thread_id()),
- ::GetThreadDesktop(::GetCurrentThreadId()));
-
- std::wstring desktop_name = policy->GetAlternateDesktop();
- HDESK desk = ::OpenDesktop(desktop_name.c_str(), 0, FALSE, DESKTOP_ENUMERATE);
- EXPECT_TRUE(NULL != desk);
- EXPECT_TRUE(::CloseDesktop(desk));
- EXPECT_TRUE(::TerminateProcess(target.process_handle(), 0));
-
- ::WaitForSingleObject(target.process_handle(), INFINITE);
-
- // Close the desktop handle.
- temp_policy = broker->CreatePolicy();
- temp_policy->DestroyAlternateDesktop();
- temp_policy->Release();
-
- // Make sure the desktop does not exist anymore.
- desk = ::OpenDesktop(desktop_name.c_str(), 0, FALSE, DESKTOP_ENUMERATE);
- EXPECT_TRUE(NULL == desk);
-}
-
-// Launches the app in the sandbox and ask it to wait in an
-// infinite loop. Waits for 2 seconds and then check if the
-// winstation associated with the app thread is not the same as the
-// current desktop.
-TEST(PolicyTargetTest, WinstaPolicy) {
- BrokerServices* broker = GetBroker();
-
- // Precreate the desktop.
- TargetPolicy* temp_policy = broker->CreatePolicy();
- temp_policy->CreateAlternateDesktop(true);
- temp_policy->Release();
-
- ASSERT_TRUE(broker != NULL);
-
- // Get the path to the sandboxed app.
- wchar_t prog_name[MAX_PATH];
- GetModuleFileNameW(NULL, prog_name, MAX_PATH);
-
- std::wstring arguments(L"\"");
- arguments += prog_name;
- arguments += L"\" -child 0 wait"; // Don't care about the "state" argument.
-
- // Launch the app.
- ResultCode result = SBOX_ALL_OK;
- base::win::ScopedProcessInformation target;
-
- TargetPolicy* policy = broker->CreatePolicy();
- policy->SetAlternateDesktop(true);
- policy->SetTokenLevel(USER_INTERACTIVE, USER_LOCKDOWN);
- result = broker->SpawnTarget(prog_name, arguments.c_str(), policy,
- target.Receive());
- policy->Release();
-
- EXPECT_EQ(SBOX_ALL_OK, result);
-
- EXPECT_EQ(1, ::ResumeThread(target.thread_handle()));
-
- EXPECT_EQ(WAIT_TIMEOUT, ::WaitForSingleObject(target.process_handle(), 2000));
-
- EXPECT_NE(::GetThreadDesktop(target.thread_id()),
- ::GetThreadDesktop(::GetCurrentThreadId()));
-
- std::wstring desktop_name = policy->GetAlternateDesktop();
- ASSERT_FALSE(desktop_name.empty());
-
- // Make sure there is a backslash, for the window station name.
- EXPECT_NE(desktop_name.find_first_of(L'\\'), std::wstring::npos);
-
- // Isolate the desktop name.
- desktop_name = desktop_name.substr(desktop_name.find_first_of(L'\\') + 1);
-
- HDESK desk = ::OpenDesktop(desktop_name.c_str(), 0, FALSE, DESKTOP_ENUMERATE);
- // This should fail if the desktop is really on another window station.
- EXPECT_FALSE(NULL != desk);
- EXPECT_TRUE(::TerminateProcess(target.process_handle(), 0));
-
- ::WaitForSingleObject(target.process_handle(), INFINITE);
-
- // Close the desktop handle.
- temp_policy = broker->CreatePolicy();
- temp_policy->DestroyAlternateDesktop();
- temp_policy->Release();
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/process_policy_test.cc b/sandbox/win/src/process_policy_test.cc
deleted file mode 100644
index 5e78a8a..0000000
--- a/sandbox/win/src/process_policy_test.cc
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <string>
-
-#include "base/sys_string_conversions.h"
-#include "base/win/scoped_handle.h"
-#include "base/win/scoped_process_information.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_policy.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/tests/common/controller.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-// While the shell API provides better calls than this home brew function
-// we use GetSystemWindowsDirectoryW which does not query the registry so
-// it is safe to use after revert.
-std::wstring MakeFullPathToSystem32(const wchar_t* name) {
- wchar_t windows_path[MAX_PATH] = {0};
- ::GetSystemWindowsDirectoryW(windows_path, MAX_PATH);
- std::wstring full_path(windows_path);
- if (full_path.empty()) {
- return full_path;
- }
- full_path += L"\\system32\\";
- full_path += name;
- return full_path;
-}
-
-// Creates a process with the |exe| and |command| parameter using the
-// unicode and ascii version of the api.
-sandbox::SboxTestResult CreateProcessHelper(const std::wstring &exe,
- const std::wstring &command) {
- base::win::ScopedProcessInformation pi;
- STARTUPINFOW si = {sizeof(si)};
-
- const wchar_t *exe_name = NULL;
- if (!exe.empty())
- exe_name = exe.c_str();
-
- const wchar_t *cmd_line = NULL;
- if (!command.empty())
- cmd_line = command.c_str();
-
- // Create the process with the unicode version of the API.
- sandbox::SboxTestResult ret1 = sandbox::SBOX_TEST_FAILED;
- if (!::CreateProcessW(exe_name, const_cast<wchar_t*>(cmd_line), NULL, NULL,
- FALSE, 0, NULL, NULL, &si, pi.Receive())) {
- DWORD last_error = GetLastError();
- if ((ERROR_NOT_ENOUGH_QUOTA == last_error) ||
- (ERROR_ACCESS_DENIED == last_error) ||
- (ERROR_FILE_NOT_FOUND == last_error)) {
- ret1 = sandbox::SBOX_TEST_DENIED;
- } else {
- ret1 = sandbox::SBOX_TEST_FAILED;
- }
- } else {
- ret1 = sandbox::SBOX_TEST_SUCCEEDED;
- }
-
- pi.Close();
-
- // Do the same with the ansi version of the api
- STARTUPINFOA sia = {sizeof(sia)};
- sandbox::SboxTestResult ret2 = sandbox::SBOX_TEST_FAILED;
-
- std::string narrow_cmd_line;
- if (cmd_line)
- narrow_cmd_line = base::SysWideToMultiByte(cmd_line, CP_UTF8);
- if (!::CreateProcessA(
- exe_name ? base::SysWideToMultiByte(exe_name, CP_UTF8).c_str() : NULL,
- cmd_line ? const_cast<char*>(narrow_cmd_line.c_str()) : NULL,
- NULL, NULL, FALSE, 0, NULL, NULL, &sia, pi.Receive())) {
- DWORD last_error = GetLastError();
- if ((ERROR_NOT_ENOUGH_QUOTA == last_error) ||
- (ERROR_ACCESS_DENIED == last_error) ||
- (ERROR_FILE_NOT_FOUND == last_error)) {
- ret2 = sandbox::SBOX_TEST_DENIED;
- } else {
- ret2 = sandbox::SBOX_TEST_FAILED;
- }
- } else {
- ret2 = sandbox::SBOX_TEST_SUCCEEDED;
- }
-
- if (ret1 == ret2)
- return ret1;
-
- return sandbox::SBOX_TEST_FAILED;
-}
-
-} // namespace
-
-namespace sandbox {
-
-// Tries to create the process in argv[0] using 7 different ways.
-// Since we also try the Ansi and Unicode version of the CreateProcess API,
-// The process referenced by argv[0] will be spawned 14 times.
-SBOX_TESTS_COMMAND int Process_RunApp(int argc, wchar_t **argv) {
- if (argc != 1) {
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
- }
- if ((NULL == argv) || (NULL == argv[0])) {
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
- }
- std::wstring path = MakeFullPathToSystem32(argv[0]);
-
- // TEST 1: Try with the path in the app_name.
- int result1 = CreateProcessHelper(path, std::wstring());
-
- // TEST 2: Try with the path in the cmd_line.
- std::wstring cmd_line = L"\"";
- cmd_line += path;
- cmd_line += L"\"";
- int result2 = CreateProcessHelper(std::wstring(), cmd_line);
-
- // TEST 3: Try file name in the cmd_line.
- int result3 = CreateProcessHelper(std::wstring(), argv[0]);
-
- // TEST 4: Try file name in the app_name and current directory sets correctly.
- std::wstring system32 = MakeFullPathToSystem32(L"");
- wchar_t current_directory[MAX_PATH + 1];
- int result4;
- bool test_succeeded = false;
- DWORD ret = ::GetCurrentDirectory(MAX_PATH, current_directory);
- if (0 != ret && ret < MAX_PATH) {
- current_directory[ret] = L'\\';
- current_directory[ret+1] = L'\0';
- if (::SetCurrentDirectory(system32.c_str())) {
- result4 = CreateProcessHelper(argv[0], std::wstring());
- if (::SetCurrentDirectory(current_directory)) {
- test_succeeded = true;
- }
- }
- }
- if (!test_succeeded)
- result4 = SBOX_TEST_FAILED;
-
- // TEST 5: Try with the path in the cmd_line and arguments.
- cmd_line = L"\"";
- cmd_line += path;
- cmd_line += L"\" /INSERT";
- int result5 = CreateProcessHelper(std::wstring(), cmd_line);
-
- // TEST 6: Try with the file_name in the cmd_line and arguments.
- cmd_line = argv[0];
- cmd_line += L" /INSERT";
- int result6 = CreateProcessHelper(std::wstring(), cmd_line);
-
- // TEST 7: Try with the path without the drive.
- cmd_line = path.substr(path.find(L'\\'));
- int result7 = CreateProcessHelper(std::wstring(), cmd_line);
-
- // Check if they all returned the same thing.
- if ((result1 == result2) && (result2 == result3) && (result3 == result4) &&
- (result4 == result5) && (result5 == result6) && (result6 == result7))
- return result1;
-
- return SBOX_TEST_FAILED;
-}
-
-// Creates a process and checks if it's possible to get a handle to it's token.
-SBOX_TESTS_COMMAND int Process_GetChildProcessToken(int argc, wchar_t **argv) {
- if (argc != 1)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- if ((NULL == argv) || (NULL == argv[0]))
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- std::wstring path = MakeFullPathToSystem32(argv[0]);
-
- base::win::ScopedProcessInformation pi;
- STARTUPINFOW si = {sizeof(si)};
-
- if (!::CreateProcessW(path.c_str(), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED,
- NULL, NULL, &si, pi.Receive())) {
- return SBOX_TEST_FAILED;
- }
-
- HANDLE token = NULL;
- BOOL result =
- ::OpenProcessToken(pi.process_handle(), TOKEN_IMPERSONATE, &token);
- DWORD error = ::GetLastError();
-
- base::win::ScopedHandle token_handle(token);
-
- if (!::TerminateProcess(pi.process_handle(), 0))
- return SBOX_TEST_FAILED;
-
- if (result && token)
- return SBOX_TEST_SUCCEEDED;
-
- if (ERROR_ACCESS_DENIED == error)
- return SBOX_TEST_DENIED;
-
- return SBOX_TEST_FAILED;
-}
-
-
-SBOX_TESTS_COMMAND int Process_OpenToken(int argc, wchar_t **argv) {
- HANDLE token;
- if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) {
- if (ERROR_ACCESS_DENIED == ::GetLastError()) {
- return SBOX_TEST_DENIED;
- }
- } else {
- ::CloseHandle(token);
- return SBOX_TEST_SUCCEEDED;
- }
-
- return SBOX_TEST_FAILED;
-}
-
-TEST(ProcessPolicyTest, TestAllAccess) {
- // Check if the "all access" rule fails to be added when the token is too
- // powerful.
- TestRunner runner;
-
- // Check the failing case.
- runner.GetPolicy()->SetTokenLevel(USER_INTERACTIVE, USER_LOCKDOWN);
- EXPECT_EQ(SBOX_ERROR_UNSUPPORTED,
- runner.GetPolicy()->AddRule(TargetPolicy::SUBSYS_PROCESS,
- TargetPolicy::PROCESS_ALL_EXEC,
- L"this is not important"));
-
- // Check the working case.
- runner.GetPolicy()->SetTokenLevel(USER_INTERACTIVE, USER_INTERACTIVE);
-
- EXPECT_EQ(SBOX_ALL_OK,
- runner.GetPolicy()->AddRule(TargetPolicy::SUBSYS_PROCESS,
- TargetPolicy::PROCESS_ALL_EXEC,
- L"this is not important"));
-}
-
-// This test is disabled. See bug 1305476.
-TEST(ProcessPolicyTest, DISABLED_RunFindstrExe) {
- TestRunner runner;
- std::wstring exe_path = MakeFullPathToSystem32(L"findstr.exe");
- std::wstring system32 = MakeFullPathToSystem32(L"");
- ASSERT_TRUE(!exe_path.empty());
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS,
- TargetPolicy::PROCESS_MIN_EXEC,
- exe_path.c_str()));
-
- // Need to add directory rules for the directories that we use in
- // SetCurrentDirectory.
- EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_DIR_ANY,
- system32.c_str()));
-
- wchar_t current_directory[MAX_PATH];
- DWORD ret = ::GetCurrentDirectory(MAX_PATH, current_directory);
- ASSERT_TRUE(0 != ret && ret < MAX_PATH);
-
- wcscat_s(current_directory, MAX_PATH, L"\\");
- EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_DIR_ANY,
- current_directory));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Process_RunApp findstr.exe"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp calc.exe"));
-}
-
-TEST(ProcessPolicyTest, OpenToken) {
- TestRunner runner;
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Process_OpenToken"));
-}
-
-TEST(ProcessPolicyTest, TestGetProcessTokenMinAccess) {
- TestRunner runner;
- std::wstring exe_path = MakeFullPathToSystem32(L"findstr.exe");
- ASSERT_TRUE(!exe_path.empty());
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS,
- TargetPolicy::PROCESS_MIN_EXEC,
- exe_path.c_str()));
-
- EXPECT_EQ(SBOX_TEST_DENIED,
- runner.RunTest(L"Process_GetChildProcessToken findstr.exe"));
-}
-
-TEST(ProcessPolicyTest, TestGetProcessTokenMaxAccess) {
- TestRunner runner(JOB_UNPROTECTED, USER_INTERACTIVE, USER_INTERACTIVE);
- std::wstring exe_path = MakeFullPathToSystem32(L"findstr.exe");
- ASSERT_TRUE(!exe_path.empty());
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS,
- TargetPolicy::PROCESS_ALL_EXEC,
- exe_path.c_str()));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED,
- runner.RunTest(L"Process_GetChildProcessToken findstr.exe"));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/process_thread_dispatcher.cc b/sandbox/win/src/process_thread_dispatcher.cc
deleted file mode 100644
index 2df203a..0000000
--- a/sandbox/win/src/process_thread_dispatcher.cc
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/process_thread_dispatcher.h"
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/interception.h"
-#include "sandbox/win/src/interceptors.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_broker.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/process_thread_interception.h"
-#include "sandbox/win/src/process_thread_policy.h"
-#include "sandbox/win/src/sandbox.h"
-
-namespace {
-
-// Extracts the application name from a command line.
-//
-// The application name is the first element of the command line. If
-// there is no quotes, the first element is delimited by the first space.
-// If there are quotes, the first element is delimited by the quotes.
-//
-// The create process call is smarter than us. It tries really hard to launch
-// the process even if the command line is wrong. For example:
-// "c:\program files\test param" will first try to launch c:\program.exe then
-// c:\program files\test.exe. We don't do that, we stop after at the first
-// space when there is no quotes.
-std::wstring GetPathFromCmdLine(const std::wstring &cmd_line) {
- std::wstring exe_name;
- // Check if it starts with '"'.
- if (cmd_line[0] == L'\"') {
- // Find the position of the second '"', this terminates the path.
- std::wstring::size_type pos = cmd_line.find(L'\"', 1);
- if (std::wstring::npos == pos)
- return cmd_line;
- exe_name = cmd_line.substr(1, pos - 1);
- } else {
- // There is no '"', that means that the appname is terminated at the
- // first space.
- std::wstring::size_type pos = cmd_line.find(L' ');
- if (std::wstring::npos == pos) {
- // There is no space, the cmd_line contains only the app_name
- exe_name = cmd_line;
- } else {
- exe_name = cmd_line.substr(0, pos);
- }
- }
-
- return exe_name;
-}
-
-// Returns true is the path in parameter is relative. False if it's
-// absolute.
-bool IsPathRelative(const std::wstring &path) {
- // A path is Relative if it's not a UNC path beginnning with \\ or a
- // path beginning with a drive. (i.e. X:\)
- if (path.find(L"\\\\") == 0 || path.find(L":\\") == 1)
- return false;
- return true;
-}
-
-// Converts a relative path to an absolute path.
-bool ConvertToAbsolutePath(const std::wstring child_current_directory,
- bool use_env_path, std::wstring *path) {
- wchar_t file_buffer[MAX_PATH];
- wchar_t *file_part = NULL;
-
- // Here we should start by looking at the path where the child application was
- // started. We don't have this information yet.
- DWORD result = 0;
- if (use_env_path) {
- // Try with the complete path
- result = ::SearchPath(NULL, path->c_str(), NULL, MAX_PATH, file_buffer,
- &file_part);
- }
-
- if (0 == result) {
- // Try with the current directory of the child
- result = ::SearchPath(child_current_directory.c_str(), path->c_str(), NULL,
- MAX_PATH, file_buffer, &file_part);
- }
-
- if (0 == result || result >= MAX_PATH)
- return false;
-
- *path = file_buffer;
- return true;
-}
-
-} // namespace
-namespace sandbox {
-
-ThreadProcessDispatcher::ThreadProcessDispatcher(PolicyBase* policy_base)
- : policy_base_(policy_base) {
- static const IPCCall open_thread = {
- {IPC_NTOPENTHREAD_TAG, ULONG_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(
- &ThreadProcessDispatcher::NtOpenThread)
- };
-
- static const IPCCall open_process = {
- {IPC_NTOPENPROCESS_TAG, ULONG_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(
- &ThreadProcessDispatcher::NtOpenProcess)
- };
-
- static const IPCCall process_token = {
- {IPC_NTOPENPROCESSTOKEN_TAG, VOIDPTR_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(
- &ThreadProcessDispatcher::NtOpenProcessToken)
- };
-
- static const IPCCall process_tokenex = {
- {IPC_NTOPENPROCESSTOKENEX_TAG, VOIDPTR_TYPE, ULONG_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(
- &ThreadProcessDispatcher::NtOpenProcessTokenEx)
- };
-
- static const IPCCall create_params = {
- {IPC_CREATEPROCESSW_TAG, WCHAR_TYPE, WCHAR_TYPE, WCHAR_TYPE, INOUTPTR_TYPE},
- reinterpret_cast<CallbackGeneric>(
- &ThreadProcessDispatcher::CreateProcessW)
- };
-
- ipc_calls_.push_back(open_thread);
- ipc_calls_.push_back(open_process);
- ipc_calls_.push_back(process_token);
- ipc_calls_.push_back(process_tokenex);
- ipc_calls_.push_back(create_params);
-}
-
-bool ThreadProcessDispatcher::SetupService(InterceptionManager* manager,
- int service) {
- switch (service) {
- case IPC_NTOPENTHREAD_TAG:
- case IPC_NTOPENPROCESS_TAG:
- case IPC_NTOPENPROCESSTOKEN_TAG:
- case IPC_NTOPENPROCESSTOKENEX_TAG:
- // There is no explicit policy for these services.
- NOTREACHED();
- return false;
-
- case IPC_CREATEPROCESSW_TAG:
- return INTERCEPT_EAT(manager, L"kernel32.dll", CreateProcessW,
- CREATE_PROCESSW_ID, 44) &&
- INTERCEPT_EAT(manager, L"kernel32.dll", CreateProcessA,
- CREATE_PROCESSA_ID, 44);
-
- default:
- return false;
- }
-}
-
-bool ThreadProcessDispatcher::NtOpenThread(IPCInfo* ipc, DWORD desired_access,
- DWORD thread_id) {
- HANDLE handle;
- NTSTATUS ret = ProcessPolicy::OpenThreadAction(*ipc->client_info,
- desired_access, thread_id,
- &handle);
- ipc->return_info.nt_status = ret;
- ipc->return_info.handle = handle;
- return true;
-}
-
-bool ThreadProcessDispatcher::NtOpenProcess(IPCInfo* ipc, DWORD desired_access,
- DWORD process_id) {
- HANDLE handle;
- NTSTATUS ret = ProcessPolicy::OpenProcessAction(*ipc->client_info,
- desired_access, process_id,
- &handle);
- ipc->return_info.nt_status = ret;
- ipc->return_info.handle = handle;
- return true;
-}
-
-bool ThreadProcessDispatcher::NtOpenProcessToken(IPCInfo* ipc, HANDLE process,
- DWORD desired_access) {
- HANDLE handle;
- NTSTATUS ret = ProcessPolicy::OpenProcessTokenAction(*ipc->client_info,
- process, desired_access,
- &handle);
- ipc->return_info.nt_status = ret;
- ipc->return_info.handle = handle;
- return true;
-}
-
-bool ThreadProcessDispatcher::NtOpenProcessTokenEx(IPCInfo* ipc, HANDLE process,
- DWORD desired_access,
- DWORD attributes) {
- HANDLE handle;
- NTSTATUS ret = ProcessPolicy::OpenProcessTokenExAction(*ipc->client_info,
- process,
- desired_access,
- attributes, &handle);
- ipc->return_info.nt_status = ret;
- ipc->return_info.handle = handle;
- return true;
-}
-
-bool ThreadProcessDispatcher::CreateProcessW(IPCInfo* ipc, std::wstring* name,
- std::wstring* cmd_line,
- std::wstring* cur_dir,
- CountedBuffer* info) {
- if (sizeof(PROCESS_INFORMATION) != info->Size())
- return false;
-
- // Check if there is an application name.
- std::wstring exe_name;
- if (!name->empty())
- exe_name = *name;
- else
- exe_name = GetPathFromCmdLine(*cmd_line);
-
- if (IsPathRelative(exe_name)) {
- if (!ConvertToAbsolutePath(*cur_dir, name->empty(), &exe_name)) {
- // Cannot find the path. Maybe the file does not exist.
- ipc->return_info.win32_result = ERROR_FILE_NOT_FOUND;
- return true;
- }
- }
-
- const wchar_t* const_exe_name = exe_name.c_str();
- CountedParameterSet<NameBased> params;
- params[NameBased::NAME] = ParamPickerMake(const_exe_name);
-
- EvalResult eval = policy_base_->EvalPolicy(IPC_CREATEPROCESSW_TAG,
- params.GetBase());
-
- PROCESS_INFORMATION* proc_info =
- reinterpret_cast<PROCESS_INFORMATION*>(info->Buffer());
- // Here we force the app_name to be the one we used for the policy lookup.
- // If our logic was wrong, at least we wont allow create a random process.
- DWORD ret = ProcessPolicy::CreateProcessWAction(eval, *ipc->client_info,
- exe_name, *cmd_line,
- proc_info);
-
- ipc->return_info.win32_result = ret;
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/process_thread_dispatcher.h b/sandbox/win/src/process_thread_dispatcher.h
deleted file mode 100644
index 1cc5743..0000000
--- a/sandbox/win/src/process_thread_dispatcher.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_PROCESS_THREAD_DISPATCHER_H_
-#define SANDBOX_SRC_PROCESS_THREAD_DISPATCHER_H_
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/sandbox_policy_base.h"
-
-namespace sandbox {
-
-// This class handles process and thread-related IPC calls.
-class ThreadProcessDispatcher : public Dispatcher {
- public:
- explicit ThreadProcessDispatcher(PolicyBase* policy_base);
- ~ThreadProcessDispatcher() {}
-
- // Dispatcher interface.
- virtual bool SetupService(InterceptionManager* manager, int service);
-
- private:
- // Processes IPC requests coming from calls to NtOpenThread() in the target.
- bool NtOpenThread(IPCInfo* ipc, DWORD desired_access, DWORD thread_id);
-
- // Processes IPC requests coming from calls to NtOpenProcess() in the target.
- bool NtOpenProcess(IPCInfo* ipc, DWORD desired_access, DWORD process_id);
-
- // Processes IPC requests from calls to NtOpenProcessToken() in the target.
- bool NtOpenProcessToken(IPCInfo* ipc, HANDLE process, DWORD desired_access);
-
- // Processes IPC requests from calls to NtOpenProcessTokenEx() in the target.
- bool NtOpenProcessTokenEx(IPCInfo* ipc, HANDLE process, DWORD desired_access,
- DWORD attributes);
-
- // Processes IPC requests coming from calls to CreateProcessW() in the target.
- bool CreateProcessW(IPCInfo* ipc, std::wstring* name, std::wstring* cmd_line,
- std::wstring* cur_dir, CountedBuffer* info);
-
- PolicyBase* policy_base_;
- DISALLOW_COPY_AND_ASSIGN(ThreadProcessDispatcher);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_PROCESS_THREAD_DISPATCHER_H_
diff --git a/sandbox/win/src/process_thread_interception.cc b/sandbox/win/src/process_thread_interception.cc
deleted file mode 100644
index cb1017b..0000000
--- a/sandbox/win/src/process_thread_interception.cc
+++ /dev/null
@@ -1,447 +0,0 @@
-// Copyright (c) 2006-2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/process_thread_interception.h"
-
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/policy_target.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "sandbox/win/src/target_services.h"
-
-namespace sandbox {
-
-SANDBOX_INTERCEPT NtExports g_nt;
-
-// Hooks NtOpenThread and proxy the call to the broker if it's trying to
-// open a thread in the same process.
-NTSTATUS WINAPI TargetNtOpenThread(NtOpenThreadFunction orig_OpenThread,
- PHANDLE thread, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes,
- PCLIENT_ID client_id) {
- NTSTATUS status = orig_OpenThread(thread, desired_access, object_attributes,
- client_id);
- if (NT_SUCCESS(status))
- return status;
-
- do {
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- break;
- if (!client_id)
- break;
-
- uint32 thread_id = 0;
- bool should_break = false;
- __try {
- // We support only the calls for the current process
- if (NULL != client_id->UniqueProcess)
- should_break = true;
-
- // Object attributes should be NULL or empty.
- if (!should_break && NULL != object_attributes) {
- if (0 != object_attributes->Attributes ||
- NULL != object_attributes->ObjectName ||
- NULL != object_attributes->RootDirectory ||
- NULL != object_attributes->SecurityDescriptor ||
- NULL != object_attributes->SecurityQualityOfService) {
- should_break = true;
- }
- }
-
- thread_id = static_cast<uint32>(
- reinterpret_cast<ULONG_PTR>(client_id->UniqueThread));
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- break;
- }
-
- if (should_break)
- break;
-
- if (!ValidParameter(thread, sizeof(HANDLE), WRITE))
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_NTOPENTHREAD_TAG, desired_access,
- thread_id, &answer);
- if (SBOX_ALL_OK != code)
- break;
-
- if (!NT_SUCCESS(answer.nt_status))
- // The nt_status here is most likely STATUS_INVALID_CID because
- // in the broker we set the process id in the CID (client ID) param
- // to be the current process. If you try to open a thread from another
- // process you will get this INVALID_CID error. On the other hand, if you
- // try to open a thread in your own process, it should return success.
- // We don't want to return STATUS_INVALID_CID here, so we return the
- // return of the original open thread status, which is most likely
- // STATUS_ACCESS_DENIED.
- break;
-
- __try {
- // Write the output parameters.
- *thread = answer.handle;
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- break;
- }
-
- return answer.nt_status;
- } while (false);
-
- return status;
-}
-
-// Hooks NtOpenProcess and proxy the call to the broker if it's trying to
-// open the current process.
-NTSTATUS WINAPI TargetNtOpenProcess(NtOpenProcessFunction orig_OpenProcess,
- PHANDLE process, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes,
- PCLIENT_ID client_id) {
- NTSTATUS status = orig_OpenProcess(process, desired_access, object_attributes,
- client_id);
- if (NT_SUCCESS(status))
- return status;
-
- do {
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- break;
- if (!client_id)
- break;
-
- uint32 process_id = 0;
- bool should_break = false;
- __try {
- // Object attributes should be NULL or empty.
- if (!should_break && NULL != object_attributes) {
- if (0 != object_attributes->Attributes ||
- NULL != object_attributes->ObjectName ||
- NULL != object_attributes->RootDirectory ||
- NULL != object_attributes->SecurityDescriptor ||
- NULL != object_attributes->SecurityQualityOfService) {
- should_break = true;
- }
- }
-
- process_id = static_cast<uint32>(
- reinterpret_cast<ULONG_PTR>(client_id->UniqueProcess));
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- break;
- }
-
- if (should_break)
- break;
-
- if (!ValidParameter(process, sizeof(HANDLE), WRITE))
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESS_TAG, desired_access,
- process_id, &answer);
- if (SBOX_ALL_OK != code)
- break;
-
- if (!NT_SUCCESS(answer.nt_status))
- return answer.nt_status;
-
- __try {
- // Write the output parameters.
- *process = answer.handle;
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- break;
- }
-
- return answer.nt_status;
- } while (false);
-
- return status;
-}
-
-
-NTSTATUS WINAPI TargetNtOpenProcessToken(
- NtOpenProcessTokenFunction orig_OpenProcessToken, HANDLE process,
- ACCESS_MASK desired_access, PHANDLE token) {
- NTSTATUS status = orig_OpenProcessToken(process, desired_access, token);
- if (NT_SUCCESS(status))
- return status;
-
- do {
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- break;
-
- if (CURRENT_PROCESS != process)
- break;
-
- if (!ValidParameter(token, sizeof(HANDLE), WRITE))
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESSTOKEN_TAG, process,
- desired_access, &answer);
- if (SBOX_ALL_OK != code)
- break;
-
- if (!NT_SUCCESS(answer.nt_status))
- return answer.nt_status;
-
- __try {
- // Write the output parameters.
- *token = answer.handle;
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- break;
- }
-
- return answer.nt_status;
- } while (false);
-
- return status;
-}
-
-NTSTATUS WINAPI TargetNtOpenProcessTokenEx(
- NtOpenProcessTokenExFunction orig_OpenProcessTokenEx, HANDLE process,
- ACCESS_MASK desired_access, ULONG handle_attributes, PHANDLE token) {
- NTSTATUS status = orig_OpenProcessTokenEx(process, desired_access,
- handle_attributes, token);
- if (NT_SUCCESS(status))
- return status;
-
- do {
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- break;
-
- if (CURRENT_PROCESS != process)
- break;
-
- if (!ValidParameter(token, sizeof(HANDLE), WRITE))
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESSTOKENEX_TAG, process,
- desired_access, handle_attributes, &answer);
- if (SBOX_ALL_OK != code)
- break;
-
- if (!NT_SUCCESS(answer.nt_status))
- return answer.nt_status;
-
- __try {
- // Write the output parameters.
- *token = answer.handle;
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- break;
- }
-
- return answer.nt_status;
- } while (false);
-
- return status;
-}
-
-BOOL WINAPI TargetCreateProcessW(CreateProcessWFunction orig_CreateProcessW,
- LPCWSTR application_name, LPWSTR command_line,
- LPSECURITY_ATTRIBUTES process_attributes,
- LPSECURITY_ATTRIBUTES thread_attributes,
- BOOL inherit_handles, DWORD flags,
- LPVOID environment, LPCWSTR current_directory,
- LPSTARTUPINFOW startup_info,
- LPPROCESS_INFORMATION process_information) {
- if (orig_CreateProcessW(application_name, command_line, process_attributes,
- thread_attributes, inherit_handles, flags,
- environment, current_directory, startup_info,
- process_information)) {
- return TRUE;
- }
- DWORD original_error = ::GetLastError();
-
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return FALSE;
-
- do {
- if (!ValidParameter(process_information, sizeof(PROCESS_INFORMATION),
- WRITE))
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- const wchar_t* cur_dir = NULL;
-
- wchar_t current_directory[MAX_PATH];
- DWORD result = ::GetCurrentDirectory(MAX_PATH, current_directory);
- if (0 != result && result < MAX_PATH)
- cur_dir = current_directory;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
-
- InOutCountedBuffer proc_info(process_information,
- sizeof(PROCESS_INFORMATION));
-
- ResultCode code = CrossCall(ipc, IPC_CREATEPROCESSW_TAG, application_name,
- command_line, cur_dir, proc_info, &answer);
- if (SBOX_ALL_OK != code)
- break;
-
- ::SetLastError(answer.win32_result);
- if (ERROR_SUCCESS != answer.win32_result)
- return FALSE;
-
- return TRUE;
- } while (false);
-
- ::SetLastError(original_error);
- return FALSE;
-}
-
-BOOL WINAPI TargetCreateProcessA(CreateProcessAFunction orig_CreateProcessA,
- LPCSTR application_name, LPSTR command_line,
- LPSECURITY_ATTRIBUTES process_attributes,
- LPSECURITY_ATTRIBUTES thread_attributes,
- BOOL inherit_handles, DWORD flags,
- LPVOID environment, LPCSTR current_directory,
- LPSTARTUPINFOA startup_info,
- LPPROCESS_INFORMATION process_information) {
- if (orig_CreateProcessA(application_name, command_line, process_attributes,
- thread_attributes, inherit_handles, flags,
- environment, current_directory, startup_info,
- process_information)) {
- return TRUE;
- }
- DWORD original_error = ::GetLastError();
-
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return FALSE;
-
- do {
- if (!ValidParameter(process_information, sizeof(PROCESS_INFORMATION),
- WRITE))
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- // Convert the input params to unicode.
- UNICODE_STRING *cmd_unicode = NULL;
- UNICODE_STRING *app_unicode = NULL;
- if (command_line) {
- cmd_unicode = AnsiToUnicode(command_line);
- if (!cmd_unicode)
- break;
- }
-
- if (application_name) {
- app_unicode = AnsiToUnicode(application_name);
- if (!app_unicode) {
- operator delete(cmd_unicode, NT_ALLOC);
- break;
- }
- }
-
- const wchar_t* cmd_line = cmd_unicode ? cmd_unicode->Buffer : NULL;
- const wchar_t* app_name = app_unicode ? app_unicode->Buffer : NULL;
- const wchar_t* cur_dir = NULL;
-
- wchar_t current_directory[MAX_PATH];
- DWORD result = ::GetCurrentDirectory(MAX_PATH, current_directory);
- if (0 != result && result < MAX_PATH)
- cur_dir = current_directory;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
-
- InOutCountedBuffer proc_info(process_information,
- sizeof(PROCESS_INFORMATION));
-
- ResultCode code = CrossCall(ipc, IPC_CREATEPROCESSW_TAG, app_name,
- cmd_line, cur_dir, proc_info, &answer);
-
- operator delete(cmd_unicode, NT_ALLOC);
- operator delete(app_unicode, NT_ALLOC);
-
- if (SBOX_ALL_OK != code)
- break;
-
- ::SetLastError(answer.win32_result);
- if (ERROR_SUCCESS != answer.win32_result)
- return FALSE;
-
- return TRUE;
- } while (false);
-
- ::SetLastError(original_error);
- return FALSE;
-}
-
-// Creates a thread without registering with CSRSS. This is required if we
-// closed the CSRSS ALPC port after lockdown.
-HANDLE WINAPI TargetCreateThread(CreateThreadFunction orig_CreateThread,
- LPSECURITY_ATTRIBUTES thread_attributes,
- SIZE_T stack_size,
- LPTHREAD_START_ROUTINE start_address,
- PVOID parameter,
- DWORD creation_flags,
- LPDWORD thread_id) {
-// Try the normal CreateThread; switch to RtlCreateUserThread if needed.
- static bool use_create_thread = true;
- HANDLE thread;
- if (use_create_thread) {
- thread = orig_CreateThread(thread_attributes, stack_size, start_address,
- parameter, creation_flags, thread_id);
- if (thread)
- return thread;
- }
-
- PSECURITY_DESCRIPTOR sd =
- thread_attributes ? thread_attributes->lpSecurityDescriptor : NULL;
- CLIENT_ID client_id;
-
- NTSTATUS result = g_nt.RtlCreateUserThread(NtCurrentProcess, sd,
- creation_flags & CREATE_SUSPENDED,
- 0, stack_size, 0, start_address,
- parameter, &thread, &client_id);
- if (!NT_SUCCESS(result))
- return 0;
-
- // CSRSS is closed if we got here, so use RtlCreateUserThread from here on.
- use_create_thread = false;
- if (thread_id)
- *thread_id = HandleToUlong(client_id.UniqueThread);
- return thread;
-}
-
-// Cache the default LCID to avoid pinging CSRSS after lockdown.
-// TODO(jschuh): This approach will miss a default locale changes after
-// lockdown. In the future we may want to have the broker check instead.
-LCID WINAPI TargetGetUserDefaultLCID(
- GetUserDefaultLCIDFunction orig_GetUserDefaultLCID) {
- static LCID default_lcid = orig_GetUserDefaultLCID();
- return default_lcid;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/process_thread_interception.h b/sandbox/win/src/process_thread_interception.h
deleted file mode 100644
index 7d2d533..0000000
--- a/sandbox/win/src/process_thread_interception.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2006-2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-#ifndef SANDBOX_SRC_PROCESS_THREAD_INTERCEPTION_H__
-#define SANDBOX_SRC_PROCESS_THREAD_INTERCEPTION_H__
-
-namespace sandbox {
-
-extern "C" {
-
-typedef BOOL (WINAPI *CreateProcessWFunction)(
- LPCWSTR lpApplicationName,
- LPWSTR lpCommandLine,
- LPSECURITY_ATTRIBUTES lpProcessAttributes,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- BOOL bInheritHandles,
- DWORD dwCreationFlags,
- LPVOID lpEnvironment,
- LPCWSTR lpCurrentDirectory,
- LPSTARTUPINFOW lpStartupInfo,
- LPPROCESS_INFORMATION lpProcessInformation);
-
-typedef BOOL (WINAPI *CreateProcessAFunction)(
- LPCSTR lpApplicationName,
- LPSTR lpCommandLine,
- LPSECURITY_ATTRIBUTES lpProcessAttributes,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- BOOL bInheritHandles,
- DWORD dwCreationFlags,
- LPVOID lpEnvironment,
- LPCSTR lpCurrentDirectory,
- LPSTARTUPINFOA lpStartupInfo,
- LPPROCESS_INFORMATION lpProcessInformation);
-
-typedef HANDLE (WINAPI *CreateThreadFunction)(
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- SIZE_T dwStackSize,
- LPTHREAD_START_ROUTINE lpStartAddress,
- PVOID lpParameter,
- DWORD dwCreationFlags,
- LPDWORD lpThreadId);
-
-typedef LCID (WINAPI *GetUserDefaultLCIDFunction)();
-
-// Interception of NtOpenThread on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenThread(
- NtOpenThreadFunction orig_OpenThread, PHANDLE thread,
- ACCESS_MASK desired_access, POBJECT_ATTRIBUTES object_attributes,
- PCLIENT_ID client_id);
-
-// Interception of NtOpenProcess on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenProcess(
- NtOpenProcessFunction orig_OpenProcess, PHANDLE process,
- ACCESS_MASK desired_access, POBJECT_ATTRIBUTES object_attributes,
- PCLIENT_ID client_id);
-
-// Interception of NtOpenProcessToken on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenProcessToken(
- NtOpenProcessTokenFunction orig_OpenProcessToken, HANDLE process,
- ACCESS_MASK desired_access, PHANDLE token);
-
-// Interception of NtOpenProcessTokenEx on the child process.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenProcessTokenEx(
- NtOpenProcessTokenExFunction orig_OpenProcessTokenEx, HANDLE process,
- ACCESS_MASK desired_access, ULONG handle_attributes, PHANDLE token);
-
-// Interception of CreateProcessW and A in kernel32.dll.
-SANDBOX_INTERCEPT BOOL WINAPI TargetCreateProcessW(
- CreateProcessWFunction orig_CreateProcessW, LPCWSTR application_name,
- LPWSTR command_line, LPSECURITY_ATTRIBUTES process_attributes,
- LPSECURITY_ATTRIBUTES thread_attributes, BOOL inherit_handles, DWORD flags,
- LPVOID environment, LPCWSTR current_directory, LPSTARTUPINFOW startup_info,
- LPPROCESS_INFORMATION process_information);
-
-SANDBOX_INTERCEPT BOOL WINAPI TargetCreateProcessA(
- CreateProcessAFunction orig_CreateProcessA, LPCSTR application_name,
- LPSTR command_line, LPSECURITY_ATTRIBUTES process_attributes,
- LPSECURITY_ATTRIBUTES thread_attributes, BOOL inherit_handles, DWORD flags,
- LPVOID environment, LPCSTR current_directory, LPSTARTUPINFOA startup_info,
- LPPROCESS_INFORMATION process_information);
-
-// Interception of CreateThread in kernel32.dll.
-SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateThread(
- CreateThreadFunction orig_CreateThread,
- LPSECURITY_ATTRIBUTES thread_attributes, SIZE_T stack_size,
- LPTHREAD_START_ROUTINE start_address, PVOID parameter,
- DWORD creation_flags, LPDWORD thread_id);
-
-// Interception of GetUserDefaultLCID in kernel32.dll.
-SANDBOX_INTERCEPT LCID WINAPI TargetGetUserDefaultLCID(
- GetUserDefaultLCIDFunction orig_GetUserDefaultLCID);
-
-} // extern "C"
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_PROCESS_THREAD_INTERCEPTION_H__
diff --git a/sandbox/win/src/process_thread_policy.cc b/sandbox/win/src/process_thread_policy.cc
deleted file mode 100644
index 9493b9e..0000000
--- a/sandbox/win/src/process_thread_policy.cc
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/process_thread_policy.h"
-
-#include <string>
-
-#include "base/memory/scoped_ptr.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/policy_engine_opcodes.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace {
-
-// These are the only safe rights that can be given to a sandboxed
-// process for the process created by the broker. All others are potential
-// vectors of privilege elevation.
-const DWORD kProcessRights = SYNCHRONIZE |
- PROCESS_QUERY_INFORMATION |
- PROCESS_QUERY_LIMITED_INFORMATION |
- PROCESS_TERMINATE |
- PROCESS_SUSPEND_RESUME;
-
-const DWORD kThreadRights = SYNCHRONIZE |
- THREAD_TERMINATE |
- THREAD_SUSPEND_RESUME |
- THREAD_QUERY_INFORMATION |
- THREAD_QUERY_LIMITED_INFORMATION |
- THREAD_SET_LIMITED_INFORMATION;
-
-// Creates a child process and duplicates the handles to 'target_process'. The
-// remaining parameters are the same as CreateProcess().
-BOOL CreateProcessExWHelper(HANDLE target_process, BOOL give_full_access,
- LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
- LPSECURITY_ATTRIBUTES lpProcessAttributes,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- BOOL bInheritHandles, DWORD dwCreationFlags,
- LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory,
- LPSTARTUPINFOW lpStartupInfo,
- LPPROCESS_INFORMATION lpProcessInformation) {
- if (!::CreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes,
- lpThreadAttributes, bInheritHandles, dwCreationFlags,
- lpEnvironment, lpCurrentDirectory, lpStartupInfo,
- lpProcessInformation)) {
- return FALSE;
- }
-
- DWORD process_access = kProcessRights;
- DWORD thread_access = kThreadRights;
- if (give_full_access) {
- process_access = PROCESS_ALL_ACCESS;
- thread_access = THREAD_ALL_ACCESS;
- }
- if (!::DuplicateHandle(::GetCurrentProcess(), lpProcessInformation->hProcess,
- target_process, &lpProcessInformation->hProcess,
- process_access, FALSE, DUPLICATE_CLOSE_SOURCE)) {
- ::CloseHandle(lpProcessInformation->hThread);
- return FALSE;
- }
- if (!::DuplicateHandle(::GetCurrentProcess(), lpProcessInformation->hThread,
- target_process, &lpProcessInformation->hThread,
- thread_access, FALSE, DUPLICATE_CLOSE_SOURCE)) {
- return FALSE;
- }
- return TRUE;
-}
-
-}
-
-namespace sandbox {
-
-bool ProcessPolicy::GenerateRules(const wchar_t* name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy) {
- scoped_ptr<PolicyRule> process;
- switch (semantics) {
- case TargetPolicy::PROCESS_MIN_EXEC: {
- process.reset(new PolicyRule(GIVE_READONLY));
- break;
- };
- case TargetPolicy::PROCESS_ALL_EXEC: {
- process.reset(new PolicyRule(GIVE_ALLACCESS));
- break;
- };
- default: {
- return false;
- };
- }
-
- if (!process->AddStringMatch(IF, NameBased::NAME, name, CASE_INSENSITIVE)) {
- return false;
- }
- if (!policy->AddRule(IPC_CREATEPROCESSW_TAG, process.get())) {
- return false;
- }
- return true;
-}
-
-NTSTATUS ProcessPolicy::OpenThreadAction(const ClientInfo& client_info,
- uint32 desired_access,
- uint32 thread_id,
- HANDLE* handle) {
- *handle = NULL;
-
- NtOpenThreadFunction NtOpenThread = NULL;
- ResolveNTFunctionPtr("NtOpenThread", &NtOpenThread);
-
- OBJECT_ATTRIBUTES attributes = {0};
- attributes.Length = sizeof(attributes);
- CLIENT_ID client_id = {0};
- client_id.UniqueProcess = reinterpret_cast<PVOID>(
- static_cast<ULONG_PTR>(client_info.process_id));
- client_id.UniqueThread =
- reinterpret_cast<PVOID>(static_cast<ULONG_PTR>(thread_id));
-
- HANDLE local_handle;
- NTSTATUS status = NtOpenThread(&local_handle, desired_access, &attributes,
- &client_id);
- if (NT_SUCCESS(status)) {
- if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
- client_info.process, handle, 0, FALSE,
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- ::CloseHandle(local_handle);
- return STATUS_ACCESS_DENIED;
- }
- }
-
- return status;
-}
-
-NTSTATUS ProcessPolicy::OpenProcessAction(const ClientInfo& client_info,
- uint32 desired_access,
- uint32 process_id,
- HANDLE* handle) {
- *handle = NULL;
-
- NtOpenProcessFunction NtOpenProcess = NULL;
- ResolveNTFunctionPtr("NtOpenProcess", &NtOpenProcess);
-
- if (client_info.process_id != process_id)
- return STATUS_ACCESS_DENIED;
-
- OBJECT_ATTRIBUTES attributes = {0};
- attributes.Length = sizeof(attributes);
- CLIENT_ID client_id = {0};
- client_id.UniqueProcess = reinterpret_cast<PVOID>(
- static_cast<ULONG_PTR>(client_info.process_id));
- HANDLE local_handle;
- NTSTATUS status = NtOpenProcess(&local_handle, desired_access, &attributes,
- &client_id);
- if (NT_SUCCESS(status)) {
- if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
- client_info.process, handle, 0, FALSE,
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- ::CloseHandle(local_handle);
- return STATUS_ACCESS_DENIED;
- }
- }
-
- return status;
-}
-
-NTSTATUS ProcessPolicy::OpenProcessTokenAction(const ClientInfo& client_info,
- HANDLE process,
- uint32 desired_access,
- HANDLE* handle) {
- *handle = NULL;
- NtOpenProcessTokenFunction NtOpenProcessToken = NULL;
- ResolveNTFunctionPtr("NtOpenProcessToken", &NtOpenProcessToken);
-
- if (CURRENT_PROCESS != process)
- return STATUS_ACCESS_DENIED;
-
- HANDLE local_handle;
- NTSTATUS status = NtOpenProcessToken(client_info.process, desired_access,
- &local_handle);
- if (NT_SUCCESS(status)) {
- if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
- client_info.process, handle, 0, FALSE,
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- ::CloseHandle(local_handle);
- return STATUS_ACCESS_DENIED;
- }
- }
- return status;
-}
-
-NTSTATUS ProcessPolicy::OpenProcessTokenExAction(const ClientInfo& client_info,
- HANDLE process,
- uint32 desired_access,
- uint32 attributes,
- HANDLE* handle) {
- *handle = NULL;
- NtOpenProcessTokenExFunction NtOpenProcessTokenEx = NULL;
- ResolveNTFunctionPtr("NtOpenProcessTokenEx", &NtOpenProcessTokenEx);
-
- if (CURRENT_PROCESS != process)
- return STATUS_ACCESS_DENIED;
-
- HANDLE local_handle;
- NTSTATUS status = NtOpenProcessTokenEx(client_info.process, desired_access,
- attributes, &local_handle);
- if (NT_SUCCESS(status)) {
- if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
- client_info.process, handle, 0, FALSE,
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- ::CloseHandle(local_handle);
- return STATUS_ACCESS_DENIED;
- }
- }
- return status;
-}
-
-DWORD ProcessPolicy::CreateProcessWAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &app_name,
- const std::wstring &command_line,
- PROCESS_INFORMATION* process_info) {
- // The only action supported is ASK_BROKER which means create the process.
- if (GIVE_ALLACCESS != eval_result && GIVE_READONLY != eval_result) {
- return ERROR_ACCESS_DENIED;
- }
-
- STARTUPINFO startup_info = {0};
- startup_info.cb = sizeof(startup_info);
- scoped_ptr_malloc<wchar_t> cmd_line(_wcsdup(command_line.c_str()));
-
- BOOL should_give_full_access = (GIVE_ALLACCESS == eval_result);
- if (!CreateProcessExWHelper(client_info.process, should_give_full_access,
- app_name.c_str(), cmd_line.get(), NULL, NULL,
- FALSE, 0, NULL, NULL, &startup_info,
- process_info)) {
- return ERROR_ACCESS_DENIED;
- }
- return ERROR_SUCCESS;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/process_thread_policy.h b/sandbox/win/src/process_thread_policy.h
deleted file mode 100644
index c35c52b5..0000000
--- a/sandbox/win/src/process_thread_policy.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_PROCESS_THREAD_POLICY_H_
-#define SANDBOX_SRC_PROCESS_THREAD_POLICY_H_
-
-#include <string>
-
-#include "sandbox/win/src/policy_low_level.h"
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/sandbox_policy.h"
-
-namespace sandbox {
-
-enum EvalResult;
-
-// This class centralizes most of the knowledge related to process execution.
-class ProcessPolicy {
- public:
- // Creates the required low-level policy rules to evaluate a high-level.
- // policy rule for process creation
- // 'name' is the executable to be spawn.
- // 'semantics' is the desired semantics.
- // 'policy' is the policy generator to which the rules are going to be added.
- static bool GenerateRules(const wchar_t* name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy);
-
- // Opens a thread from the child process and returns the handle.
- // client_info contains the information about the child process,
- // desired_access is the access requested by the child and thread_id
- // is the thread_id to be opened.
- // The function returns the return value of NtOpenThread.
- static NTSTATUS OpenThreadAction(const ClientInfo& client_info,
- uint32 desired_access,
- uint32 thread_id,
- HANDLE* handle);
-
- // Opens the process id passed in and returns the duplicated handle to
- // the child. We only allow the child processes to open themselves. Any other
- // pid open is denied.
- static NTSTATUS OpenProcessAction(const ClientInfo& client_info,
- uint32 desired_access,
- uint32 process_id,
- HANDLE* handle);
-
- // Opens the token associated with the process and returns the duplicated
- // handle to the child. We only allow the child processes to open his own
- // token (using ::GetCurrentProcess()).
- static NTSTATUS OpenProcessTokenAction(const ClientInfo& client_info,
- HANDLE process,
- uint32 desired_access,
- HANDLE* handle);
-
- // Opens the token associated with the process and returns the duplicated
- // handle to the child. We only allow the child processes to open his own
- // token (using ::GetCurrentProcess()).
- static NTSTATUS OpenProcessTokenExAction(const ClientInfo& client_info,
- HANDLE process,
- uint32 desired_access,
- uint32 attributes,
- HANDLE* handle);
-
- // Processes a 'CreateProcessW()' request from the target.
- // 'client_info' : the target process that is making the request.
- // 'eval_result' : The desired policy action to accomplish.
- // 'app_name' : The full path of the process to be created.
- // 'command_line' : The command line passed to the created process.
- static DWORD CreateProcessWAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &app_name,
- const std::wstring &command_line,
- PROCESS_INFORMATION* process_info);
-};
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_PROCESS_THREAD_POLICY_H_
diff --git a/sandbox/win/src/registry_dispatcher.cc b/sandbox/win/src/registry_dispatcher.cc
deleted file mode 100644
index f4dc5f5..0000000
--- a/sandbox/win/src/registry_dispatcher.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/registry_dispatcher.h"
-
-#include "base/win/scoped_handle.h"
-#include "base/win/windows_version.h"
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/interception.h"
-#include "sandbox/win/src/interceptors.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/policy_broker.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/registry_interception.h"
-#include "sandbox/win/src/registry_policy.h"
-
-namespace {
-
-// Builds a path using the root directory and the name.
-bool GetCompletePath(HANDLE root, const std::wstring& name,
- std::wstring* complete_name) {
- if (root) {
- if (!sandbox::GetPathFromHandle(root, complete_name))
- return false;
-
- *complete_name += L"\\";
- *complete_name += name;
- } else {
- *complete_name = name;
- }
-
- return true;
-}
-
-}
-
-namespace sandbox {
-
-RegistryDispatcher::RegistryDispatcher(PolicyBase* policy_base)
- : policy_base_(policy_base) {
- static const IPCCall create_params = {
- {IPC_NTCREATEKEY_TAG, WCHAR_TYPE, ULONG_TYPE, VOIDPTR_TYPE, ULONG_TYPE,
- ULONG_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(&RegistryDispatcher::NtCreateKey)
- };
-
- static const IPCCall open_params = {
- {IPC_NTOPENKEY_TAG, WCHAR_TYPE, ULONG_TYPE, VOIDPTR_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(&RegistryDispatcher::NtOpenKey)
- };
-
- ipc_calls_.push_back(create_params);
- ipc_calls_.push_back(open_params);
-}
-
-bool RegistryDispatcher::SetupService(InterceptionManager* manager,
- int service) {
- if (IPC_NTCREATEKEY_TAG == service)
- return INTERCEPT_NT(manager, NtCreateKey, CREATE_KEY_ID, 32);
-
- if (IPC_NTOPENKEY_TAG == service) {
- bool result = INTERCEPT_NT(manager, NtOpenKey, OPEN_KEY_ID, 16);
- if (base::win::GetVersion() >= base::win::VERSION_WIN7)
- result &= INTERCEPT_NT(manager, NtOpenKeyEx, OPEN_KEY_EX_ID, 20);
- return result;
- }
-
- return false;
-}
-
-bool RegistryDispatcher::NtCreateKey(
- IPCInfo* ipc, std::wstring* name, DWORD attributes, HANDLE root,
- DWORD desired_access, DWORD title_index, DWORD create_options) {
- base::win::ScopedHandle root_handle;
- std::wstring real_path = *name;
-
- // If there is a root directory, we need to duplicate the handle to make
- // it valid in this process.
- if (root) {
- if (!::DuplicateHandle(ipc->client_info->process, root,
- ::GetCurrentProcess(), &root, 0, FALSE,
- DUPLICATE_SAME_ACCESS))
- return false;
-
- root_handle.Set(root);
- }
-
- if (!GetCompletePath(root, *name, &real_path))
- return false;
-
- const wchar_t* regname = real_path.c_str();
- CountedParameterSet<OpenKey> params;
- params[OpenKey::NAME] = ParamPickerMake(regname);
- params[OpenKey::ACCESS] = ParamPickerMake(desired_access);
-
- EvalResult result = policy_base_->EvalPolicy(IPC_NTCREATEKEY_TAG,
- params.GetBase());
-
- HANDLE handle;
- NTSTATUS nt_status;
- ULONG disposition = 0;
- if (!RegistryPolicy::CreateKeyAction(result, *ipc->client_info, *name,
- attributes, root, desired_access,
- title_index, create_options, &handle,
- &nt_status, &disposition)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- // Return operation status on the IPC.
- ipc->return_info.extended[0].unsigned_int = disposition;
- ipc->return_info.nt_status = nt_status;
- ipc->return_info.handle = handle;
- return true;
-}
-
-bool RegistryDispatcher::NtOpenKey(IPCInfo* ipc, std::wstring* name,
- DWORD attributes, HANDLE root,
- DWORD desired_access) {
- base::win::ScopedHandle root_handle;
- std::wstring real_path = *name;
-
- // If there is a root directory, we need to duplicate the handle to make
- // it valid in this process.
- if (root) {
- if (!::DuplicateHandle(ipc->client_info->process, root,
- ::GetCurrentProcess(), &root, 0, FALSE,
- DUPLICATE_SAME_ACCESS))
- return false;
- root_handle.Set(root);
- }
-
- if (!GetCompletePath(root, *name, &real_path))
- return false;
-
- const wchar_t* regname = real_path.c_str();
- CountedParameterSet<OpenKey> params;
- params[OpenKey::NAME] = ParamPickerMake(regname);
- params[OpenKey::ACCESS] = ParamPickerMake(desired_access);
-
- EvalResult result = policy_base_->EvalPolicy(IPC_NTOPENKEY_TAG,
- params.GetBase());
- HANDLE handle;
- NTSTATUS nt_status;
- if (!RegistryPolicy::OpenKeyAction(result, *ipc->client_info, *name,
- attributes, root, desired_access, &handle,
- &nt_status)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- // Return operation status on the IPC.
- ipc->return_info.nt_status = nt_status;
- ipc->return_info.handle = handle;
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/registry_dispatcher.h b/sandbox/win/src/registry_dispatcher.h
deleted file mode 100644
index 782a070..0000000
--- a/sandbox/win/src/registry_dispatcher.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_REGISTRY_DISPATCHER_H_
-#define SANDBOX_SRC_REGISTRY_DISPATCHER_H_
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/sandbox_policy_base.h"
-
-namespace sandbox {
-
-// This class handles registry-related IPC calls.
-class RegistryDispatcher : public Dispatcher {
- public:
- explicit RegistryDispatcher(PolicyBase* policy_base);
- ~RegistryDispatcher() {}
-
- // Dispatcher interface.
- virtual bool SetupService(InterceptionManager* manager, int service);
-
- private:
- // Processes IPC requests coming from calls to NtCreateKey in the target.
- bool NtCreateKey(IPCInfo* ipc, std::wstring* name, DWORD attributes,
- HANDLE root, DWORD desired_access,
- DWORD title_index, DWORD create_options);
-
- // Processes IPC requests coming from calls to NtOpenKey in the target.
- bool NtOpenKey(IPCInfo* ipc, std::wstring* name, DWORD attributes,
- HANDLE root, DWORD desired_access);
-
- PolicyBase* policy_base_;
- DISALLOW_COPY_AND_ASSIGN(RegistryDispatcher);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_REGISTRY_DISPATCHER_H_
diff --git a/sandbox/win/src/registry_interception.cc b/sandbox/win/src/registry_interception.cc
deleted file mode 100644
index 936d4ac..0000000
--- a/sandbox/win/src/registry_interception.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/registry_interception.h"
-
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "sandbox/win/src/target_services.h"
-
-namespace sandbox {
-
-NTSTATUS WINAPI TargetNtCreateKey(NtCreateKeyFunction orig_CreateKey,
- PHANDLE key, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes,
- ULONG title_index, PUNICODE_STRING class_name,
- ULONG create_options, PULONG disposition) {
- // Check if the process can create it first.
- NTSTATUS status = orig_CreateKey(key, desired_access, object_attributes,
- title_index, class_name, create_options,
- disposition);
- if (NT_SUCCESS(status))
- return status;
-
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return status;
-
- do {
- if (!ValidParameter(key, sizeof(HANDLE), WRITE))
- break;
-
- if (disposition && !ValidParameter(disposition, sizeof(ULONG), WRITE))
- break;
-
- // At this point we don't support class_name.
- if (class_name && class_name->Buffer && class_name->Length)
- break;
-
- // We don't support creating link keys, volatile keys and backup/restore.
- if (create_options)
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- wchar_t* name;
- uint32 attributes = 0;
- HANDLE root_directory = 0;
- NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
- &root_directory);
- if (!NT_SUCCESS(ret) || NULL == name)
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
-
- ResultCode code = CrossCall(ipc, IPC_NTCREATEKEY_TAG, name, attributes,
- root_directory, desired_access, title_index,
- create_options, &answer);
-
- operator delete(name, NT_ALLOC);
-
- if (SBOX_ALL_OK != code)
- break;
-
- if (!NT_SUCCESS(answer.nt_status))
- // TODO(nsylvain): We should return answer.nt_status here instead
- // of status. We can do this only after we checked the policy.
- // otherwise we will returns ACCESS_DENIED for all paths
- // that are not specified by a policy, even though your token allows
- // access to that path, and the original call had a more meaningful
- // error. Bug 4369
- break;
-
- __try {
- *key = answer.handle;
-
- if (disposition)
- *disposition = answer.extended[0].unsigned_int;
-
- status = answer.nt_status;
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- break;
- }
- } while (false);
-
- return status;
-}
-
-NTSTATUS WINAPI CommonNtOpenKey(NTSTATUS status, PHANDLE key,
- ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes) {
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return status;
-
- do {
- if (!ValidParameter(key, sizeof(HANDLE), WRITE))
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- wchar_t* name;
- uint32 attributes;
- HANDLE root_directory;
- NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
- &root_directory);
- if (!NT_SUCCESS(ret) || NULL == name)
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_NTOPENKEY_TAG, name, attributes,
- root_directory, desired_access, &answer);
-
- operator delete(name, NT_ALLOC);
-
- if (SBOX_ALL_OK != code)
- break;
-
- if (!NT_SUCCESS(answer.nt_status))
- // TODO(nsylvain): We should return answer.nt_status here instead
- // of status. We can do this only after we checked the policy.
- // otherwise we will returns ACCESS_DENIED for all paths
- // that are not specified by a policy, even though your token allows
- // access to that path, and the original call had a more meaningful
- // error. Bug 4369
- break;
-
- __try {
- *key = answer.handle;
- status = answer.nt_status;
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- break;
- }
- } while (false);
-
- return status;
-}
-
-NTSTATUS WINAPI TargetNtOpenKey(NtOpenKeyFunction orig_OpenKey, PHANDLE key,
- ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes) {
- // Check if the process can open it first.
- NTSTATUS status = orig_OpenKey(key, desired_access, object_attributes);
- if (NT_SUCCESS(status))
- return status;
-
- return CommonNtOpenKey(status, key, desired_access, object_attributes);
-}
-
-NTSTATUS WINAPI TargetNtOpenKeyEx(NtOpenKeyExFunction orig_OpenKeyEx,
- PHANDLE key, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes,
- ULONG open_options) {
- // Check if the process can open it first.
- NTSTATUS status = orig_OpenKeyEx(key, desired_access, object_attributes,
- open_options);
-
- // We do not support open_options at this time. The 2 current known values
- // are REG_OPTION_CREATE_LINK, to open a symbolic link, and
- // REG_OPTION_BACKUP_RESTORE to open the key with special privileges.
- if (NT_SUCCESS(status) || open_options != 0)
- return status;
-
- return CommonNtOpenKey(status, key, desired_access, object_attributes);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/registry_interception.h b/sandbox/win/src/registry_interception.h
deleted file mode 100644
index c3cbde0..0000000
--- a/sandbox/win/src/registry_interception.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-#ifndef SANDBOX_SRC_REGISTRY_INTERCEPTION_H__
-#define SANDBOX_SRC_REGISTRY_INTERCEPTION_H__
-
-namespace sandbox {
-
-extern "C" {
-
-// Interception of NtCreateKey on the child process.
-// It should never be called directly
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtCreateKey(
- NtCreateKeyFunction orig_CreateKey, PHANDLE key, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, ULONG title_index,
- PUNICODE_STRING class_name, ULONG create_options, PULONG disposition);
-
-// Interception of NtOpenKey on the child process.
-// It should never be called directly
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenKey(
- NtOpenKeyFunction orig_OpenKey, PHANDLE key, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes);
-
-// Interception of NtOpenKeyEx on the child process.
-// It should never be called directly
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenKeyEx(
- NtOpenKeyExFunction orig_OpenKeyEx, PHANDLE key, ACCESS_MASK desired_access,
- POBJECT_ATTRIBUTES object_attributes, ULONG open_options);
-
-} // extern "C"
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_REGISTRY_INTERCEPTION_H__
diff --git a/sandbox/win/src/registry_policy.cc b/sandbox/win/src/registry_policy.cc
deleted file mode 100644
index 55f3bcd..0000000
--- a/sandbox/win/src/registry_policy.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "sandbox/win/src/registry_policy.h"
-
-#include "base/logging.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_engine_opcodes.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox_utils.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace {
-
-static const DWORD kAllowedRegFlags = KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS |
- KEY_NOTIFY | KEY_READ | GENERIC_READ |
- GENERIC_EXECUTE | READ_CONTROL;
-
-// Opens the key referenced by |obj_attributes| with |access| and
-// checks what permission was given. Remove the WRITE flags and update
-// |access| with the new value.
-NTSTATUS TranslateMaximumAllowed(OBJECT_ATTRIBUTES* obj_attributes,
- DWORD* access) {
- NtOpenKeyFunction NtOpenKey = NULL;
- ResolveNTFunctionPtr("NtOpenKey", &NtOpenKey);
-
- NtCloseFunction NtClose = NULL;
- ResolveNTFunctionPtr("NtClose", &NtClose);
-
- NtQueryObjectFunction NtQueryObject = NULL;
- ResolveNTFunctionPtr("NtQueryObject", &NtQueryObject);
-
- // Open the key.
- HANDLE handle;
- NTSTATUS status = NtOpenKey(&handle, *access, obj_attributes);
- if (!NT_SUCCESS(status))
- return status;
-
- OBJECT_BASIC_INFORMATION info = {0};
- status = NtQueryObject(handle, ObjectBasicInformation, &info, sizeof(info),
- NULL);
- NtClose(handle);
- if (!NT_SUCCESS(status))
- return status;
-
- *access = info.GrantedAccess & kAllowedRegFlags;
- return STATUS_SUCCESS;
-}
-
-NTSTATUS NtCreateKeyInTarget(HANDLE* target_key_handle,
- ACCESS_MASK desired_access,
- OBJECT_ATTRIBUTES* obj_attributes,
- ULONG title_index,
- UNICODE_STRING* class_name,
- ULONG create_options,
- ULONG* disposition,
- HANDLE target_process) {
- NtCreateKeyFunction NtCreateKey = NULL;
- ResolveNTFunctionPtr("NtCreateKey", &NtCreateKey);
-
- if (MAXIMUM_ALLOWED & desired_access) {
- NTSTATUS status = TranslateMaximumAllowed(obj_attributes, &desired_access);
- if (!NT_SUCCESS(status))
- return STATUS_ACCESS_DENIED;
- }
-
- HANDLE local_handle = INVALID_HANDLE_VALUE;
- NTSTATUS status = NtCreateKey(&local_handle, desired_access, obj_attributes,
- title_index, class_name, create_options,
- disposition);
- if (!NT_SUCCESS(status))
- return status;
-
- if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
- target_process, target_key_handle, 0, FALSE,
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- ::CloseHandle(local_handle);
- return STATUS_ACCESS_DENIED;
- }
- return STATUS_SUCCESS;
-}
-
-NTSTATUS NtOpenKeyInTarget(HANDLE* target_key_handle,
- ACCESS_MASK desired_access,
- OBJECT_ATTRIBUTES* obj_attributes,
- HANDLE target_process) {
- NtOpenKeyFunction NtOpenKey = NULL;
- ResolveNTFunctionPtr("NtOpenKey", &NtOpenKey);
-
- if (MAXIMUM_ALLOWED & desired_access) {
- NTSTATUS status = TranslateMaximumAllowed(obj_attributes, &desired_access);
- if (!NT_SUCCESS(status))
- return STATUS_ACCESS_DENIED;
- }
-
- HANDLE local_handle = INVALID_HANDLE_VALUE;
- NTSTATUS status = NtOpenKey(&local_handle, desired_access, obj_attributes);
-
- if (!NT_SUCCESS(status))
- return status;
-
- if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
- target_process, target_key_handle, 0, FALSE,
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- ::CloseHandle(local_handle);
- return STATUS_ACCESS_DENIED;
- }
- return STATUS_SUCCESS;
-}
-
-}
-
-namespace sandbox {
-
-bool RegistryPolicy::GenerateRules(const wchar_t* name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy) {
- std::wstring resovled_name(name);
- if (resovled_name.empty()) {
- return false;
- }
-
- if (!ResolveRegistryName(resovled_name, &resovled_name))
- return false;
-
- name = resovled_name.c_str();
-
- EvalResult result = ASK_BROKER;
-
- PolicyRule open(result);
- PolicyRule create(result);
-
- switch (semantics) {
- case TargetPolicy::REG_ALLOW_READONLY: {
- // We consider all flags that are not known to be readonly as potentially
- // used for write. Here we also support MAXIMUM_ALLOWED, but we are going
- // to expand it to read-only before the call.
- DWORD restricted_flags = ~(kAllowedRegFlags | MAXIMUM_ALLOWED);
- open.AddNumberMatch(IF_NOT, OpenKey::ACCESS, restricted_flags, AND);
- create.AddNumberMatch(IF_NOT, OpenKey::ACCESS, restricted_flags, AND);
- break;
- }
- case TargetPolicy::REG_ALLOW_ANY: {
- break;
- }
- default: {
- NOTREACHED();
- return false;
- }
- }
-
- if (!create.AddStringMatch(IF, OpenKey::NAME, name, CASE_INSENSITIVE) ||
- !policy->AddRule(IPC_NTCREATEKEY_TAG, &create)) {
- return false;
- }
-
- if (!open.AddStringMatch(IF, OpenKey::NAME, name, CASE_INSENSITIVE) ||
- !policy->AddRule(IPC_NTOPENKEY_TAG, &open)) {
- return false;
- }
-
- return true;
-}
-
-bool RegistryPolicy::CreateKeyAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &key,
- uint32 attributes,
- HANDLE root_directory,
- uint32 desired_access,
- uint32 title_index,
- uint32 create_options,
- HANDLE* handle,
- NTSTATUS* nt_status,
- ULONG* disposition) {
- // The only action supported is ASK_BROKER which means create the requested
- // file as specified.
- if (ASK_BROKER != eval_result) {
- *nt_status = STATUS_ACCESS_DENIED;
- return false;
- }
-
- // We don't support creating link keys, volatile keys or backup/restore.
- if (create_options) {
- *nt_status = STATUS_ACCESS_DENIED;
- return false;
- }
-
- UNICODE_STRING uni_name = {0};
- OBJECT_ATTRIBUTES obj_attributes = {0};
- InitObjectAttribs(key, attributes, root_directory, &obj_attributes,
- &uni_name);
- *nt_status = NtCreateKeyInTarget(handle, desired_access, &obj_attributes,
- title_index, NULL, create_options,
- disposition, client_info.process);
- return true;
-}
-
-bool RegistryPolicy::OpenKeyAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &key,
- uint32 attributes,
- HANDLE root_directory,
- uint32 desired_access,
- HANDLE* handle,
- NTSTATUS* nt_status) {
- // The only action supported is ASK_BROKER which means open the requested
- // file as specified.
- if (ASK_BROKER != eval_result) {
- *nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
-
- UNICODE_STRING uni_name = {0};
- OBJECT_ATTRIBUTES obj_attributes = {0};
- InitObjectAttribs(key, attributes, root_directory, &obj_attributes,
- &uni_name);
- *nt_status = NtOpenKeyInTarget(handle, desired_access, &obj_attributes,
- client_info.process);
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/registry_policy.h b/sandbox/win/src/registry_policy.h
deleted file mode 100644
index 8badde2..0000000
--- a/sandbox/win/src/registry_policy.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_REGISTRY_POLICY_H__
-#define SANDBOX_SRC_REGISTRY_POLICY_H__
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/policy_low_level.h"
-#include "sandbox/win/src/sandbox_policy.h"
-
-namespace sandbox {
-
-enum EvalResult;
-
-// This class centralizes most of the knowledge related to registry policy
-class RegistryPolicy {
- public:
- // Creates the required low-level policy rules to evaluate a high-level
- // policy rule for registry IO, in particular open or create actions.
- static bool GenerateRules(const wchar_t* name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy);
-
- // Performs the desired policy action on a create request with an
- // API that is compatible with the IPC-received parameters.
- static bool CreateKeyAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &key,
- uint32 attributes,
- HANDLE root_directory,
- uint32 desired_access,
- uint32 title_index,
- uint32 create_options,
- HANDLE* handle,
- NTSTATUS* nt_status,
- ULONG* disposition);
-
- // Performs the desired policy action on an open request with an
- // API that is compatible with the IPC-received parameters.
- static bool OpenKeyAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &key,
- uint32 attributes,
- HANDLE root_directory,
- uint32 desired_access,
- HANDLE* handle,
- NTSTATUS* nt_status);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_REGISTRY_POLICY_H__
diff --git a/sandbox/win/src/registry_policy_test.cc b/sandbox/win/src/registry_policy_test.cc
deleted file mode 100644
index d8ee34b..0000000
--- a/sandbox/win/src/registry_policy_test.cc
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <shlobj.h>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "sandbox/win/src/registry_policy.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_policy.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/win_utils.h"
-#include "sandbox/win/tests/common/controller.h"
-
-namespace {
-
-static const DWORD kAllowedRegFlags = KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS |
- KEY_NOTIFY | KEY_READ | GENERIC_READ |
- GENERIC_EXECUTE | READ_CONTROL;
-
-#define BINDNTDLL(name) \
- name ## Function name = reinterpret_cast<name ## Function>( \
- ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), #name))
-
-bool IsKeyOpenForRead(HKEY handle) {
- BINDNTDLL(NtQueryObject);
-
- OBJECT_BASIC_INFORMATION info = {0};
- NTSTATUS status = NtQueryObject(handle, ObjectBasicInformation, &info,
- sizeof(info), NULL);
-
- if (!NT_SUCCESS(status))
- return false;
-
- if ((info.GrantedAccess & (~kAllowedRegFlags)) != 0)
- return false;
- return true;
-}
-
-}
-
-namespace sandbox {
-
-SBOX_TESTS_COMMAND int Reg_OpenKey(int argc, wchar_t **argv) {
- if (argc != 4)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- REGSAM desired_access = 0;
- ULONG options = 0;
- if (wcscmp(argv[1], L"read") == 0) {
- desired_access = KEY_READ;
- } else if (wcscmp(argv[1], L"write") == 0) {
- desired_access = KEY_ALL_ACCESS;
- } else if (wcscmp(argv[1], L"link") == 0) {
- options = REG_OPTION_CREATE_LINK;
- desired_access = KEY_ALL_ACCESS;
- } else {
- desired_access = MAXIMUM_ALLOWED;
- }
-
- HKEY root = GetReservedKeyFromName(argv[2]);
- HKEY key;
- LRESULT result = 0;
-
- if (wcscmp(argv[0], L"create") == 0)
- result = ::RegCreateKeyEx(root, argv[3], 0, NULL, options, desired_access,
- NULL, &key, NULL);
- else
- result = ::RegOpenKeyEx(root, argv[3], 0, desired_access, &key);
-
- if (ERROR_SUCCESS == result) {
- if (MAXIMUM_ALLOWED == desired_access) {
- if (!IsKeyOpenForRead(key)) {
- ::RegCloseKey(key);
- return SBOX_TEST_FAILED;
- }
- }
- ::RegCloseKey(key);
- return SBOX_TEST_SUCCEEDED;
- } else if (ERROR_ACCESS_DENIED == result) {
- return SBOX_TEST_DENIED;
- }
-
- return SBOX_TEST_FAILED;
-}
-
-TEST(RegistryPolicyTest, TestKeyAnyAccess) {
- TestRunner runner;
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_READONLY,
- L"HKEY_LOCAL_MACHINE"));
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_ANY,
- L"HKEY_LOCAL_MACHINE\\Software\\Microsoft"));
-
- // Tests read access on key allowed for read-write.
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
- L"Reg_OpenKey create read HKEY_LOCAL_MACHINE software\\microsoft"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
- L"Reg_OpenKey open read HKEY_LOCAL_MACHINE software\\microsoft"));
-
- if (::IsUserAnAdmin()) {
- // Tests write access on key allowed for read-write.
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
- L"Reg_OpenKey create write HKEY_LOCAL_MACHINE software\\microsoft"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
- L"Reg_OpenKey open write HKEY_LOCAL_MACHINE software\\microsoft"));
- }
-
- // Tests subdirectory access on keys where we don't have subdirectory acess.
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Reg_OpenKey create read "
- L"HKEY_LOCAL_MACHINE software\\microsoft\\Windows"));
-
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Reg_OpenKey open read "
- L"HKEY_LOCAL_MACHINE software\\microsoft\\windows"));
-
- // Tests to see if we can create keys where we dont have subdirectory access.
- // This is denied.
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Reg_OpenKey create write "
- L"HKEY_LOCAL_MACHINE software\\Microsoft\\google_unit_tests"));
-
- RegDeleteKey(HKEY_LOCAL_MACHINE, L"software\\Microsoft\\google_unit_tests");
-
- // Tests if we need to handle differently the "\\" at the end.
- // This is denied. We need to add both rules.
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
- L"Reg_OpenKey create read HKEY_LOCAL_MACHINE software\\microsoft\\"));
-
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
- L"Reg_OpenKey open read HKEY_LOCAL_MACHINE software\\microsoft\\"));
-}
-
-TEST(RegistryPolicyTest, TestKeyNoAccess) {
- TestRunner runner;
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_READONLY,
- L"HKEY_LOCAL_MACHINE"));
-
- // Tests read access where we don't have access at all.
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
- L"Reg_OpenKey create read HKEY_LOCAL_MACHINE software"));
-
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
- L"Reg_OpenKey open read HKEY_LOCAL_MACHINE software"));
-}
-
-TEST(RegistryPolicyTest, TestKeyReadOnlyAccess) {
- TestRunner runner;
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_READONLY,
- L"HKEY_LOCAL_MACHINE"));
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_READONLY,
- L"HKEY_LOCAL_MACHINE\\Software\\Policies"));
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_READONLY,
- L"HKEY_LOCAL_MACHINE\\Software\\Policies\\*"));
-
- // Tests subdirectory acess on keys where we have subdirectory acess.
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Reg_OpenKey create read "
- L"HKEY_LOCAL_MACHINE software\\Policies\\microsoft"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Reg_OpenKey open read "
- L"HKEY_LOCAL_MACHINE software\\Policies\\microsoft"));
-
- // Tests to see if we can create keys where we have subdirectory access.
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Reg_OpenKey create write "
- L"HKEY_LOCAL_MACHINE software\\Policies\\google_unit_tests"));
-
- RegDeleteKey(HKEY_LOCAL_MACHINE, L"software\\Policies\\google_unit_tests");
-}
-
-TEST(RegistryPolicyTest, TestKeyAllAccessSubDir) {
- TestRunner runner;
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_READONLY,
- L"HKEY_LOCAL_MACHINE"));
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_ANY,
- L"HKEY_LOCAL_MACHINE\\Software\\Policies"));
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_ANY,
- L"HKEY_LOCAL_MACHINE\\Software\\Policies\\*"));
-
- if (::IsUserAnAdmin()) {
- // Tests to see if we can create keys where we have subdirectory access.
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Reg_OpenKey create write "
- L"HKEY_LOCAL_MACHINE software\\Policies\\google_unit_tests"));
-
- RegDeleteKey(HKEY_LOCAL_MACHINE, L"software\\Policies\\google_unit_tests");
- }
-}
-
-TEST(RegistryPolicyTest, TestKeyCreateLink) {
- TestRunner runner;
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_READONLY,
- L"HKEY_LOCAL_MACHINE"));
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_ANY,
- L"HKEY_LOCAL_MACHINE\\Software\\Policies"));
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_ANY,
- L"HKEY_LOCAL_MACHINE\\Software\\Policies\\*"));
-
- // Tests to see if we can create a registry link key.
- // NOTE: In theory here we should make sure to check for SBOX_TEST_DENIED
- // instead of !SBOX_TEST_SUCCEEDED, but unfortunately the result is not
- // access denied. Internally RegCreateKeyEx (At least on Vista 64) tries to
- // create the link, and we return successfully access denied, then, it
- // decides to try to break the path in multiple chunks, and create the links
- // one by one. In this scenario, it tries to create "HKLM\Software" as a
- // link key, which obviously fail with STATUS_OBJECT_NAME_COLLISION, and
- // this is what is returned to the user.
- EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Reg_OpenKey create link "
- L"HKEY_LOCAL_MACHINE software\\Policies\\google_unit_tests"));
-
- // In case our code fails, and the call works, we need to delete the new
- // link. There is no api for this, so we need to use the NT call.
- HKEY key = NULL;
- LRESULT result = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- L"software\\Policies\\google_unit_tests",
- REG_OPTION_OPEN_LINK, MAXIMUM_ALLOWED,
- &key);
-
- if (!result) {
- HMODULE ntdll = GetModuleHandle(L"ntdll.dll");
- NtDeleteKeyFunction NtDeleteKey =
- reinterpret_cast<NtDeleteKeyFunction>(GetProcAddress(ntdll,
- "NtDeleteKey"));
- NtDeleteKey(key);
- }
-}
-
-TEST(RegistryPolicyTest, TestKeyReadOnlyHKCU) {
- TestRunner runner;
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_READONLY,
- L"HKEY_CURRENT_USER"));
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_READONLY,
- L"HKEY_CURRENT_USER\\Software"));
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_READONLY,
- L"HKEY_USERS\\.default"));
-
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_READONLY,
- L"HKEY_USERS\\.default\\software"));
-
- // Tests read access where we only have read-only access.
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
- L"Reg_OpenKey create read HKEY_CURRENT_USER software"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
- L"Reg_OpenKey open read HKEY_CURRENT_USER software"));
-
- // Tests write access where we only have read-only acess.
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
- L"Reg_OpenKey create write HKEY_CURRENT_USER software"));
-
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
- L"Reg_OpenKey open write HKEY_CURRENT_USER software"));
-
- // Tests maximum allowed access where we only have read-only access.
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
- L"Reg_OpenKey create maximum_allowed HKEY_CURRENT_USER software"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
- L"Reg_OpenKey open maximum_allowed HKEY_CURRENT_USER software"));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/resolver.cc b/sandbox/win/src/resolver.cc
deleted file mode 100644
index 6616fa5..0000000
--- a/sandbox/win/src/resolver.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/resolver.h"
-
-#include "base/win/pe_image.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-
-namespace sandbox {
-
-NTSTATUS ResolverThunk::Init(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes) {
- if (NULL == thunk_storage || 0 == storage_bytes ||
- NULL == target_module || NULL == target_name)
- return STATUS_INVALID_PARAMETER;
-
- if (storage_bytes < GetThunkSize())
- return STATUS_BUFFER_TOO_SMALL;
-
- NTSTATUS ret = STATUS_SUCCESS;
- if (NULL == interceptor_entry_point) {
- ret = ResolveInterceptor(interceptor_module, interceptor_name,
- &interceptor_entry_point);
- if (!NT_SUCCESS(ret))
- return ret;
- }
-
- ret = ResolveTarget(target_module, target_name, &target_);
- if (!NT_SUCCESS(ret))
- return ret;
-
- interceptor_ = interceptor_entry_point;
-
- return ret;
-}
-
-NTSTATUS ResolverThunk::ResolveInterceptor(const void* interceptor_module,
- const char* interceptor_name,
- const void** address) {
- DCHECK_NT(address);
- if (!interceptor_module)
- return STATUS_INVALID_PARAMETER;
-
- base::win::PEImage pe(interceptor_module);
- if (!pe.VerifyMagic())
- return STATUS_INVALID_IMAGE_FORMAT;
-
- *address = pe.GetProcAddress(interceptor_name);
-
- if (!(*address))
- return STATUS_PROCEDURE_NOT_FOUND;
-
- return STATUS_SUCCESS;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/resolver.h b/sandbox/win/src/resolver.h
deleted file mode 100644
index 85f1e91..0000000
--- a/sandbox/win/src/resolver.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Defines ResolverThunk, the interface for classes that perform interceptions.
-// For more details see
-// http://dev.chromium.org/developers/design-documents/sandbox .
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/nt_internals.h"
-
-#ifndef SANDBOX_SRC_RESOLVER_H__
-#define SANDBOX_SRC_RESOLVER_H__
-
-namespace sandbox {
-
-// A resolver is the object in charge of performing the actual interception of
-// a function. There should be a concrete implementation of a resolver roughly
-// per type of interception.
-class ResolverThunk {
- public:
- ResolverThunk() {}
- virtual ~ResolverThunk() {}
-
- // Performs the actual interception of a function.
- // target_name is an exported function from the module loaded at
- // target_module, and must be replaced by interceptor_name, exported from
- // interceptor_module. interceptor_entry_point can be provided instead of
- // interceptor_name / interceptor_module.
- // thunk_storage must point to a buffer on the child's address space, to hold
- // the patch thunk, and related data. If provided, storage_used will receive
- // the number of bytes used from thunk_storage.
- //
- // Example: (without error checking)
- //
- // size_t size = resolver.GetThunkSize();
- // char* buffer = ::VirtualAllocEx(child_process, NULL, size,
- // MEM_COMMIT, PAGE_READWRITE);
- // resolver.Setup(ntdll_module, NULL, L"NtCreateFile", NULL,
- // &MyReplacementFunction, buffer, size, NULL);
- //
- // In general, the idea is to allocate a single big buffer for all
- // interceptions on the same dll, and call Setup n times.
- // WARNING: This means that any data member that is specific to a single
- // interception must be reset within this method.
- virtual NTSTATUS Setup(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes,
- size_t* storage_used) = 0;
-
- // Gets the address of function_name inside module (main exe).
- virtual NTSTATUS ResolveInterceptor(const void* module,
- const char* function_name,
- const void** address);
-
- // Gets the address of an exported function_name inside module.
- virtual NTSTATUS ResolveTarget(const void* module,
- const char* function_name,
- void** address);
-
- // Gets the required buffer size for this type of thunk.
- virtual size_t GetThunkSize() const = 0;
-
- protected:
- // Performs basic initialization on behalf of a concrete instance of a
- // resolver. That is, parameter validation and resolution of the target
- // and the interceptor into the member variables.
- //
- // target_name is an exported function from the module loaded at
- // target_module, and must be replaced by interceptor_name, exported from
- // interceptor_module. interceptor_entry_point can be provided instead of
- // interceptor_name / interceptor_module.
- // thunk_storage must point to a buffer on the child's address space, to hold
- // the patch thunk, and related data.
- virtual NTSTATUS Init(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes);
-
- // Gets the required buffer size for the internal part of the thunk.
- size_t GetInternalThunkSize() const;
-
- // Initializes the internal part of the thunk.
- // interceptor is the function to be called instead of original_function.
- bool SetInternalThunk(void* storage, size_t storage_bytes,
- const void* original_function, const void* interceptor);
-
- // Holds the resolved interception target.
- void* target_;
- // Holds the resolved interception interceptor.
- const void* interceptor_;
-
- DISALLOW_COPY_AND_ASSIGN(ResolverThunk);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_RESOLVER_H__
diff --git a/sandbox/win/src/resolver_32.cc b/sandbox/win/src/resolver_32.cc
deleted file mode 100644
index e5d7be3..0000000
--- a/sandbox/win/src/resolver_32.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/resolver.h"
-
-#include "sandbox/win/src/sandbox_nt_util.h"
-
-namespace {
-
-#pragma pack(push, 1)
-struct InternalThunk {
- // This struct contains roughly the following code:
- // sub esp, 8 // Create working space
- // push edx // Save register
- // mov edx, [esp + 0xc] // Get return adddress
- // mov [esp + 8], edx // Store return address
- // mov dword ptr [esp + 0xc], 0x7c401200 // Store extra argument
- // mov dword ptr [esp + 4], 0x40010203 // Store address to jump to
- // pop edx // Restore register
- // ret // Jump to interceptor
- //
- // This code only modifies esp and eip so it must work with to normal calling
- // convention. It is assembled as:
- //
- // 00 83ec08 sub esp,8
- // 03 52 push edx
- // 04 8b54240c mov edx,dword ptr [esp + 0Ch]
- // 08 89542408 mov dword ptr [esp + 8], edx
- // 0c c744240c0012407c mov dword ptr [esp + 0Ch], 7C401200h
- // 14 c744240403020140 mov dword ptr [esp + 4], 40010203h
- // 1c 5a pop edx
- // 1d c3 ret
- InternalThunk() {
- opcodes_1 = 0x5208ec83;
- opcodes_2 = 0x0c24548b;
- opcodes_3 = 0x08245489;
- opcodes_4 = 0x0c2444c7;
- opcodes_5 = 0x042444c7;
- opcodes_6 = 0xc35a;
- extra_argument = 0;
- interceptor_function = 0;
- };
- ULONG opcodes_1; // = 0x5208ec83
- ULONG opcodes_2; // = 0x0c24548b
- ULONG opcodes_3; // = 0x08245489
- ULONG opcodes_4; // = 0x0c2444c7
- ULONG extra_argument;
- ULONG opcodes_5; // = 0x042444c7
- ULONG interceptor_function;
- USHORT opcodes_6; // = 0xc35a
-};
-#pragma pack(pop)
-
-}; // namespace
-
-namespace sandbox {
-
-bool ResolverThunk::SetInternalThunk(void* storage, size_t storage_bytes,
- const void* original_function,
- const void* interceptor) {
- if (storage_bytes < sizeof(InternalThunk))
- return false;
-
- InternalThunk* thunk = new(storage, NT_PLACE) InternalThunk;
-
-#pragma warning(push)
-#pragma warning(disable: 4311)
- // These casts generate warnings because they are 32 bit specific.
- thunk->interceptor_function = reinterpret_cast<ULONG>(interceptor);
- thunk->extra_argument = reinterpret_cast<ULONG>(original_function);
-#pragma warning(pop)
-
- return true;
-}
-
-size_t ResolverThunk::GetInternalThunkSize() const {
- return sizeof(InternalThunk);
-}
-
-NTSTATUS ResolverThunk::ResolveTarget(const void* module,
- const char* function_name,
- void** address) {
- const void** casted = const_cast<const void**>(address);
- return ResolverThunk::ResolveInterceptor(module, function_name, casted);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/resolver_64.cc b/sandbox/win/src/resolver_64.cc
deleted file mode 100644
index ca58b20..0000000
--- a/sandbox/win/src/resolver_64.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/resolver.h"
-
-#include "sandbox/win/src/sandbox_nt_util.h"
-
-namespace {
-
-const BYTE kPushRax = 0x50;
-const USHORT kMovRax = 0xB848;
-const ULONG kMovRspRax = 0x24048948;
-const BYTE kRetNp = 0xC3;
-
-#pragma pack(push, 1)
-struct InternalThunk {
- // This struct contains roughly the following code:
- // 00 50 push rax
- // 01 48b8f0debc9a78563412 mov rax,123456789ABCDEF0h
- // 0b 48890424 mov qword ptr [rsp],rax
- // 0f c3 ret
- //
- // The code modifies rax, but that should not be an issue for the common
- // calling conventions.
-
- InternalThunk() {
- push_rax = kPushRax;
- mov_rax = kMovRax;
- interceptor_function = 0;
- mov_rsp_rax = kMovRspRax;
- ret = kRetNp;
- };
- BYTE push_rax; // = 50
- USHORT mov_rax; // = 48 B8
- ULONG_PTR interceptor_function;
- ULONG mov_rsp_rax; // = 48 89 04 24
- BYTE ret; // = C3
-};
-#pragma pack(pop)
-
-} // namespace.
-
-namespace sandbox {
-
-size_t ResolverThunk::GetInternalThunkSize() const {
- return sizeof(InternalThunk);
-}
-
-bool ResolverThunk::SetInternalThunk(void* storage, size_t storage_bytes,
- const void* original_function,
- const void* interceptor) {
- if (storage_bytes < sizeof(InternalThunk))
- return false;
-
- InternalThunk* thunk = new(storage, NT_PLACE) InternalThunk;
- thunk->interceptor_function = reinterpret_cast<ULONG_PTR>(interceptor);
-
- return true;
-}
-
-NTSTATUS ResolverThunk::ResolveTarget(const void* module,
- const char* function_name,
- void** address) {
- // We don't support sidestep & co.
- return STATUS_NOT_IMPLEMENTED;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/restricted_token.cc b/sandbox/win/src/restricted_token.cc
deleted file mode 100644
index 8a096a1..0000000
--- a/sandbox/win/src/restricted_token.cc
+++ /dev/null
@@ -1,466 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/restricted_token.h"
-
-#include <vector>
-
-#include "base/logging.h"
-#include "sandbox/win/src/acl.h"
-#include "sandbox/win/src/win_utils.h"
-
-
-namespace sandbox {
-
-unsigned RestrictedToken::Init(const HANDLE effective_token) {
- DCHECK(!init_);
- if (init_)
- return ERROR_ALREADY_INITIALIZED;
-
- if (effective_token) {
- // We duplicate the handle to be able to use it even if the original handle
- // is closed.
- HANDLE effective_token_dup;
- if (::DuplicateHandle(::GetCurrentProcess(),
- effective_token,
- ::GetCurrentProcess(),
- &effective_token_dup,
- DUPLICATE_SAME_ACCESS,
- FALSE,
- 0)) { // no special options
- effective_token_ = effective_token_dup;
- } else {
- return ::GetLastError();
- }
- } else {
- if (!::OpenProcessToken(::GetCurrentProcess(),
- TOKEN_ALL_ACCESS,
- &effective_token_))
- return ::GetLastError();
- }
-
- init_ = true;
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::GetRestrictedTokenHandle(HANDLE *token_handle) const {
- DCHECK(init_);
- if (!init_)
- return ERROR_NO_TOKEN;
-
- size_t deny_size = sids_for_deny_only_.size();
- size_t restrict_size = sids_to_restrict_.size();
- size_t privileges_size = privileges_to_disable_.size();
-
- SID_AND_ATTRIBUTES *deny_only_array = NULL;
- if (deny_size) {
- deny_only_array = new SID_AND_ATTRIBUTES[deny_size];
-
- for (unsigned int i = 0; i < sids_for_deny_only_.size() ; ++i) {
- deny_only_array[i].Attributes = SE_GROUP_USE_FOR_DENY_ONLY;
- deny_only_array[i].Sid =
- const_cast<SID*>(sids_for_deny_only_[i].GetPSID());
- }
- }
-
- SID_AND_ATTRIBUTES *sids_to_restrict_array = NULL;
- if (restrict_size) {
- sids_to_restrict_array = new SID_AND_ATTRIBUTES[restrict_size];
-
- for (unsigned int i = 0; i < restrict_size; ++i) {
- sids_to_restrict_array[i].Attributes = 0;
- sids_to_restrict_array[i].Sid =
- const_cast<SID*>(sids_to_restrict_[i].GetPSID());
- }
- }
-
- LUID_AND_ATTRIBUTES *privileges_to_disable_array = NULL;
- if (privileges_size) {
- privileges_to_disable_array = new LUID_AND_ATTRIBUTES[privileges_size];
-
- for (unsigned int i = 0; i < privileges_size; ++i) {
- privileges_to_disable_array[i].Attributes = 0;
- privileges_to_disable_array[i].Luid = privileges_to_disable_[i];
- }
- }
-
- BOOL result = TRUE;
- HANDLE new_token = NULL;
- // The SANDBOX_INERT flag did nothing in XP and it was just a way to tell
- // if a token has ben restricted given the limiations of IsTokenRestricted()
- // but it appears that in Windows 7 it hints the AppLocker subsystem to
- // leave us alone.
- if (deny_size || restrict_size || privileges_size) {
- result = ::CreateRestrictedToken(effective_token_,
- SANDBOX_INERT,
- static_cast<DWORD>(deny_size),
- deny_only_array,
- static_cast<DWORD>(privileges_size),
- privileges_to_disable_array,
- static_cast<DWORD>(restrict_size),
- sids_to_restrict_array,
- &new_token);
- } else {
- // Duplicate the token even if it's not modified at this point
- // because any subsequent changes to this token would also affect the
- // current process.
- result = ::DuplicateTokenEx(effective_token_, TOKEN_ALL_ACCESS, NULL,
- SecurityIdentification, TokenPrimary,
- &new_token);
- }
-
- if (deny_only_array)
- delete[] deny_only_array;
-
- if (sids_to_restrict_array)
- delete[] sids_to_restrict_array;
-
- if (privileges_to_disable_array)
- delete[] privileges_to_disable_array;
-
- if (!result)
- return ::GetLastError();
-
- // Modify the default dacl on the token to contain Restricted and the user.
- if (!AddSidToDefaultDacl(new_token, WinRestrictedCodeSid, GENERIC_ALL))
- return ::GetLastError();
-
- if (!AddUserSidToDefaultDacl(new_token, GENERIC_ALL))
- return ::GetLastError();
-
- DWORD error = SetTokenIntegrityLevel(new_token, integrity_level_);
- if (ERROR_SUCCESS != error)
- return error;
-
- BOOL status = ::DuplicateHandle(::GetCurrentProcess(),
- new_token,
- ::GetCurrentProcess(),
- token_handle,
- TOKEN_ALL_ACCESS,
- FALSE, // Don't inherit.
- 0);
-
- if (new_token != effective_token_)
- ::CloseHandle(new_token);
-
- if (!status)
- return ::GetLastError();
-
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::GetRestrictedTokenHandleForImpersonation(
- HANDLE *token_handle) const {
- DCHECK(init_);
- if (!init_)
- return ERROR_NO_TOKEN;
-
- HANDLE restricted_token_handle;
- unsigned err_code = GetRestrictedTokenHandle(&restricted_token_handle);
- if (ERROR_SUCCESS != err_code)
- return err_code;
-
- HANDLE impersonation_token;
- if (!::DuplicateToken(restricted_token_handle,
- SecurityImpersonation,
- &impersonation_token)) {
- ::CloseHandle(restricted_token_handle);
- return ::GetLastError();
- }
-
- ::CloseHandle(restricted_token_handle);
-
- BOOL status = ::DuplicateHandle(::GetCurrentProcess(),
- impersonation_token,
- ::GetCurrentProcess(),
- token_handle,
- TOKEN_ALL_ACCESS,
- FALSE, // Don't inherit.
- 0);
-
- ::CloseHandle(impersonation_token);
-
- if (!status)
- return ::GetLastError();
-
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::AddAllSidsForDenyOnly(std::vector<Sid> *exceptions) {
- DCHECK(init_);
- if (!init_)
- return ERROR_NO_TOKEN;
-
- TOKEN_GROUPS *token_groups = NULL;
- DWORD size = 0;
-
- BOOL result = ::GetTokenInformation(effective_token_,
- TokenGroups,
- NULL, // No buffer.
- 0, // Size is 0.
- &size);
- if (!size)
- return ::GetLastError();
-
- token_groups = reinterpret_cast<TOKEN_GROUPS*>(new BYTE[size]);
- result = ::GetTokenInformation(effective_token_,
- TokenGroups,
- token_groups,
- size,
- &size);
- if (!result) {
- delete[] reinterpret_cast<BYTE*>(token_groups);
- return ::GetLastError();
- }
-
- // Build the list of the deny only group SIDs
- for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) {
- if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0 &&
- (token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) == 0) {
- bool should_ignore = false;
- if (exceptions) {
- for (unsigned int j = 0; j < exceptions->size(); ++j) {
- if (::EqualSid(const_cast<SID*>((*exceptions)[j].GetPSID()),
- token_groups->Groups[i].Sid)) {
- should_ignore = true;
- break;
- }
- }
- }
- if (!should_ignore) {
- sids_for_deny_only_.push_back(
- reinterpret_cast<SID*>(token_groups->Groups[i].Sid));
- }
- }
- }
-
- delete[] reinterpret_cast<BYTE*>(token_groups);
-
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::AddSidForDenyOnly(const Sid &sid) {
- DCHECK(init_);
- if (!init_)
- return ERROR_NO_TOKEN;
-
- sids_for_deny_only_.push_back(sid);
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::AddUserSidForDenyOnly() {
- DCHECK(init_);
- if (!init_)
- return ERROR_NO_TOKEN;
-
- DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
- TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(new BYTE[size]);
-
- BOOL result = ::GetTokenInformation(effective_token_,
- TokenUser,
- token_user,
- size,
- &size);
-
- Sid user = reinterpret_cast<SID*>(token_user->User.Sid);
- delete[] reinterpret_cast<BYTE*>(token_user);
-
- if (!result)
- return ::GetLastError();
-
- sids_for_deny_only_.push_back(user);
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::DeleteAllPrivileges(
- const std::vector<std::wstring> *exceptions) {
- DCHECK(init_);
- if (!init_)
- return ERROR_NO_TOKEN;
-
- // Get the list of privileges in the token
- TOKEN_PRIVILEGES *token_privileges = NULL;
- DWORD size = 0;
-
- BOOL result = ::GetTokenInformation(effective_token_,
- TokenPrivileges,
- NULL, // No buffer.
- 0, // Size is 0.
- &size);
- if (!size)
- return ::GetLastError();
-
- token_privileges = reinterpret_cast<TOKEN_PRIVILEGES*>(new BYTE[size]);
- result = ::GetTokenInformation(effective_token_,
- TokenPrivileges,
- token_privileges,
- size,
- &size);
- if (!result) {
- delete[] reinterpret_cast<BYTE *>(token_privileges);
- return ::GetLastError();
- }
-
-
- // Build the list of privileges to disable
- for (unsigned int i = 0; i < token_privileges->PrivilegeCount; ++i) {
- bool should_ignore = false;
- if (exceptions) {
- for (unsigned int j = 0; j < exceptions->size(); ++j) {
- LUID luid = {0};
- ::LookupPrivilegeValue(NULL, (*exceptions)[j].c_str(), &luid);
- if (token_privileges->Privileges[i].Luid.HighPart == luid.HighPart &&
- token_privileges->Privileges[i].Luid.LowPart == luid.LowPart) {
- should_ignore = true;
- break;
- }
- }
- }
- if (!should_ignore) {
- privileges_to_disable_.push_back(token_privileges->Privileges[i].Luid);
- }
- }
-
- delete[] reinterpret_cast<BYTE *>(token_privileges);
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::DeletePrivilege(const wchar_t *privilege) {
- DCHECK(init_);
- if (!init_)
- return ERROR_NO_TOKEN;
-
- LUID luid = {0};
- if (LookupPrivilegeValue(NULL, privilege, &luid))
- privileges_to_disable_.push_back(luid);
- else
- return ::GetLastError();
-
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::AddRestrictingSid(const Sid &sid) {
- DCHECK(init_);
- if (!init_)
- return ERROR_NO_TOKEN;
-
- sids_to_restrict_.push_back(sid); // No attributes
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::AddRestrictingSidLogonSession() {
- DCHECK(init_);
- if (!init_)
- return ERROR_NO_TOKEN;
-
- TOKEN_GROUPS *token_groups = NULL;
- DWORD size = 0;
-
- BOOL result = ::GetTokenInformation(effective_token_,
- TokenGroups,
- NULL, // No buffer.
- 0, // Size is 0.
- &size);
- if (!size)
- return ::GetLastError();
-
- token_groups = reinterpret_cast<TOKEN_GROUPS*>(new BYTE[size]);
- result = ::GetTokenInformation(effective_token_,
- TokenGroups,
- token_groups,
- size,
- &size);
- if (!result) {
- delete[] reinterpret_cast<BYTE*>(token_groups);
- return ::GetLastError();
- }
-
- SID *logon_sid = NULL;
- for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) {
- if ((token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) != 0) {
- logon_sid = static_cast<SID*>(token_groups->Groups[i].Sid);
- break;
- }
- }
-
- if (logon_sid)
- sids_to_restrict_.push_back(logon_sid);
-
- delete[] reinterpret_cast<BYTE*>(token_groups);
-
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::AddRestrictingSidCurrentUser() {
- DCHECK(init_);
- if (!init_)
- return ERROR_NO_TOKEN;
-
- DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
- TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(new BYTE[size]);
-
- BOOL result = ::GetTokenInformation(effective_token_,
- TokenUser,
- token_user,
- size,
- &size);
-
- Sid user = reinterpret_cast<SID*>(token_user->User.Sid);
- delete[] reinterpret_cast<BYTE*>(token_user);
-
-
- if (!result)
- return ::GetLastError();
-
- sids_to_restrict_.push_back(user);
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::AddRestrictingSidAllSids() {
- DCHECK(init_);
- if (!init_)
- return ERROR_NO_TOKEN;
-
- // Add the current user to the list.
- unsigned error = AddRestrictingSidCurrentUser();
- if (ERROR_SUCCESS != error)
- return error;
-
- TOKEN_GROUPS *token_groups = NULL;
- DWORD size = 0;
-
- // Get the buffer size required.
- BOOL result = ::GetTokenInformation(effective_token_, TokenGroups, NULL, 0,
- &size);
- if (!size)
- return ::GetLastError();
-
- token_groups = reinterpret_cast<TOKEN_GROUPS*>(new BYTE[size]);
- result = ::GetTokenInformation(effective_token_,
- TokenGroups,
- token_groups,
- size,
- &size);
- if (!result) {
- delete[] reinterpret_cast<BYTE*>(token_groups);
- return ::GetLastError();
- }
-
- // Build the list of restricting sids from all groups.
- for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) {
- if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0)
- AddRestrictingSid(reinterpret_cast<SID*>(token_groups->Groups[i].Sid));
- }
-
- delete[] reinterpret_cast<BYTE*>(token_groups);
-
- return ERROR_SUCCESS;
-}
-
-unsigned RestrictedToken::SetIntegrityLevel(IntegrityLevel integrity_level) {
- integrity_level_ = integrity_level;
- return ERROR_SUCCESS;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/restricted_token.h b/sandbox/win/src/restricted_token.h
deleted file mode 100644
index 4327856..0000000
--- a/sandbox/win/src/restricted_token.h
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_RESTRICTED_TOKEN_H_
-#define SANDBOX_SRC_RESTRICTED_TOKEN_H_
-
-#include <windows.h>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/restricted_token_utils.h"
-#include "sandbox/win/src/security_level.h"
-#include "sandbox/win/src/sid.h"
-
-// Flags present in the Group SID list. These 2 flags are new in Windows Vista
-#ifndef SE_GROUP_INTEGRITY
-#define SE_GROUP_INTEGRITY (0x00000020L)
-#endif
-#ifndef SE_GROUP_INTEGRITY_ENABLED
-#define SE_GROUP_INTEGRITY_ENABLED (0x00000040L)
-#endif
-
-namespace sandbox {
-
-// Handles the creation of a restricted token using the effective token or
-// any token handle.
-// Sample usage:
-// RestrictedToken restricted_token;
-// unsigned err_code = restricted_token.Init(NULL); // Use the current
-// // effective token
-// if (ERROR_SUCCESS != err_code) {
-// // handle error.
-// }
-//
-// restricted_token.AddRestrictingSid(ATL::Sids::Users().GetPSID());
-// HANDLE token_handle;
-// err_code = restricted_token.GetRestrictedTokenHandle(&token_handle);
-// if (ERROR_SUCCESS != err_code) {
-// // handle error.
-// }
-// [...]
-// CloseHandle(token_handle);
-class RestrictedToken {
- public:
- // Init() has to be called before calling any other method in the class.
- RestrictedToken()
- : init_(false), effective_token_(NULL),
- integrity_level_(INTEGRITY_LEVEL_LAST) { }
-
- ~RestrictedToken() {
- if (effective_token_)
- CloseHandle(effective_token_);
- }
-
- // Initializes the RestrictedToken object with effective_token.
- // If effective_token is NULL, it initializes the RestrictedToken object with
- // the effective token of the current process.
- unsigned Init(HANDLE effective_token);
-
- // Creates a restricted token and returns its handle using the token_handle
- // output parameter. This handle has to be closed by the caller.
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- unsigned GetRestrictedTokenHandle(HANDLE *token_handle) const;
-
- // Creates a restricted token and uses this new token to create a new token
- // for impersonation. Returns the handle of this impersonation token using
- // the token_handle output parameter. This handle has to be closed by
- // the caller.
- //
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- //
- // The sample usage is the same as the GetRestrictedTokenHandle function.
- unsigned GetRestrictedTokenHandleForImpersonation(HANDLE *token_handle) const;
-
- // Lists all sids in the token and mark them as Deny Only except for those
- // present in the exceptions parameter. If there is no exception needed,
- // the caller can pass an empty list or NULL for the exceptions
- // parameter.
- //
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- //
- // Sample usage:
- // std::vector<Sid> sid_exceptions;
- // sid_exceptions.push_back(ATL::Sids::Users().GetPSID());
- // sid_exceptions.push_back(ATL::Sids::World().GetPSID());
- // restricted_token.AddAllSidsForDenyOnly(&sid_exceptions);
- // Note: A Sid marked for Deny Only in a token cannot be used to grant
- // access to any resource. It can only be used to deny access.
- unsigned AddAllSidsForDenyOnly(std::vector<Sid> *exceptions);
-
- // Adds a user or group SID for Deny Only in the restricted token.
- // Parameter: sid is the SID to add in the Deny Only list.
- // The return value is always ERROR_SUCCESS.
- //
- // Sample Usage:
- // restricted_token.AddSidForDenyOnly(ATL::Sids::Admins().GetPSID());
- unsigned AddSidForDenyOnly(const Sid &sid);
-
- // Adds the user sid of the token for Deny Only in the restricted token.
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- unsigned AddUserSidForDenyOnly();
-
- // Lists all privileges in the token and add them to the list of privileges
- // to remove except for those present in the exceptions parameter. If
- // there is no exception needed, the caller can pass an empty list or NULL
- // for the exceptions parameter.
- //
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- //
- // Sample usage:
- // std::vector<std::wstring> privilege_exceptions;
- // privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
- // restricted_token.DeleteAllPrivileges(&privilege_exceptions);
- unsigned DeleteAllPrivileges(
- const std::vector<std::wstring> *exceptions);
-
- // Adds a privilege to the list of privileges to remove in the restricted
- // token.
- // Parameter: privilege is the privilege name to remove. This is the string
- // representing the privilege. (e.g. "SeChangeNotifyPrivilege").
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- //
- // Sample usage:
- // restricted_token.DeletePrivilege(SE_LOAD_DRIVER_NAME);
- unsigned DeletePrivilege(const wchar_t *privilege);
-
- // Adds a SID to the list of restricting sids in the restricted token.
- // Parameter: sid is the sid to add to the list restricting sids.
- // The return value is always ERROR_SUCCESS.
- //
- // Sample usage:
- // restricted_token.AddRestrictingSid(ATL::Sids::Users().GetPSID());
- // Note: The list of restricting is used to force Windows to perform all
- // access checks twice. The first time using your user SID and your groups,
- // and the second time using your list of restricting sids. The access has
- // to be granted in both places to get access to the resource requested.
- unsigned AddRestrictingSid(const Sid &sid);
-
- // Adds the logon sid of the token in the list of restricting sids for the
- // restricted token.
- //
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- unsigned AddRestrictingSidLogonSession();
-
- // Adds the owner sid of the token in the list of restricting sids for the
- // restricted token.
- //
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- unsigned AddRestrictingSidCurrentUser();
-
- // Adds all group sids and the user sid to the restricting sids list.
- //
- // If the function succeeds, the return value is ERROR_SUCCESS. If the
- // function fails, the return value is the win32 error code corresponding to
- // the error.
- unsigned AddRestrictingSidAllSids();
-
- // Sets the token integrity level. This is only valid on Vista. The integrity
- // level cannot be higher than your current integrity level.
- unsigned SetIntegrityLevel(IntegrityLevel integrity_level);
-
- private:
- // The list of restricting sids in the restricted token.
- std::vector<Sid> sids_to_restrict_;
- // The list of privileges to remove in the restricted token.
- std::vector<LUID> privileges_to_disable_;
- // The list of sids to mark as Deny Only in the restricted token.
- std::vector<Sid> sids_for_deny_only_;
- // The token to restrict. Can only be set in a constructor.
- HANDLE effective_token_;
- // The token integrity level. Only valid on Vista.
- IntegrityLevel integrity_level_;
- // Tells if the object is initialized or not (if Init() has been called)
- bool init_;
-
- DISALLOW_COPY_AND_ASSIGN(RestrictedToken);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_RESTRICTED_TOKEN_H_
diff --git a/sandbox/win/src/restricted_token_unittest.cc b/sandbox/win/src/restricted_token_unittest.cc
deleted file mode 100644
index df35f1c..0000000
--- a/sandbox/win/src/restricted_token_unittest.cc
+++ /dev/null
@@ -1,530 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains unit tests for the RestrictedToken.
-
-#define _ATL_NO_EXCEPTIONS
-#include <atlbase.h>
-#include <atlsecurity.h>
-#include <vector>
-#include "sandbox/win/src/restricted_token.h"
-#include "sandbox/win/src/sid.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace sandbox {
-
-// Tests the initializatioin with an invalid token handle.
-TEST(RestrictedTokenTest, InvalidHandle) {
- RestrictedToken token;
- ASSERT_EQ(ERROR_INVALID_HANDLE, token.Init(reinterpret_cast<HANDLE>(0x5555)));
-}
-
-// Tests the initialization with NULL as parameter.
-TEST(RestrictedTokenTest, DefaultInit) {
- // Get the current process token.
- HANDLE token_handle = INVALID_HANDLE_VALUE;
- ASSERT_TRUE(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
- &token_handle));
-
- ASSERT_NE(INVALID_HANDLE_VALUE, token_handle);
-
- ATL::CAccessToken access_token;
- access_token.Attach(token_handle);
-
- // Create the token using the current token.
- RestrictedToken token_default;
- ASSERT_EQ(ERROR_SUCCESS, token_default.Init(NULL));
-
- // Get the handle to the restricted token.
-
- HANDLE restricted_token_handle = NULL;
- ASSERT_EQ(ERROR_SUCCESS,
- token_default.GetRestrictedTokenHandle(&restricted_token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(restricted_token_handle);
-
- ATL::CSid sid_user_restricted;
- ATL::CSid sid_user_default;
- ATL::CSid sid_owner_restricted;
- ATL::CSid sid_owner_default;
- ASSERT_TRUE(restricted_token.GetUser(&sid_user_restricted));
- ASSERT_TRUE(access_token.GetUser(&sid_user_default));
- ASSERT_TRUE(restricted_token.GetOwner(&sid_owner_restricted));
- ASSERT_TRUE(access_token.GetOwner(&sid_owner_default));
-
- // Check if both token have the same owner and user.
- ASSERT_EQ(sid_user_restricted, sid_user_default);
- ASSERT_EQ(sid_owner_restricted, sid_owner_default);
-}
-
-// Tests the initialization with a custom token as parameter.
-TEST(RestrictedTokenTest, CustomInit) {
- // Get the current process token.
- HANDLE token_handle = INVALID_HANDLE_VALUE;
- ASSERT_TRUE(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
- &token_handle));
-
- ASSERT_NE(INVALID_HANDLE_VALUE, token_handle);
-
- ATL::CAccessToken access_token;
- access_token.Attach(token_handle);
-
- // Change the primary group.
- access_token.SetPrimaryGroup(ATL::Sids::World());
-
- // Create the token using the current token.
- RestrictedToken token;
- ASSERT_EQ(ERROR_SUCCESS, token.Init(access_token.GetHandle()));
-
- // Get the handle to the restricted token.
-
- HANDLE restricted_token_handle = NULL;
- ASSERT_EQ(ERROR_SUCCESS,
- token.GetRestrictedTokenHandle(&restricted_token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(restricted_token_handle);
-
- ATL::CSid sid_restricted;
- ATL::CSid sid_default;
- ASSERT_TRUE(restricted_token.GetPrimaryGroup(&sid_restricted));
- ASSERT_TRUE(access_token.GetPrimaryGroup(&sid_default));
-
- // Check if both token have the same owner.
- ASSERT_EQ(sid_restricted, sid_default);
-}
-
-// Verifies that the token created by the object are valid.
-TEST(RestrictedTokenTest, ResultToken) {
- RestrictedToken token;
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
-
- ASSERT_EQ(ERROR_SUCCESS,
- token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
-
- HANDLE restricted_token;
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&restricted_token));
-
- ASSERT_TRUE(::IsTokenRestricted(restricted_token));
-
- DWORD length = 0;
- TOKEN_TYPE type;
- ASSERT_TRUE(::GetTokenInformation(restricted_token,
- ::TokenType,
- &type,
- sizeof(type),
- &length));
-
- ASSERT_EQ(type, TokenPrimary);
-
- HANDLE impersonation_token;
- ASSERT_EQ(ERROR_SUCCESS,
- token.GetRestrictedTokenHandleForImpersonation(&impersonation_token));
-
- ASSERT_TRUE(::IsTokenRestricted(impersonation_token));
-
- ASSERT_TRUE(::GetTokenInformation(impersonation_token,
- ::TokenType,
- &type,
- sizeof(type),
- &length));
-
- ASSERT_EQ(type, TokenImpersonation);
-
- ::CloseHandle(impersonation_token);
- ::CloseHandle(restricted_token);
-}
-
-// Verifies that the token created has "Restricted" in its default dacl.
-TEST(RestrictedTokenTest, DefaultDacl) {
- RestrictedToken token;
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
-
- ASSERT_EQ(ERROR_SUCCESS,
- token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
-
- HANDLE handle;
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(handle);
-
- ATL::CDacl dacl;
- ASSERT_TRUE(restricted_token.GetDefaultDacl(&dacl));
-
- bool restricted_found = false;
-
- unsigned int ace_count = dacl.GetAceCount();
- for (unsigned int i = 0; i < ace_count ; ++i) {
- ATL::CSid sid;
- ACCESS_MASK mask = 0;
- dacl.GetAclEntry(i, &sid, &mask);
- if (sid == ATL::Sids::RestrictedCode() && mask == GENERIC_ALL) {
- restricted_found = true;
- break;
- }
- }
-
- ASSERT_TRUE(restricted_found);
-}
-
-// Tests the method "AddSidForDenyOnly".
-TEST(RestrictedTokenTest, DenySid) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.AddSidForDenyOnly(Sid(WinWorldSid)));
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
-
- ATL::CTokenGroups groups;
- ASSERT_TRUE(restricted_token.GetGroups(&groups));
-
- ATL::CSid::CSidArray sids;
- ATL::CAtlArray<DWORD> attributes;
- groups.GetSidsAndAttributes(&sids, &attributes);
-
- for (unsigned int i = 0; i < sids.GetCount(); i++) {
- if (ATL::Sids::World() == sids[i]) {
- ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
- attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
- }
- }
-}
-
-// Tests the method "AddAllSidsForDenyOnly".
-TEST(RestrictedTokenTest, DenySids) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.AddAllSidsForDenyOnly(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
-
- ATL::CTokenGroups groups;
- ASSERT_TRUE(restricted_token.GetGroups(&groups));
-
- ATL::CSid::CSidArray sids;
- ATL::CAtlArray<DWORD> attributes;
- groups.GetSidsAndAttributes(&sids, &attributes);
-
- // Verify that all sids are really gone.
- for (unsigned int i = 0; i < sids.GetCount(); i++) {
- if ((attributes[i] & SE_GROUP_LOGON_ID) == 0 &&
- (attributes[i] & SE_GROUP_INTEGRITY) == 0) {
- ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
- attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
- }
- }
-}
-
-// Tests the method "AddAllSidsForDenyOnly" using an exception list.
-TEST(RestrictedTokenTest, DenySidsException) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- std::vector<Sid> sids_exception;
- sids_exception.push_back(Sid(WinWorldSid));
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.AddAllSidsForDenyOnly(&sids_exception));
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
-
- ATL::CTokenGroups groups;
- ASSERT_TRUE(restricted_token.GetGroups(&groups));
-
- ATL::CSid::CSidArray sids;
- ATL::CAtlArray<DWORD> attributes;
- groups.GetSidsAndAttributes(&sids, &attributes);
-
- // Verify that all sids are really gone.
- for (unsigned int i = 0; i < sids.GetCount(); i++) {
- if ((attributes[i] & SE_GROUP_LOGON_ID) == 0 &&
- (attributes[i] & SE_GROUP_INTEGRITY) == 0) {
- if (ATL::Sids::World() == sids[i]) {
- ASSERT_EQ(NULL, attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
- } else {
- ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
- attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
- }
- }
- }
-}
-
-// Tests test method AddOwnerSidForDenyOnly.
-TEST(RestrictedTokenTest, DenyOwnerSid) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.AddUserSidForDenyOnly());
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
-
- ATL::CTokenGroups groups;
- ASSERT_TRUE(restricted_token.GetGroups(&groups));
-
- ATL::CSid::CSidArray sids;
- ATL::CAtlArray<DWORD> attributes;
- groups.GetSidsAndAttributes(&sids, &attributes);
-
- ATL::CSid user_sid;
- ASSERT_TRUE(restricted_token.GetUser(&user_sid));
-
- for (unsigned int i = 0; i < sids.GetCount(); ++i) {
- if (user_sid == sids[i]) {
- ASSERT_EQ(SE_GROUP_USE_FOR_DENY_ONLY,
- attributes[i] & SE_GROUP_USE_FOR_DENY_ONLY);
- }
- }
-}
-
-// Tests the method DeleteAllPrivileges.
-TEST(RestrictedTokenTest, DeleteAllPrivileges) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.DeleteAllPrivileges(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
-
- ATL::CTokenPrivileges privileges;
- ASSERT_TRUE(restricted_token.GetPrivileges(&privileges));
-
- ASSERT_EQ(0, privileges.GetCount());
-}
-
-// Tests the method DeleteAllPrivileges with an exception list.
-TEST(RestrictedTokenTest, DeleteAllPrivilegesException) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- std::vector<std::wstring> exceptions;
- exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.DeleteAllPrivileges(&exceptions));
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
-
- ATL::CTokenPrivileges privileges;
- ASSERT_TRUE(restricted_token.GetPrivileges(&privileges));
-
- ATL::CTokenPrivileges::CNames privilege_names;
- ATL::CTokenPrivileges::CAttributes privilege_name_attributes;
- privileges.GetNamesAndAttributes(&privilege_names,
- &privilege_name_attributes);
-
- ASSERT_EQ(1, privileges.GetCount());
-
- for (unsigned int i = 0; i < privileges.GetCount(); ++i) {
- ASSERT_EQ(privilege_names[i], SE_CHANGE_NOTIFY_NAME);
- }
-}
-
-// Tests the method DeletePrivilege.
-TEST(RestrictedTokenTest, DeletePrivilege) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.DeletePrivilege(SE_CHANGE_NOTIFY_NAME));
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
-
- ATL::CTokenPrivileges privileges;
- ASSERT_TRUE(restricted_token.GetPrivileges(&privileges));
-
- ATL::CTokenPrivileges::CNames privilege_names;
- ATL::CTokenPrivileges::CAttributes privilege_name_attributes;
- privileges.GetNamesAndAttributes(&privilege_names,
- &privilege_name_attributes);
-
- for (unsigned int i = 0; i < privileges.GetCount(); ++i) {
- ASSERT_NE(privilege_names[i], SE_CHANGE_NOTIFY_NAME);
- }
-}
-
-// Checks if a sid is in the restricting list of the restricted token.
-// Asserts if it's not the case. If count is a positive number, the number of
-// elements in the restricting sids list has to be equal.
-void CheckRestrictingSid(const ATL::CAccessToken &restricted_token,
- ATL::CSid sid, int count) {
- DWORD length = 1000;
- BYTE *memory = new BYTE[1000];
- TOKEN_GROUPS *groups = reinterpret_cast<TOKEN_GROUPS*>(memory);
- ASSERT_TRUE(::GetTokenInformation(restricted_token.GetHandle(),
- TokenRestrictedSids,
- groups,
- length,
- &length));
-
- ATL::CTokenGroups atl_groups(*groups);
- delete[] memory;
-
- if (count >= 0)
- ASSERT_EQ(count, atl_groups.GetCount());
-
- ATL::CSid::CSidArray sids;
- ATL::CAtlArray<DWORD> attributes;
- atl_groups.GetSidsAndAttributes(&sids, &attributes);
-
- bool present = false;
- for (unsigned int i = 0; i < sids.GetCount(); ++i) {
- if (sids[i] == sid) {
- present = true;
- break;
- }
- }
-
- ASSERT_TRUE(present);
-}
-
-// Tests the method AddRestrictingSid.
-TEST(RestrictedTokenTest, AddRestrictingSid) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS,
- token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
-
- CheckRestrictingSid(restricted_token, ATL::Sids::World(), 1);
-}
-
-// Tests the method AddRestrictingSidCurrentUser.
-TEST(RestrictedTokenTest, AddRestrictingSidCurrentUser) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidCurrentUser());
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
- ATL::CSid user;
- restricted_token.GetUser(&user);
-
- CheckRestrictingSid(restricted_token, user, 1);
-}
-
-// Tests the method AddRestrictingSidLogonSession.
-TEST(RestrictedTokenTest, AddRestrictingSidLogonSession) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidLogonSession());
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
- ATL::CSid session;
- restricted_token.GetLogonSid(&session);
-
- CheckRestrictingSid(restricted_token, session, 1);
-}
-
-// Tests adding a lot of restricting sids.
-TEST(RestrictedTokenTest, AddMultipleRestrictingSids) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidCurrentUser());
- ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidLogonSession());
- ASSERT_EQ(ERROR_SUCCESS,
- token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
- ATL::CSid session;
- restricted_token.GetLogonSid(&session);
-
- DWORD length = 1000;
- BYTE *memory = new BYTE[1000];
- TOKEN_GROUPS *groups = reinterpret_cast<TOKEN_GROUPS*>(memory);
- ASSERT_TRUE(::GetTokenInformation(restricted_token.GetHandle(),
- TokenRestrictedSids,
- groups,
- length,
- &length));
-
- ATL::CTokenGroups atl_groups(*groups);
- delete[] memory;
-
- ASSERT_EQ(3, atl_groups.GetCount());
-}
-
-// Tests the method "AddRestrictingSidAllSids".
-TEST(RestrictedTokenTest, AddAllSidToRestrictingSids) {
- RestrictedToken token;
- HANDLE token_handle = NULL;
-
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
- ASSERT_EQ(ERROR_SUCCESS, token.AddRestrictingSidAllSids());
- ASSERT_EQ(ERROR_SUCCESS, token.GetRestrictedTokenHandle(&token_handle));
-
- ATL::CAccessToken restricted_token;
- restricted_token.Attach(token_handle);
-
- ATL::CTokenGroups groups;
- ASSERT_TRUE(restricted_token.GetGroups(&groups));
-
- ATL::CSid::CSidArray sids;
- ATL::CAtlArray<DWORD> attributes;
- groups.GetSidsAndAttributes(&sids, &attributes);
-
- // Verify that all group sids are in the restricting sid list.
- for (unsigned int i = 0; i < sids.GetCount(); i++) {
- if ((attributes[i] & SE_GROUP_INTEGRITY) == 0) {
- CheckRestrictingSid(restricted_token, sids[i], -1);
- }
- }
-
- // Verify that the user is in the restricting sid list.
- ATL::CSid user;
- restricted_token.GetUser(&user);
- CheckRestrictingSid(restricted_token, user, -1);
-}
-
-// Test to be executed only in release because they are triggering DCHECKs.
-#ifndef _DEBUG
-
-// Checks the error code when the object is initialized twice.
-TEST(RestrictedTokenTest, DoubleInit) {
- RestrictedToken token;
- ASSERT_EQ(ERROR_SUCCESS, token.Init(NULL));
-
- ASSERT_EQ(ERROR_ALREADY_INITIALIZED, token.Init(NULL));
-}
-
-#endif
-
-} // namespace sandbox
diff --git a/sandbox/win/src/restricted_token_utils.cc b/sandbox/win/src/restricted_token_utils.cc
deleted file mode 100644
index 5f1a246..0000000
--- a/sandbox/win/src/restricted_token_utils.cc
+++ /dev/null
@@ -1,344 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <aclapi.h>
-#include <sddl.h>
-#include <vector>
-
-#include "sandbox/win/src/restricted_token_utils.h"
-
-#include "base/logging.h"
-#include "base/win/scoped_handle.h"
-#include "base/win/scoped_process_information.h"
-#include "base/win/windows_version.h"
-#include "sandbox/win/src/job.h"
-#include "sandbox/win/src/restricted_token.h"
-#include "sandbox/win/src/security_level.h"
-#include "sandbox/win/src/sid.h"
-
-namespace sandbox {
-
-DWORD CreateRestrictedToken(HANDLE *token_handle,
- TokenLevel security_level,
- IntegrityLevel integrity_level,
- TokenType token_type) {
- if (!token_handle)
- return ERROR_BAD_ARGUMENTS;
-
- RestrictedToken restricted_token;
- restricted_token.Init(NULL); // Initialized with the current process token
-
- std::vector<std::wstring> privilege_exceptions;
- std::vector<Sid> sid_exceptions;
-
- bool deny_sids = true;
- bool remove_privileges = true;
-
- switch (security_level) {
- case USER_UNPROTECTED: {
- deny_sids = false;
- remove_privileges = false;
- break;
- }
- case USER_RESTRICTED_SAME_ACCESS: {
- deny_sids = false;
- remove_privileges = false;
-
- unsigned err_code = restricted_token.AddRestrictingSidAllSids();
- if (ERROR_SUCCESS != err_code)
- return err_code;
-
- break;
- }
- case USER_NON_ADMIN: {
- sid_exceptions.push_back(WinBuiltinUsersSid);
- sid_exceptions.push_back(WinWorldSid);
- sid_exceptions.push_back(WinInteractiveSid);
- sid_exceptions.push_back(WinAuthenticatedUserSid);
- privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
- break;
- }
- case USER_INTERACTIVE: {
- sid_exceptions.push_back(WinBuiltinUsersSid);
- sid_exceptions.push_back(WinWorldSid);
- sid_exceptions.push_back(WinInteractiveSid);
- sid_exceptions.push_back(WinAuthenticatedUserSid);
- privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
- restricted_token.AddRestrictingSid(WinBuiltinUsersSid);
- restricted_token.AddRestrictingSid(WinWorldSid);
- restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
- restricted_token.AddRestrictingSidCurrentUser();
- restricted_token.AddRestrictingSidLogonSession();
- break;
- }
- case USER_LIMITED: {
- sid_exceptions.push_back(WinBuiltinUsersSid);
- sid_exceptions.push_back(WinWorldSid);
- sid_exceptions.push_back(WinInteractiveSid);
- privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
- restricted_token.AddRestrictingSid(WinBuiltinUsersSid);
- restricted_token.AddRestrictingSid(WinWorldSid);
- restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
-
- // This token has to be able to create objects in BNO.
- // Unfortunately, on vista, it needs the current logon sid
- // in the token to achieve this. You should also set the process to be
- // low integrity level so it can't access object created by other
- // processes.
- if (base::win::GetVersion() >= base::win::VERSION_VISTA)
- restricted_token.AddRestrictingSidLogonSession();
- break;
- }
- case USER_RESTRICTED: {
- privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
- restricted_token.AddUserSidForDenyOnly();
- restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
- break;
- }
- case USER_LOCKDOWN: {
- restricted_token.AddUserSidForDenyOnly();
- restricted_token.AddRestrictingSid(WinNullSid);
- break;
- }
- default: {
- return ERROR_BAD_ARGUMENTS;
- }
- }
-
- DWORD err_code = ERROR_SUCCESS;
- if (deny_sids) {
- err_code = restricted_token.AddAllSidsForDenyOnly(&sid_exceptions);
- if (ERROR_SUCCESS != err_code)
- return err_code;
- }
-
- if (remove_privileges) {
- err_code = restricted_token.DeleteAllPrivileges(&privilege_exceptions);
- if (ERROR_SUCCESS != err_code)
- return err_code;
- }
-
- restricted_token.SetIntegrityLevel(integrity_level);
-
- switch (token_type) {
- case PRIMARY: {
- err_code = restricted_token.GetRestrictedTokenHandle(token_handle);
- break;
- }
- case IMPERSONATION: {
- err_code = restricted_token.GetRestrictedTokenHandleForImpersonation(
- token_handle);
- break;
- }
- default: {
- err_code = ERROR_BAD_ARGUMENTS;
- break;
- }
- }
-
- return err_code;
-}
-
-DWORD StartRestrictedProcessInJob(wchar_t *command_line,
- TokenLevel primary_level,
- TokenLevel impersonation_level,
- JobLevel job_level,
- HANDLE *const job_handle_ret) {
- Job job;
- DWORD err_code = job.Init(job_level, NULL, 0);
- if (ERROR_SUCCESS != err_code)
- return err_code;
-
- if (JOB_UNPROTECTED != job_level) {
- // Share the Desktop handle to be able to use MessageBox() in the sandboxed
- // application.
- err_code = job.UserHandleGrantAccess(GetDesktopWindow());
- if (ERROR_SUCCESS != err_code)
- return err_code;
- }
-
- // Create the primary (restricted) token for the process
- HANDLE primary_token_handle = NULL;
- err_code = CreateRestrictedToken(&primary_token_handle,
- primary_level,
- INTEGRITY_LEVEL_LAST,
- PRIMARY);
- if (ERROR_SUCCESS != err_code) {
- return err_code;
- }
- base::win::ScopedHandle primary_token(primary_token_handle);
-
- // Create the impersonation token (restricted) to be able to start the
- // process.
- HANDLE impersonation_token_handle;
- err_code = CreateRestrictedToken(&impersonation_token_handle,
- impersonation_level,
- INTEGRITY_LEVEL_LAST,
- IMPERSONATION);
- if (ERROR_SUCCESS != err_code) {
- return err_code;
- }
- base::win::ScopedHandle impersonation_token(impersonation_token_handle);
-
- // Start the process
- STARTUPINFO startup_info = {0};
- base::win::ScopedProcessInformation process_info;
- DWORD flags = CREATE_SUSPENDED;
-
- if (base::win::GetVersion() < base::win::VERSION_WIN8) {
- // Windows 8 implements nested jobs, but for older systems we need to
- // break out of any job we're in to enforce our restrictions.
- flags |= CREATE_BREAKAWAY_FROM_JOB;
- }
-
- if (!::CreateProcessAsUser(primary_token.Get(),
- NULL, // No application name.
- command_line,
- NULL, // No security attribute.
- NULL, // No thread attribute.
- FALSE, // Do not inherit handles.
- flags,
- NULL, // Use the environment of the caller.
- NULL, // Use current directory of the caller.
- &startup_info,
- process_info.Receive())) {
- return ::GetLastError();
- }
-
- // Change the token of the main thread of the new process for the
- // impersonation token with more rights.
- {
- HANDLE temp_thread = process_info.thread_handle();
- if (!::SetThreadToken(&temp_thread, impersonation_token.Get())) {
- ::TerminateProcess(process_info.process_handle(),
- 0); // exit code
- return ::GetLastError();
- }
- }
-
- err_code = job.AssignProcessToJob(process_info.process_handle());
- if (ERROR_SUCCESS != err_code) {
- ::TerminateProcess(process_info.process_handle(),
- 0); // exit code
- return ::GetLastError();
- }
-
- // Start the application
- ::ResumeThread(process_info.thread_handle());
-
- (*job_handle_ret) = job.Detach();
-
- return ERROR_SUCCESS;
-}
-
-DWORD SetObjectIntegrityLabel(HANDLE handle, SE_OBJECT_TYPE type,
- const wchar_t* ace_access,
- const wchar_t* integrity_level_sid) {
- // Build the SDDL string for the label.
- std::wstring sddl = L"S:("; // SDDL for a SACL.
- sddl += SDDL_MANDATORY_LABEL; // Ace Type is "Mandatory Label".
- sddl += L";;"; // No Ace Flags.
- sddl += ace_access; // Add the ACE access.
- sddl += L";;;"; // No ObjectType and Inherited Object Type.
- sddl += integrity_level_sid; // Trustee Sid.
- sddl += L")";
-
- DWORD error = ERROR_SUCCESS;
- PSECURITY_DESCRIPTOR sec_desc = NULL;
-
- PACL sacl = NULL;
- BOOL sacl_present = FALSE;
- BOOL sacl_defaulted = FALSE;
-
- if (::ConvertStringSecurityDescriptorToSecurityDescriptorW(sddl.c_str(),
- SDDL_REVISION,
- &sec_desc, NULL)) {
- if (::GetSecurityDescriptorSacl(sec_desc, &sacl_present, &sacl,
- &sacl_defaulted)) {
- error = ::SetSecurityInfo(handle, type,
- LABEL_SECURITY_INFORMATION, NULL, NULL, NULL,
- sacl);
- } else {
- error = ::GetLastError();
- }
-
- ::LocalFree(sec_desc);
- } else {
- return::GetLastError();
- }
-
- return error;
-}
-
-const wchar_t* GetIntegrityLevelString(IntegrityLevel integrity_level) {
- switch (integrity_level) {
- case INTEGRITY_LEVEL_SYSTEM:
- return L"S-1-16-16384";
- case INTEGRITY_LEVEL_HIGH:
- return L"S-1-16-12288";
- case INTEGRITY_LEVEL_MEDIUM:
- return L"S-1-16-8192";
- case INTEGRITY_LEVEL_MEDIUM_LOW:
- return L"S-1-16-6144";
- case INTEGRITY_LEVEL_LOW:
- return L"S-1-16-4096";
- case INTEGRITY_LEVEL_BELOW_LOW:
- return L"S-1-16-2048";
- case INTEGRITY_LEVEL_UNTRUSTED:
- return L"S-1-16-0";
- case INTEGRITY_LEVEL_LAST:
- return NULL;
- }
-
- NOTREACHED();
- return NULL;
-}
-DWORD SetTokenIntegrityLevel(HANDLE token, IntegrityLevel integrity_level) {
- if (base::win::GetVersion() < base::win::VERSION_VISTA)
- return ERROR_SUCCESS;
-
- const wchar_t* integrity_level_str = GetIntegrityLevelString(integrity_level);
- if (!integrity_level_str) {
- // No mandatory level specified, we don't change it.
- return ERROR_SUCCESS;
- }
-
- PSID integrity_sid = NULL;
- if (!::ConvertStringSidToSid(integrity_level_str, &integrity_sid))
- return ::GetLastError();
-
- TOKEN_MANDATORY_LABEL label = {0};
- label.Label.Attributes = SE_GROUP_INTEGRITY;
- label.Label.Sid = integrity_sid;
-
- DWORD size = sizeof(TOKEN_MANDATORY_LABEL) + ::GetLengthSid(integrity_sid);
- BOOL result = ::SetTokenInformation(token, TokenIntegrityLevel, &label,
- size);
- ::LocalFree(integrity_sid);
-
- return result ? ERROR_SUCCESS : ::GetLastError();
-}
-
-DWORD SetProcessIntegrityLevel(IntegrityLevel integrity_level) {
- if (base::win::GetVersion() < base::win::VERSION_VISTA)
- return ERROR_SUCCESS;
-
- // We don't check for an invalid level here because we'll just let it
- // fail on the SetTokenIntegrityLevel call later on.
- if (integrity_level == INTEGRITY_LEVEL_LAST) {
- // No mandatory level specified, we don't change it.
- return ERROR_SUCCESS;
- }
-
- HANDLE token_handle;
- if (!::OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_DEFAULT,
- &token_handle))
- return ::GetLastError();
-
- base::win::ScopedHandle token(token_handle);
-
- return SetTokenIntegrityLevel(token.Get(), integrity_level);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/restricted_token_utils.h b/sandbox/win/src/restricted_token_utils.h
deleted file mode 100644
index f2a280a..0000000
--- a/sandbox/win/src/restricted_token_utils.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_RESTRICTED_TOKEN_UTILS_H__
-#define SANDBOX_SRC_RESTRICTED_TOKEN_UTILS_H__
-
-#include <accctrl.h>
-#include <windows.h>
-
-#include "sandbox/win/src/restricted_token.h"
-#include "sandbox/win/src/security_level.h"
-
-// Contains the utility functions to be able to create restricted tokens based
-// on a security profiles.
-
-namespace sandbox {
-
-// The type of the token returned by the CreateNakedToken.
-enum TokenType {
- IMPERSONATION = 0,
- PRIMARY
-};
-
-// Creates a restricted token based on the effective token of the current
-// process. The parameter security_level determines how much the token is
-// restricted. The token_type determines if the token will be used as a primary
-// token or impersonation token. The integrity level of the token is set to
-// |integrity level| on Vista only.
-// token_handle is the output value containing the handle of the
-// newly created restricted token.
-// If the function succeeds, the return value is ERROR_SUCCESS. If the
-// function fails, the return value is the win32 error code corresponding to
-// the error.
-DWORD CreateRestrictedToken(HANDLE *token_handle,
- TokenLevel security_level,
- IntegrityLevel integrity_level,
- TokenType token_type);
-
-// Starts the process described by the input parameter command_line in a job
-// with a restricted token. Also set the main thread of this newly created
-// process to impersonate a user with more rights so it can initialize
-// correctly.
-//
-// Parameters: primary_level is the security level of the primary token.
-// impersonation_level is the security level of the impersonation token used
-// to initialize the process. job_level is the security level of the job
-// object used to encapsulate the process.
-//
-// The output parameter job_handle is the handle to the job object. It has
-// to be closed with CloseHandle() when not needed. Closing this handle will
-// kill the process started.
-//
-// Note: The process started with this function has to call RevertToSelf() as
-// soon as possible to stop using the impersonation token and start being
-// secure.
-//
-// Note: The Unicode version of this function will fail if the command_line
-// parameter is a const string.
-DWORD StartRestrictedProcessInJob(wchar_t *command_line,
- TokenLevel primary_level,
- TokenLevel impersonation_level,
- JobLevel job_level,
- HANDLE *job_handle);
-
-// Sets the integrity label on a object handle.
-DWORD SetObjectIntegrityLabel(HANDLE handle, SE_OBJECT_TYPE type,
- const wchar_t* ace_access,
- const wchar_t* integrity_level_sid);
-
-// Sets the integrity level on a token. This is only valid on Vista. It returns
-// without failing on XP. If the integrity level that you specify is greater
-// than the current integrity level, the function will fail.
-DWORD SetTokenIntegrityLevel(HANDLE token, IntegrityLevel integrity_level);
-
-// Sets the integrity level on the current process on Vista. It returns without
-// failing on XP. If the integrity level that you specify is greater than the
-// current integrity level, the function will fail.
-DWORD SetProcessIntegrityLevel(IntegrityLevel integrity_level);
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_RESTRICTED_TOKEN_UTILS_H__
diff --git a/sandbox/win/src/sandbox.cc b/sandbox/win/src/sandbox.cc
deleted file mode 100644
index 3344ba4..0000000
--- a/sandbox/win/src/sandbox.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdio.h>
-#include <windows.h>
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/broker_services.h"
-#include "sandbox/win/src/target_services.h"
-
-#if defined(_WIN64) && !defined(NACL_WIN64)
-// We allow building this code for Win64 as part of NaCl to enable development
-#error Sandbox code was not tested on 64-bit Windows. See \
- http://crbug.com/27218 for details and progress log.
-#endif
-
-
-namespace sandbox {
-// The section for IPC and policy.
-SANDBOX_INTERCEPT HANDLE g_shared_section = NULL;
-
-static bool s_is_broker = false;
-
-// GetBrokerServices: the current implementation relies on a shared section
-// that is created by the broker and opened by the target.
-BrokerServices* SandboxFactory::GetBrokerServices() {
- // Can't be the broker if the shared section is open.
- if (NULL != g_shared_section) {
- return NULL;
- }
- // If the shared section does not exist we are the broker, then create
- // the broker object.
- s_is_broker = true;
- return BrokerServicesBase::GetInstance();
-}
-
-// GetTargetServices implementation must follow the same technique as the
-// GetBrokerServices, but in this case the logic is the opposite.
-TargetServices* SandboxFactory::GetTargetServices() {
- // Can't be the target if the section handle is not valid.
- if (NULL == g_shared_section) {
- return NULL;
- }
- // We are the target
- s_is_broker = false;
- // Creates and returns the target services implementation.
- return TargetServicesBase::GetInstance();
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/sandbox.h b/sandbox/win/src/sandbox.h
deleted file mode 100644
index ee4b7b0..0000000
--- a/sandbox/win/src/sandbox.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Sandbox is a sandbox library for windows processes. Use when you want a
-// 'privileged' process and a 'locked down process' to interact with.
-// The privileged process is called the broker and it is started by external
-// means (such as the user starting it). The 'sandboxed' process is called the
-// target and it is started by the broker. There can be many target processes
-// started by a single broker process. This library provides facilities
-// for both the broker and the target.
-//
-// The design rationale and relevant documents can be found at http://go/sbox.
-//
-// Note: this header does not include the SandboxFactory definitions because
-// there are cases where the Sandbox library is linked against the main .exe
-// while its API needs to be used in a DLL.
-
-#ifndef SANDBOX_SRC_SANDBOX_H__
-#define SANDBOX_SRC_SANDBOX_H__
-
-#include <windows.h>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/sandbox_policy.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-// sandbox: Google User-Land Application Sandbox
-namespace sandbox {
-
-class BrokerServices;
-class ProcessState;
-class TargetPolicy;
-class TargetServices;
-
-// BrokerServices exposes all the broker API.
-// The basic use is to start the target(s) and wait for them to end.
-//
-// This API is intended to be called in the following order
-// (error checking omitted):
-// BrokerServices* broker = SandboxFactory::GetBrokerServices();
-// broker->Init();
-// PROCESS_INFORMATION target;
-// broker->SpawnTarget(target_exe_path, target_args, &target);
-// ::ResumeThread(target->hThread);
-// // -- later you can call:
-// broker->WaitForAllTargets(option);
-//
-class BrokerServices {
- public:
- // Initializes the broker. Must be called before any other on this class.
- // returns ALL_OK if successful. All other return values imply failure.
- // If the return is ERROR_GENERIC, you can call ::GetLastError() to get
- // more information.
- virtual ResultCode Init() = 0;
-
- // Returns the interface pointer to a new, empty policy object. Use this
- // interface to specify the sandbox policy for new processes created by
- // SpawnTarget()
- virtual TargetPolicy* CreatePolicy() = 0;
-
- // Creates a new target (child process) in a suspended state.
- // Parameters:
- // exe_path: This is the full path to the target binary. This parameter
- // can be null and in this case the exe path must be the first argument
- // of the command_line.
- // command_line: The arguments to be passed as command line to the new
- // process. This can be null if the exe_path parameter is not null.
- // policy: This is the pointer to the policy object for the sandbox to
- // be created.
- // target: returns the resulting target process information such as process
- // handle and PID just as if CreateProcess() had been called. The caller is
- // responsible for closing the handles returned in this structure.
- // Returns:
- // ALL_OK if successful. All other return values imply failure.
- virtual ResultCode SpawnTarget(const wchar_t* exe_path,
- const wchar_t* command_line,
- TargetPolicy* policy,
- PROCESS_INFORMATION* target) = 0;
-
- // This call blocks (waits) for all the targets to terminate.
- // Returns:
- // ALL_OK if successful. All other return values imply failure.
- // If the return is ERROR_GENERIC, you can call ::GetLastError() to get
- // more information.
- virtual ResultCode WaitForAllTargets() = 0;
-
- // Adds an unsandboxed process as a peer for policy decisions (e.g.
- // HANDLES_DUP_ANY policy).
- // Returns:
- // ALL_OK if successful. All other return values imply failure.
- // If the return is ERROR_GENERIC, you can call ::GetLastError() to get
- // more information.
- virtual ResultCode AddTargetPeer(HANDLE peer_process) = 0;
-};
-
-// TargetServices models the current process from the perspective
-// of a target process. To obtain a pointer to it use
-// Sandbox::GetTargetServices(). Note that this call returns a non-null
-// pointer only if this process is in fact a target. A process is a target
-// only if the process was spawned by a call to BrokerServices::SpawnTarget().
-//
-// This API allows the target to gain access to resources with a high
-// privilege token and then when it is ready to perform dangerous activities
-// (such as download content from the web) it can lower its token and
-// enter into locked-down (sandbox) mode.
-// The typical usage is as follows:
-//
-// TargetServices* target_services = Sandbox::GetTargetServices();
-// if (NULL != target_services) {
-// // We are the target.
-// target_services->Init();
-// // Do work that requires high privileges here.
-// // ....
-// // When ready to enter lock-down mode call LowerToken:
-// target_services->LowerToken();
-// }
-//
-// For more information see the BrokerServices API documentation.
-class TargetServices {
- public:
- // Initializes the target. Must call this function before any other.
- // returns ALL_OK if successful. All other return values imply failure.
- // If the return is ERROR_GENERIC, you can call ::GetLastError() to get
- // more information.
- virtual ResultCode Init() = 0;
-
- // Discards the impersonation token and uses the lower token, call before
- // processing any untrusted data or running third-party code. If this call
- // fails the current process could be terminated immediately.
- virtual void LowerToken() = 0;
-
- // Returns the ProcessState object. Through that object it's possible to have
- // information about the current state of the process, such as whether
- // LowerToken has been called or not.
- virtual ProcessState* GetState() = 0;
-
- // Requests the broker to duplicate the supplied handle into the target
- // process. The target process must be an active sandbox child process
- // and the source process must have a corresponding policy allowing
- // handle duplication for this object type.
- // Returns:
- // ALL_OK if successful. All other return values imply failure.
- // If the return is ERROR_GENERIC, you can call ::GetLastError() to get
- // more information.
- virtual ResultCode DuplicateHandle(HANDLE source_handle,
- DWORD target_process_id,
- HANDLE* target_handle,
- DWORD desired_access,
- DWORD options) = 0;
-};
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_SANDBOX_H__
diff --git a/sandbox/win/src/sandbox.vcproj b/sandbox/win/src/sandbox.vcproj
deleted file mode 100644
index f206e01..0000000
--- a/sandbox/win/src/sandbox.vcproj
+++ /dev/null
@@ -1,658 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="sandbox"
- ProjectGUID="{881F6A97-D539-4C48-B401-DF04385B2343}"
- RootNamespace="sandbox"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- ConfigurationType="4"
- InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="2"
- ForcedIncludeFiles="stdafx.h"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copy wow_helper to output directory"
- CommandLine="copy $(ProjectDir)\..\wow_helper\wow_helper.exe $(OutDir) &amp;&amp; copy $(ProjectDir)\..\wow_helper\wow_helper.pdb $(OutDir)"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- ConfigurationType="4"
- InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\testing\using_gtest.vsprops"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copy wow_helper to output directory"
- CommandLine="copy $(ProjectDir)\..\wow_helper\wow_helper.exe $(OutDir) &amp;&amp; copy $(ProjectDir)\..\wow_helper\wow_helper.pdb $(OutDir)"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="security"
- >
- <File
- RelativePath=".\acl.cc"
- >
- </File>
- <File
- RelativePath=".\acl.h"
- >
- </File>
- <File
- RelativePath=".\dep.cc"
- >
- </File>
- <File
- RelativePath=".\dep.h"
- >
- </File>
- <File
- RelativePath=".\job.cc"
- >
- </File>
- <File
- RelativePath=".\job.h"
- >
- </File>
- <File
- RelativePath=".\restricted_token.cc"
- >
- </File>
- <File
- RelativePath=".\restricted_token.h"
- >
- </File>
- <File
- RelativePath=".\restricted_token_utils.cc"
- >
- </File>
- <File
- RelativePath=".\restricted_token_utils.h"
- >
- </File>
- <File
- RelativePath=".\security_level.h"
- >
- </File>
- <File
- RelativePath=".\sid.cc"
- >
- </File>
- <File
- RelativePath=".\sid.h"
- >
- </File>
- <File
- RelativePath=".\window.cc"
- >
- </File>
- <File
- RelativePath=".\window.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Interception"
- >
- <File
- RelativePath=".\eat_resolver.cc"
- >
- </File>
- <File
- RelativePath=".\eat_resolver.h"
- >
- </File>
- <File
- RelativePath=".\interception.cc"
- >
- </File>
- <File
- RelativePath=".\interception.h"
- >
- </File>
- <File
- RelativePath=".\interception_agent.cc"
- >
- </File>
- <File
- RelativePath=".\interception_agent.h"
- >
- </File>
- <File
- RelativePath=".\interception_internal.h"
- >
- </File>
- <File
- RelativePath=".\pe_image.cc"
- >
- </File>
- <File
- RelativePath=".\pe_image.h"
- >
- </File>
- <File
- RelativePath=".\resolver.cc"
- >
- </File>
- <File
- RelativePath=".\resolver.h"
- >
- </File>
- <File
- RelativePath=".\service_resolver.cc"
- >
- </File>
- <File
- RelativePath=".\service_resolver.h"
- >
- </File>
- <File
- RelativePath=".\sidestep_resolver.cc"
- >
- </File>
- <File
- RelativePath=".\sidestep_resolver.h"
- >
- </File>
- <File
- RelativePath=".\target_interceptions.cc"
- >
- </File>
- <File
- RelativePath=".\target_interceptions.h"
- >
- </File>
- <File
- RelativePath=".\Wow64.cc"
- >
- </File>
- <File
- RelativePath=".\Wow64.h"
- >
- </File>
- <Filter
- Name="sidestep"
- >
- <File
- RelativePath=".\sidestep\ia32_modrm_map.cpp"
- >
- </File>
- <File
- RelativePath=".\sidestep\ia32_opcode_map.cpp"
- >
- </File>
- <File
- RelativePath=".\sidestep\mini_disassembler.cpp"
- >
- </File>
- <File
- RelativePath=".\sidestep\mini_disassembler.h"
- >
- </File>
- <File
- RelativePath=".\sidestep\mini_disassembler_types.h"
- >
- </File>
- <File
- RelativePath=".\sidestep\preamble_patcher.h"
- >
- </File>
- <File
- RelativePath=".\sidestep\preamble_patcher_with_stub.cpp"
- >
- </File>
- </Filter>
- </Filter>
- <Filter
- Name="nt_level"
- >
- <File
- RelativePath=".\nt_internals.h"
- >
- </File>
- <File
- RelativePath=".\policy_target.cc"
- >
- </File>
- <File
- RelativePath=".\policy_target.h"
- >
- </File>
- <File
- RelativePath=".\sandbox_nt_types.h"
- >
- </File>
- <File
- RelativePath=".\sandbox_nt_util.cc"
- >
- </File>
- <File
- RelativePath=".\sandbox_nt_util.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Policy_handlers"
- >
- <File
- RelativePath=".\filesystem_dispatcher.cc"
- >
- </File>
- <File
- RelativePath=".\filesystem_dispatcher.h"
- >
- </File>
- <File
- RelativePath=".\filesystem_interception.cc"
- >
- </File>
- <File
- RelativePath=".\filesystem_interception.h"
- >
- </File>
- <File
- RelativePath=".\filesystem_policy.cc"
- >
- </File>
- <File
- RelativePath=".\filesystem_policy.h"
- >
- </File>
- <File
- RelativePath=".\named_pipe_dispatcher.cc"
- >
- </File>
- <File
- RelativePath=".\named_pipe_dispatcher.h"
- >
- </File>
- <File
- RelativePath=".\named_pipe_interception.cc"
- >
- </File>
- <File
- RelativePath=".\named_pipe_interception.h"
- >
- </File>
- <File
- RelativePath=".\named_pipe_policy.cc"
- >
- </File>
- <File
- RelativePath=".\named_pipe_policy.h"
- >
- </File>
- <File
- RelativePath=".\policy_params.h"
- >
- </File>
- <File
- RelativePath=".\process_thread_dispatcher.cc"
- >
- </File>
- <File
- RelativePath=".\process_thread_dispatcher.h"
- >
- </File>
- <File
- RelativePath=".\process_thread_interception.cc"
- >
- </File>
- <File
- RelativePath=".\process_thread_interception.h"
- >
- </File>
- <File
- RelativePath=".\process_thread_policy.cc"
- >
- </File>
- <File
- RelativePath=".\process_thread_policy.h"
- >
- </File>
- <File
- RelativePath=".\registry_dispatcher.cc"
- >
- </File>
- <File
- RelativePath=".\registry_dispatcher.h"
- >
- </File>
- <File
- RelativePath=".\registry_interception.cc"
- >
- </File>
- <File
- RelativePath=".\registry_interception.h"
- >
- </File>
- <File
- RelativePath=".\registry_policy.cc"
- >
- </File>
- <File
- RelativePath=".\registry_policy.h"
- >
- </File>
- <File
- RelativePath=".\sync_dispatcher.cc"
- >
- </File>
- <File
- RelativePath=".\sync_dispatcher.h"
- >
- </File>
- <File
- RelativePath=".\sync_interception.cc"
- >
- </File>
- <File
- RelativePath=".\sync_interception.h"
- >
- </File>
- <File
- RelativePath=".\sync_policy.cc"
- >
- </File>
- <File
- RelativePath=".\sync_policy.h"
- >
- </File>
- </Filter>
- <Filter
- Name="IPC"
- >
- <File
- RelativePath=".\crosscall_client.h"
- >
- </File>
- <File
- RelativePath=".\crosscall_params.h"
- >
- </File>
- <File
- RelativePath=".\crosscall_server.cc"
- >
- </File>
- <File
- RelativePath=".\crosscall_server.h"
- >
- </File>
- <File
- RelativePath=".\ipc_tags.h"
- >
- </File>
- <File
- RelativePath=".\sharedmem_ipc_client.cc"
- >
- </File>
- <File
- RelativePath=".\sharedmem_ipc_client.h"
- >
- </File>
- <File
- RelativePath=".\sharedmem_ipc_server.cc"
- >
- </File>
- <File
- RelativePath=".\sharedmem_ipc_server.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Policy_base"
- >
- <File
- RelativePath=".\policy_engine_opcodes.cc"
- >
- </File>
- <File
- RelativePath=".\policy_engine_opcodes.h"
- >
- </File>
- <File
- RelativePath=".\policy_engine_params.h"
- >
- </File>
- <File
- RelativePath=".\policy_engine_processor.cc"
- >
- </File>
- <File
- RelativePath=".\policy_engine_processor.h"
- >
- </File>
- <File
- RelativePath=".\policy_low_level.cc"
- >
- </File>
- <File
- RelativePath=".\policy_low_level.h"
- >
- </File>
- <File
- RelativePath=".\sandbox_policy_base.cc"
- >
- </File>
- <File
- RelativePath=".\sandbox_policy_base.h"
- >
- </File>
- </Filter>
- <File
- RelativePath=".\broker_services.cc"
- >
- </File>
- <File
- RelativePath=".\broker_services.h"
- >
- </File>
- <File
- RelativePath=".\internal_types.h"
- >
- </File>
- <File
- RelativePath=".\policy_broker.cc"
- >
- </File>
- <File
- RelativePath=".\policy_broker.h"
- >
- </File>
- <File
- RelativePath=".\sandbox.cc"
- >
- </File>
- <File
- RelativePath=".\sandbox.h"
- >
- </File>
- <File
- RelativePath=".\sandbox_factory.h"
- >
- </File>
- <File
- RelativePath=".\sandbox_policy.h"
- >
- </File>
- <File
- RelativePath=".\sandbox_types.h"
- >
- </File>
- <File
- RelativePath=".\sandbox_utils.cc"
- >
- </File>
- <File
- RelativePath=".\sandbox_utils.h"
- >
- </File>
- <File
- RelativePath=".\shared_handles.cc"
- >
- </File>
- <File
- RelativePath=".\shared_handles.h"
- >
- </File>
- <File
- RelativePath=".\stdafx.cc"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="1"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- UsePrecompiledHeader="0"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath=".\stdafx.h"
- >
- </File>
- <File
- RelativePath=".\target_process.cc"
- >
- </File>
- <File
- RelativePath=".\target_process.h"
- >
- </File>
- <File
- RelativePath=".\target_services.cc"
- >
- </File>
- <File
- RelativePath=".\target_services.h"
- >
- </File>
- <File
- RelativePath=".\win2k_threadpool.cc"
- >
- </File>
- <File
- RelativePath=".\win2k_threadpool.h"
- >
- </File>
- <File
- RelativePath=".\win_utils.cc"
- >
- </File>
- <File
- RelativePath=".\win_utils.h"
- >
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/sandbox/win/src/sandbox_factory.h b/sandbox/win/src/sandbox_factory.h
deleted file mode 100644
index 7a0280f..0000000
--- a/sandbox/win/src/sandbox_factory.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SANDBOX_FACTORY_H__
-#define SANDBOX_SRC_SANDBOX_FACTORY_H__
-
-#include "sandbox/win/src/sandbox.h"
-
-// SandboxFactory is a set of static methods to get access to the broker
-// or target services object. Only one of the two methods (GetBrokerServices,
-// GetTargetServices) will return a non-null pointer and that should be used
-// as the indication that the process is the broker or the target:
-//
-// BrokerServices* broker_services = SandboxFactory::GetBrokerServices();
-// if (NULL != broker_services) {
-// //we are the broker, call broker api here
-// broker_services->Init();
-// } else {
-// TargetServices* target_services = SandboxFactory::GetTargetServices();
-// if (NULL != target_services) {
-// //we are the target, call target api here
-// target_services->Init();
-// }
-//
-// The methods in this class are expected to be called from a single thread
-//
-// The Sandbox library needs to be linked against the main executable, but
-// sometimes the API calls are issued from a DLL that loads into the exe
-// process. These factory methods then need to be called from the main
-// exe and the interface pointers then can be safely passed to the DLL where
-// the Sandbox API calls are made.
-namespace sandbox {
-
-class SandboxFactory {
- public:
- // Returns the Broker API interface, returns NULL if this process is the
- // target.
- static BrokerServices* GetBrokerServices();
-
- // Returns the Target API interface, returns NULL if this process is the
- // broker.
- static TargetServices* GetTargetServices();
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(SandboxFactory);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_SANDBOX_FACTORY_H__
diff --git a/sandbox/win/src/sandbox_nt_types.h b/sandbox/win/src/sandbox_nt_types.h
deleted file mode 100644
index 1303ac2..0000000
--- a/sandbox/win/src/sandbox_nt_types.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SANDBOX_NT_TYPES_H__
-#define SANDBOX_SRC_SANDBOX_NT_TYPES_H__
-
-#include "sandbox/win/src/nt_internals.h"
-
-namespace sandbox {
-
-struct NtExports {
- NtAllocateVirtualMemoryFunction AllocateVirtualMemory;
- NtCloseFunction Close;
- NtDuplicateObjectFunction DuplicateObject;
- NtFreeVirtualMemoryFunction FreeVirtualMemory;
- NtMapViewOfSectionFunction MapViewOfSection;
- NtProtectVirtualMemoryFunction ProtectVirtualMemory;
- NtQueryInformationProcessFunction QueryInformationProcess;
- NtQueryObjectFunction QueryObject;
- NtQuerySectionFunction QuerySection;
- NtQueryVirtualMemoryFunction QueryVirtualMemory;
- NtUnmapViewOfSectionFunction UnmapViewOfSection;
- RtlAllocateHeapFunction RtlAllocateHeap;
- RtlAnsiStringToUnicodeStringFunction RtlAnsiStringToUnicodeString;
- RtlCompareUnicodeStringFunction RtlCompareUnicodeString;
- RtlCreateHeapFunction RtlCreateHeap;
- RtlCreateUserThreadFunction RtlCreateUserThread;
- RtlDestroyHeapFunction RtlDestroyHeap;
- RtlFreeHeapFunction RtlFreeHeap;
- _strnicmpFunction _strnicmp;
- strlenFunction strlen;
- wcslenFunction wcslen;
-};
-
-// This is the value used for the ntdll level allocator.
-enum AllocationType {
- NT_ALLOC,
- NT_PLACE,
- NT_PAGE
-};
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_SANDBOX_NT_TYPES_H__
diff --git a/sandbox/win/src/sandbox_nt_util.cc b/sandbox/win/src/sandbox_nt_util.cc
deleted file mode 100644
index 4c937bd..0000000
--- a/sandbox/win/src/sandbox_nt_util.cc
+++ /dev/null
@@ -1,599 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/sandbox_nt_util.h"
-
-#include "base/win/pe_image.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/target_services.h"
-
-namespace sandbox {
-
-// This is the list of all imported symbols from ntdll.dll.
-SANDBOX_INTERCEPT NtExports g_nt = { NULL };
-
-}
-
-namespace {
-
-#if defined(_WIN64)
-void* AllocateNearTo(void* source, size_t size) {
- using sandbox::g_nt;
-
- // Start with 1 GB above the source.
- const unsigned int kOneGB = 0x40000000;
- void* base = reinterpret_cast<char*>(source) + kOneGB;
- SIZE_T actual_size = size;
- ULONG_PTR zero_bits = 0; // Not the correct type if used.
- ULONG type = MEM_RESERVE;
-
- if (reinterpret_cast<SIZE_T>(source) > 0x7ff80000000) {
- // We are at the top of the address space. Let's try the highest available
- // address.
- base = NULL;
- type |= MEM_TOP_DOWN;
- }
-
- NTSTATUS ret;
- int attempts = 0;
- for (; attempts < 20; attempts++) {
- ret = g_nt.AllocateVirtualMemory(NtCurrentProcess, &base, zero_bits,
- &actual_size, type, PAGE_READWRITE);
- if (NT_SUCCESS(ret)) {
- if (base < source) {
- // We won't be able to patch this dll.
- VERIFY_SUCCESS(g_nt.FreeVirtualMemory(NtCurrentProcess, &base, &size,
- MEM_RELEASE));
- return NULL;
- }
- break;
- }
-
- // Try 100 MB higher.
- base = reinterpret_cast<char*>(base) + 100 * 0x100000;
- };
-
- if (attempts == 20)
- return NULL;
-
- ret = g_nt.AllocateVirtualMemory(NtCurrentProcess, &base, zero_bits,
- &actual_size, MEM_COMMIT, PAGE_READWRITE);
-
- if (!NT_SUCCESS(ret)) {
- VERIFY_SUCCESS(g_nt.FreeVirtualMemory(NtCurrentProcess, &base, &size,
- MEM_RELEASE));
- base = NULL;
- }
-
- return base;
-}
-#else // defined(_WIN64).
-void* AllocateNearTo(void* source, size_t size) {
- using sandbox::g_nt;
- UNREFERENCED_PARAMETER(source);
-
- // In 32-bit processes allocations below 512k are predictable, so mark
- // anything in that range as reserved and retry until we get a good address.
- const void* const kMinAddress = reinterpret_cast<void*>(512 * 1024);
- NTSTATUS ret;
- SIZE_T actual_size;
- void* base;
- do {
- base = NULL;
- actual_size = 64 * 1024;
- ret = g_nt.AllocateVirtualMemory(NtCurrentProcess, &base, 0, &actual_size,
- MEM_RESERVE, PAGE_NOACCESS);
- if (!NT_SUCCESS(ret))
- return NULL;
- } while (base < kMinAddress);
-
- actual_size = size;
- ret = g_nt.AllocateVirtualMemory(NtCurrentProcess, &base, 0, &actual_size,
- MEM_COMMIT, PAGE_READWRITE);
- if (!NT_SUCCESS(ret))
- return NULL;
- return base;
-}
-#endif // defined(_WIN64).
-
-} // namespace.
-
-namespace sandbox {
-
-// Handle for our private heap.
-void* g_heap = NULL;
-
-SANDBOX_INTERCEPT HANDLE g_shared_section;
-SANDBOX_INTERCEPT size_t g_shared_IPC_size = 0;
-SANDBOX_INTERCEPT size_t g_shared_policy_size = 0;
-
-void* volatile g_shared_policy_memory = NULL;
-void* volatile g_shared_IPC_memory = NULL;
-
-// Both the IPC and the policy share a single region of memory in which the IPC
-// memory is first and the policy memory is last.
-bool MapGlobalMemory() {
- if (NULL == g_shared_IPC_memory) {
- void* memory = NULL;
- SIZE_T size = 0;
- // Map the entire shared section from the start.
- NTSTATUS ret = g_nt.MapViewOfSection(g_shared_section, NtCurrentProcess,
- &memory, 0, 0, NULL, &size, ViewUnmap,
- 0, PAGE_READWRITE);
-
- if (!NT_SUCCESS(ret) || NULL == memory) {
- NOTREACHED_NT();
- return false;
- }
-
- if (NULL != _InterlockedCompareExchangePointer(&g_shared_IPC_memory,
- memory, NULL)) {
- // Somebody beat us to the memory setup.
- ret = g_nt.UnmapViewOfSection(NtCurrentProcess, memory);
- VERIFY_SUCCESS(ret);
- }
- DCHECK_NT(g_shared_IPC_size > 0);
- g_shared_policy_memory = reinterpret_cast<char*>(g_shared_IPC_memory)
- + g_shared_IPC_size;
- }
- DCHECK_NT(g_shared_policy_memory);
- DCHECK_NT(g_shared_policy_size > 0);
- return true;
-}
-
-void* GetGlobalIPCMemory() {
- if (!MapGlobalMemory())
- return NULL;
- return g_shared_IPC_memory;
-}
-
-void* GetGlobalPolicyMemory() {
- if (!MapGlobalMemory())
- return NULL;
- return g_shared_policy_memory;
-}
-
-bool InitHeap() {
- if (!g_heap) {
- // Create a new heap using default values for everything.
- void* heap = g_nt.RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL);
- if (!heap)
- return false;
-
- if (NULL != _InterlockedCompareExchangePointer(&g_heap, heap, NULL)) {
- // Somebody beat us to the memory setup.
- g_nt.RtlDestroyHeap(heap);
- }
- }
- return (g_heap) ? true : false;
-}
-
-// Physically reads or writes from memory to verify that (at this time), it is
-// valid. Returns a dummy value.
-int TouchMemory(void* buffer, size_t size_bytes, RequiredAccess intent) {
- const int kPageSize = 4096;
- int dummy = 0;
- char* start = reinterpret_cast<char*>(buffer);
- char* end = start + size_bytes - 1;
-
- if (WRITE == intent) {
- for (; start < end; start += kPageSize) {
- *start = 0;
- }
- *end = 0;
- } else {
- for (; start < end; start += kPageSize) {
- dummy += *start;
- }
- dummy += *end;
- }
-
- return dummy;
-}
-
-bool ValidParameter(void* buffer, size_t size, RequiredAccess intent) {
- DCHECK_NT(size);
- __try {
- TouchMemory(buffer, size, intent);
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- return false;
- }
- return true;
-}
-
-NTSTATUS CopyData(void* destination, const void* source, size_t bytes) {
- NTSTATUS ret = STATUS_SUCCESS;
- __try {
- if (SandboxFactory::GetTargetServices()->GetState()->InitCalled()) {
- memcpy(destination, source, bytes);
- } else {
- const char* from = reinterpret_cast<const char*>(source);
- char* to = reinterpret_cast<char*>(destination);
- for (size_t i = 0; i < bytes; i++) {
- to[i] = from[i];
- }
- }
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- ret = GetExceptionCode();
- }
- return ret;
-}
-
-// Hacky code... replace with AllocAndCopyObjectAttributes.
-NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object,
- wchar_t** out_name, uint32* attributes,
- HANDLE* root) {
- if (!InitHeap())
- return STATUS_NO_MEMORY;
-
- DCHECK_NT(out_name);
- *out_name = NULL;
- NTSTATUS ret = STATUS_UNSUCCESSFUL;
- __try {
- do {
- if (in_object->RootDirectory != static_cast<HANDLE>(0) && !root)
- break;
- if (NULL == in_object->ObjectName)
- break;
- if (NULL == in_object->ObjectName->Buffer)
- break;
-
- size_t size = in_object->ObjectName->Length + sizeof(wchar_t);
- *out_name = new(NT_ALLOC) wchar_t[size/sizeof(wchar_t)];
- if (NULL == *out_name)
- break;
-
- ret = CopyData(*out_name, in_object->ObjectName->Buffer,
- size - sizeof(wchar_t));
- if (!NT_SUCCESS(ret))
- break;
-
- (*out_name)[size / sizeof(wchar_t) - 1] = L'\0';
-
- if (attributes)
- *attributes = in_object->Attributes;
-
- if (root)
- *root = in_object->RootDirectory;
- ret = STATUS_SUCCESS;
- } while (false);
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- ret = GetExceptionCode();
- }
-
- if (!NT_SUCCESS(ret) && *out_name) {
- operator delete(*out_name, NT_ALLOC);
- *out_name = NULL;
- }
-
- return ret;
-}
-
-NTSTATUS GetProcessId(HANDLE process, ULONG *process_id) {
- PROCESS_BASIC_INFORMATION proc_info;
- ULONG bytes_returned;
-
- NTSTATUS ret = g_nt.QueryInformationProcess(process, ProcessBasicInformation,
- &proc_info, sizeof(proc_info),
- &bytes_returned);
- if (!NT_SUCCESS(ret) || sizeof(proc_info) != bytes_returned)
- return ret;
-
- *process_id = proc_info.UniqueProcessId;
- return STATUS_SUCCESS;
-}
-
-bool IsSameProcess(HANDLE process) {
- if (NtCurrentProcess == process)
- return true;
-
- static ULONG s_process_id = 0;
-
- if (!s_process_id) {
- NTSTATUS ret = GetProcessId(NtCurrentProcess, &s_process_id);
- if (!NT_SUCCESS(ret))
- return false;
- }
-
- ULONG process_id;
- NTSTATUS ret = GetProcessId(process, &process_id);
- if (!NT_SUCCESS(ret))
- return false;
-
- return (process_id == s_process_id);
-}
-
-bool IsValidImageSection(HANDLE section, PVOID *base, PLARGE_INTEGER offset,
- PSIZE_T view_size) {
- if (!section || !base || !view_size || offset)
- return false;
-
- HANDLE query_section;
-
- NTSTATUS ret = g_nt.DuplicateObject(NtCurrentProcess, section,
- NtCurrentProcess, &query_section,
- SECTION_QUERY, 0, 0);
- if (!NT_SUCCESS(ret))
- return false;
-
- SECTION_BASIC_INFORMATION basic_info;
- SIZE_T bytes_returned;
- ret = g_nt.QuerySection(query_section, SectionBasicInformation, &basic_info,
- sizeof(basic_info), &bytes_returned);
-
- VERIFY_SUCCESS(g_nt.Close(query_section));
-
- if (!NT_SUCCESS(ret) || sizeof(basic_info) != bytes_returned)
- return false;
-
- if (!(basic_info.Attributes & SEC_IMAGE))
- return false;
-
- return true;
-}
-
-UNICODE_STRING* AnsiToUnicode(const char* string) {
- ANSI_STRING ansi_string;
- ansi_string.Length = static_cast<USHORT>(g_nt.strlen(string));
- ansi_string.MaximumLength = ansi_string.Length + 1;
- ansi_string.Buffer = const_cast<char*>(string);
-
- if (ansi_string.Length > ansi_string.MaximumLength)
- return NULL;
-
- size_t name_bytes = ansi_string.MaximumLength * sizeof(wchar_t) +
- sizeof(UNICODE_STRING);
-
- UNICODE_STRING* out_string = reinterpret_cast<UNICODE_STRING*>(
- new(NT_ALLOC) char[name_bytes]);
- if (!out_string)
- return NULL;
-
- out_string->MaximumLength = ansi_string.MaximumLength * sizeof(wchar_t);
- out_string->Buffer = reinterpret_cast<wchar_t*>(&out_string[1]);
-
- BOOLEAN alloc_destination = FALSE;
- NTSTATUS ret = g_nt.RtlAnsiStringToUnicodeString(out_string, &ansi_string,
- alloc_destination);
- DCHECK_NT(STATUS_BUFFER_OVERFLOW != ret);
- if (!NT_SUCCESS(ret)) {
- operator delete(out_string, NT_ALLOC);
- return NULL;
- }
-
- return out_string;
-}
-
-UNICODE_STRING* GetImageInfoFromModule(HMODULE module, uint32* flags) {
- UNICODE_STRING* out_name = NULL;
- __try {
- do {
- *flags = 0;
- base::win::PEImage pe(module);
-
- if (!pe.VerifyMagic())
- break;
- *flags |= MODULE_IS_PE_IMAGE;
-
- PIMAGE_EXPORT_DIRECTORY exports = pe.GetExportDirectory();
- if (exports) {
- char* name = reinterpret_cast<char*>(pe.RVAToAddr(exports->Name));
- out_name = AnsiToUnicode(name);
- }
-
- PIMAGE_NT_HEADERS headers = pe.GetNTHeaders();
- if (headers) {
- if (headers->OptionalHeader.AddressOfEntryPoint)
- *flags |= MODULE_HAS_ENTRY_POINT;
- if (headers->OptionalHeader.SizeOfCode)
- *flags |= MODULE_HAS_CODE;
- }
- } while (false);
- } __except(EXCEPTION_EXECUTE_HANDLER) {
- }
-
- return out_name;
-}
-
-UNICODE_STRING* GetBackingFilePath(PVOID address) {
- // We'll start with something close to max_path charactes for the name.
- ULONG buffer_bytes = MAX_PATH * 2;
-
- for (;;) {
- MEMORY_SECTION_NAME* section_name = reinterpret_cast<MEMORY_SECTION_NAME*>(
- new(NT_ALLOC) char[buffer_bytes]);
-
- if (!section_name)
- return NULL;
-
- ULONG returned_bytes;
- NTSTATUS ret = g_nt.QueryVirtualMemory(NtCurrentProcess, address,
- MemorySectionName, section_name,
- buffer_bytes, &returned_bytes);
-
- if (STATUS_BUFFER_OVERFLOW == ret) {
- // Retry the call with the given buffer size.
- operator delete(section_name, NT_ALLOC);
- section_name = NULL;
- buffer_bytes = returned_bytes;
- continue;
- }
- if (!NT_SUCCESS(ret)) {
- operator delete(section_name, NT_ALLOC);
- return NULL;
- }
-
- return reinterpret_cast<UNICODE_STRING*>(section_name);
- }
-}
-
-UNICODE_STRING* ExtractModuleName(const UNICODE_STRING* module_path) {
- if ((!module_path) || (!module_path->Buffer))
- return NULL;
-
- wchar_t* sep = NULL;
- int start_pos = module_path->Length / sizeof(wchar_t) - 1;
- int ix = start_pos;
-
- for (; ix >= 0; --ix) {
- if (module_path->Buffer[ix] == L'\\') {
- sep = &module_path->Buffer[ix];
- break;
- }
- }
-
- // Ends with path separator. Not a valid module name.
- if ((ix == start_pos) && sep)
- return NULL;
-
- // No path separator found. Use the entire name.
- if (!sep) {
- sep = &module_path->Buffer[-1];
- }
-
- // Add one to the size so we can null terminate the string.
- size_t size_bytes = (start_pos - ix + 1) * sizeof(wchar_t);
-
- // Based on the code above, size_bytes should always be small enough
- // to make the static_cast below safe.
- DCHECK_NT(kuint16max > size_bytes);
- char* str_buffer = new(NT_ALLOC) char[size_bytes + sizeof(UNICODE_STRING)];
- if (!str_buffer)
- return NULL;
-
- UNICODE_STRING* out_string = reinterpret_cast<UNICODE_STRING*>(str_buffer);
- out_string->Buffer = reinterpret_cast<wchar_t*>(&out_string[1]);
- out_string->Length = static_cast<USHORT>(size_bytes - sizeof(wchar_t));
- out_string->MaximumLength = static_cast<USHORT>(size_bytes);
-
- NTSTATUS ret = CopyData(out_string->Buffer, &sep[1], out_string->Length);
- if (!NT_SUCCESS(ret)) {
- operator delete(out_string, NT_ALLOC);
- return NULL;
- }
-
- out_string->Buffer[out_string->Length / sizeof(wchar_t)] = L'\0';
- return out_string;
-}
-
-NTSTATUS AutoProtectMemory::ChangeProtection(void* address, size_t bytes,
- ULONG protect) {
- DCHECK_NT(!changed_);
- SIZE_T new_bytes = bytes;
- NTSTATUS ret = g_nt.ProtectVirtualMemory(NtCurrentProcess, &address,
- &new_bytes, protect, &old_protect_);
- if (NT_SUCCESS(ret)) {
- changed_ = true;
- address_ = address;
- bytes_ = new_bytes;
- }
-
- return ret;
-}
-
-NTSTATUS AutoProtectMemory::RevertProtection() {
- if (!changed_)
- return STATUS_SUCCESS;
-
- DCHECK_NT(address_);
- DCHECK_NT(bytes_);
-
- SIZE_T new_bytes = bytes_;
- NTSTATUS ret = g_nt.ProtectVirtualMemory(NtCurrentProcess, &address_,
- &new_bytes, old_protect_,
- &old_protect_);
- DCHECK_NT(NT_SUCCESS(ret));
-
- changed_ = false;
- address_ = NULL;
- bytes_ = 0;
- old_protect_ = 0;
-
- return ret;
-}
-
-bool IsSupportedRenameCall(FILE_RENAME_INFORMATION* file_info, DWORD length,
- uint32 file_info_class) {
- if (FileRenameInformation != file_info_class)
- return false;
-
- if (length < sizeof(FILE_RENAME_INFORMATION))
- return false;
-
- // Make sure file name length doesn't exceed the message length
- if (length - offsetof(FILE_RENAME_INFORMATION, FileName) <
- file_info->FileNameLength)
- return false;
-
- // We don't support a root directory.
- if (file_info->RootDirectory)
- return false;
-
- // Check if it starts with \\??\\. We don't support relative paths.
- if (file_info->FileNameLength < 4 || file_info->FileNameLength > kuint16max)
- return false;
-
- if (file_info->FileName[0] != L'\\' ||
- file_info->FileName[1] != L'?' ||
- file_info->FileName[2] != L'?' ||
- file_info->FileName[3] != L'\\')
- return false;
-
- return true;
-}
-
-} // namespace sandbox
-
-void* operator new(size_t size, sandbox::AllocationType type,
- void* near_to) {
- using namespace sandbox;
-
- if (NT_ALLOC == type) {
- if (!InitHeap())
- return NULL;
-
- // Use default flags for the allocation.
- return g_nt.RtlAllocateHeap(sandbox::g_heap, 0, size);
- } else if (NT_PAGE == type) {
- return AllocateNearTo(near_to, size);
- }
- NOTREACHED_NT();
- return NULL;
-}
-
-void operator delete(void* memory, sandbox::AllocationType type) {
- using namespace sandbox;
-
- if (NT_ALLOC == type) {
- // Use default flags.
- VERIFY(g_nt.RtlFreeHeap(sandbox::g_heap, 0, memory));
- } else if (NT_PAGE == type) {
- void* base = memory;
- SIZE_T size = 0;
- VERIFY_SUCCESS(g_nt.FreeVirtualMemory(NtCurrentProcess, &base, &size,
- MEM_RELEASE));
- } else {
- NOTREACHED_NT();
- }
-}
-
-void operator delete(void* memory, sandbox::AllocationType type,
- void* near_to) {
- UNREFERENCED_PARAMETER(near_to);
- operator delete(memory, type);
-}
-
-void* __cdecl operator new(size_t size, void* buffer,
- sandbox::AllocationType type) {
- UNREFERENCED_PARAMETER(size);
- UNREFERENCED_PARAMETER(type);
- return buffer;
-}
-
-void __cdecl operator delete(void* memory, void* buffer,
- sandbox::AllocationType type) {
- UNREFERENCED_PARAMETER(memory);
- UNREFERENCED_PARAMETER(buffer);
- UNREFERENCED_PARAMETER(type);
-}
diff --git a/sandbox/win/src/sandbox_nt_util.h b/sandbox/win/src/sandbox_nt_util.h
deleted file mode 100644
index 06538cd..0000000
--- a/sandbox/win/src/sandbox_nt_util.h
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SANDBOX_NT_UTIL_H_
-#define SANDBOX_SRC_SANDBOX_NT_UTIL_H_
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_nt_types.h"
-
-// Placement new and delete to be used from ntdll interception code.
-void* __cdecl operator new(size_t size, sandbox::AllocationType type,
- void* near_to = NULL);
-void __cdecl operator delete(void* memory, sandbox::AllocationType type);
-// Add operator delete that matches the placement form of the operator new
-// above. This is required by compiler to generate code to call operator delete
-// in case the object's constructor throws an exception.
-// See http://msdn.microsoft.com/en-us/library/cxdxz3x6.aspx
-void __cdecl operator delete(void* memory, sandbox::AllocationType type,
- void* near_to);
-
-// Regular placement new and delete
-void* __cdecl operator new(size_t size, void* buffer,
- sandbox::AllocationType type);
-void __cdecl operator delete(void* memory, void* buffer,
- sandbox::AllocationType type);
-
-// DCHECK_NT is defined to be pretty much an assert at this time because we
-// don't have logging from the ntdll layer on the child.
-//
-// VERIFY_NT and VERIFY_SUCCESS_NT are the standard asserts on debug, but
-// execute the actual argument on release builds. VERIFY_NT expects an action
-// returning a bool, while VERIFY_SUCCESS_NT expects an action returning
-// NTSTATUS.
-#ifndef NDEBUG
-#define DCHECK_NT(condition) { (condition) ? 0 : __debugbreak(); }
-#define VERIFY(action) DCHECK_NT(action)
-#define VERIFY_SUCCESS(action) DCHECK_NT(NT_SUCCESS(action))
-#else
-#define DCHECK_NT(condition)
-#define VERIFY(action) (action)
-#define VERIFY_SUCCESS(action) (action)
-#endif
-
-#define NOTREACHED_NT() DCHECK_NT(false)
-
-namespace sandbox {
-
-extern "C" long _InterlockedCompareExchange(long volatile* destination,
- long exchange, long comperand);
-
-#pragma intrinsic(_InterlockedCompareExchange)
-
-// We want to make sure that we use an intrinsic version of the function, not
-// the one provided by kernel32.
-__forceinline void* _InterlockedCompareExchangePointer(
- void* volatile* destination, void* exchange, void* comperand) {
- size_t ret = _InterlockedCompareExchange(
- reinterpret_cast<long volatile*>(destination),
- static_cast<long>(reinterpret_cast<size_t>(exchange)),
- static_cast<long>(reinterpret_cast<size_t>(comperand)));
-
- return reinterpret_cast<void*>(static_cast<size_t>(ret));
-}
-
-// Returns a pointer to the IPC shared memory.
-void* GetGlobalIPCMemory();
-
-// Returns a pointer to the Policy shared memory.
-void* GetGlobalPolicyMemory();
-
-enum RequiredAccess {
- READ,
- WRITE
-};
-
-// Performs basic user mode buffer validation. In any case, buffers access must
-// be protected by SEH. intent specifies if the buffer should be tested for read
-// or write.
-// Note that write intent implies destruction of the buffer content (we actually
-// write)
-bool ValidParameter(void* buffer, size_t size, RequiredAccess intent);
-
-
-// Copies data from a user buffer to our buffer. Returns the operation status.
-NTSTATUS CopyData(void* destination, const void* source, size_t bytes);
-
-// Copies the name from an object attributes.
-NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object,
- wchar_t** out_name, uint32* attributes, HANDLE* root);
-
-// Initializes our ntdll level heap
-bool InitHeap();
-
-// Returns true if the provided handle refers to the current process.
-bool IsSameProcess(HANDLE process);
-
-enum MappedModuleFlags {
- MODULE_IS_PE_IMAGE = 1, // Module is an executable.
- MODULE_HAS_ENTRY_POINT = 2, // Execution entry point found.
- MODULE_HAS_CODE = 4 // Non zero size of executable sections.
-};
-
-// Returns the name and characteristics for a given PE module. The return
-// value is the name as defined by the export table and the flags is any
-// combination of the MappedModuleFlags enumeration.
-//
-// The returned buffer must be freed with a placement delete from the ntdll
-// level allocator:
-//
-// UNICODE_STRING* name = GetPEImageInfoFromModule(HMODULE module, &flags);
-// if (!name) {
-// // probably not a valid dll
-// return;
-// }
-// InsertYourLogicHere(name);
-// operator delete(name, NT_ALLOC);
-UNICODE_STRING* GetImageInfoFromModule(HMODULE module, uint32* flags);
-
-// Returns the full path and filename for a given dll.
-// May return NULL if the provided address is not backed by a named section, or
-// if the current OS version doesn't support the call. The returned buffer must
-// be freed with a placement delete (see GetImageNameFromModule example).
-UNICODE_STRING* GetBackingFilePath(PVOID address);
-
-// Returns the last component of a path that contains the module name.
-// It will return NULL if the path ends with the path separator. The returned
-// buffer must be freed with a placement delete (see GetImageNameFromModule
-// example).
-UNICODE_STRING* ExtractModuleName(const UNICODE_STRING* module_path);
-
-// Returns true if the parameters correspond to a dll mapped as code.
-bool IsValidImageSection(HANDLE section, PVOID *base, PLARGE_INTEGER offset,
- PSIZE_T view_size);
-
-// Converts an ansi string to an UNICODE_STRING.
-UNICODE_STRING* AnsiToUnicode(const char* string);
-
-// Provides a simple way to temporarily change the protection of a memory page.
-class AutoProtectMemory {
- public:
- AutoProtectMemory()
- : changed_(false), address_(NULL), bytes_(0), old_protect_(0) {}
-
- ~AutoProtectMemory() {
- RevertProtection();
- }
-
- // Sets the desired protection of a given memory range.
- NTSTATUS ChangeProtection(void* address, size_t bytes, ULONG protect);
-
- // Restores the original page protection.
- NTSTATUS RevertProtection();
-
- private:
- bool changed_;
- void* address_;
- size_t bytes_;
- ULONG old_protect_;
-
- DISALLOW_COPY_AND_ASSIGN(AutoProtectMemory);
-};
-
-// Returns true if the file_rename_information structure is supported by our
-// rename handler.
-bool IsSupportedRenameCall(FILE_RENAME_INFORMATION* file_info, DWORD length,
- uint32 file_info_class);
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_SANDBOX_NT_UTIL_H__
diff --git a/sandbox/win/src/sandbox_policy.h b/sandbox/win/src/sandbox_policy.h
deleted file mode 100644
index 566351a4..0000000
--- a/sandbox/win/src/sandbox_policy.h
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SANDBOX_POLICY_H_
-#define SANDBOX_SRC_SANDBOX_POLICY_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/security_level.h"
-
-namespace sandbox {
-
-class TargetPolicy {
- public:
- // Windows subsystems that can have specific rules.
- // Note: The process subsystem(SUBSY_PROCESS) does not evaluate the request
- // exactly like the CreateProcess API does. See the comment at the top of
- // process_thread_dispatcher.cc for more details.
- enum SubSystem {
- SUBSYS_FILES, // Creation and opening of files and pipes.
- SUBSYS_NAMED_PIPES, // Creation of named pipes.
- SUBSYS_PROCESS, // Creation of child processes.
- SUBSYS_REGISTRY, // Creation and opening of registry keys.
- SUBSYS_SYNC, // Creation of named sync objects.
- SUBSYS_HANDLES // Duplication of handles to other processes.
- };
-
- // Allowable semantics when a rule is matched.
- enum Semantics {
- FILES_ALLOW_ANY, // Allows open or create for any kind of access that
- // the file system supports.
- FILES_ALLOW_READONLY, // Allows open or create with read access only.
- FILES_ALLOW_QUERY, // Allows access to query the attributes of a file.
- FILES_ALLOW_DIR_ANY, // Allows open or create with directory semantics
- // only.
- HANDLES_DUP_ANY, // Allows duplicating handles opened with any
- // access permissions.
- HANDLES_DUP_BROKER, // Allows duplicating handles to the broker process.
- NAMEDPIPES_ALLOW_ANY, // Allows creation of a named pipe.
- PROCESS_MIN_EXEC, // Allows to create a process with minimal rights
- // over the resulting process and thread handles.
- // No other parameters besides the command line are
- // passed to the child process.
- PROCESS_ALL_EXEC, // Allows the creation of a process and return fill
- // access on the returned handles.
- // This flag can be used only when the main token of
- // the sandboxed application is at least INTERACTIVE.
- EVENTS_ALLOW_ANY, // Allows the creation of an event with full access.
- EVENTS_ALLOW_READONLY, // Allows opening an even with synchronize access.
- REG_ALLOW_READONLY, // Allows readonly access to a registry key.
- REG_ALLOW_ANY // Allows read and write access to a registry key.
- };
-
- // Increments the reference count of this object. The reference count must
- // be incremented if this interface is given to another component.
- virtual void AddRef() = 0;
-
- // Decrements the reference count of this object. When the reference count
- // is zero the object is automatically destroyed.
- // Indicates that the caller is done with this interface. After calling
- // release no other method should be called.
- virtual void Release() = 0;
-
- // Sets the security level for the target process' two tokens.
- // This setting is permanent and cannot be changed once the target process is
- // spawned.
- // initial: the security level for the initial token. This is the token that
- // is used by the process from the creation of the process until the moment
- // the process calls TargetServices::LowerToken() or the process calls
- // win32's ReverToSelf(). Once this happens the initial token is no longer
- // available and the lockdown token is in effect.
- // lockdown: the security level for the token that comes into force after the
- // process calls TargetServices::LowerToken() or the process calls
- // ReverToSelf(). See the explanation of each level in the TokenLevel
- // definition.
- // Return value: SBOX_ALL_OK if the setting succeeds and false otherwise.
- // Returns false if the lockdown value is more permissive than the initial
- // value.
- //
- // Important: most of the sandbox-provided security relies on this single
- // setting. The caller should strive to set the lockdown level as restricted
- // as possible.
- virtual ResultCode SetTokenLevel(TokenLevel initial, TokenLevel lockdown) = 0;
-
- // Sets the security level of the Job Object to which the target process will
- // belong. This setting is permanent and cannot be changed once the target
- // process is spawned. The job controls the global security settings which
- // can not be specified in the token security profile.
- // job_level: the security level for the job. See the explanation of each
- // level in the JobLevel definition.
- // ui_exceptions: specify what specific rights that are disabled in the
- // chosen job_level that need to be granted. Use this parameter to avoid
- // selecting the next permissive job level unless you need all the rights
- // that are granted in such level.
- // The exceptions can be specified as a combination of the following
- // constants:
- // JOB_OBJECT_UILIMIT_HANDLES : grant access to all user-mode handles. These
- // include windows, icons, menus and various GDI objects. In addition the
- // target process can set hooks, and broadcast messages to other processes
- // that belong to the same desktop.
- // JOB_OBJECT_UILIMIT_READCLIPBOARD : grant read-only access to the clipboard.
- // JOB_OBJECT_UILIMIT_WRITECLIPBOARD : grant write access to the clipboard.
- // JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS : allow changes to the system-wide
- // parameters as defined by the Win32 call SystemParametersInfo().
- // JOB_OBJECT_UILIMIT_DISPLAYSETTINGS : allow programmatic changes to the
- // display settings.
- // JOB_OBJECT_UILIMIT_GLOBALATOMS : allow access to the global atoms table.
- // JOB_OBJECT_UILIMIT_DESKTOP : allow the creation of new desktops.
- // JOB_OBJECT_UILIMIT_EXITWINDOWS : allow the call to ExitWindows().
- //
- // Return value: SBOX_ALL_OK if the setting succeeds and false otherwise.
- //
- // Note: JOB_OBJECT_XXXX constants are defined in winnt.h and documented at
- // length in:
- // http://msdn2.microsoft.com/en-us/library/ms684152.aspx
- //
- // Note: the recommended level is JOB_RESTRICTED or JOB_LOCKDOWN.
- virtual ResultCode SetJobLevel(JobLevel job_level, uint32 ui_exceptions) = 0;
-
- // Specifies the desktop on which the application is going to run. If the
- // desktop does not exist, it will be created. If alternate_winstation is
- // set to true, the desktop will be created on an alternate window station.
- virtual ResultCode SetAlternateDesktop(bool alternate_winstation) = 0;
-
- // Returns the name of the alternate desktop used. If an alternate window
- // station is specified, the name is prepended by the window station name,
- // followed by a backslash.
- virtual std::wstring GetAlternateDesktop() const = 0;
-
- // Precreates the desktop and window station, if any.
- virtual ResultCode CreateAlternateDesktop(bool alternate_winstation) = 0;
-
- // Destroys the desktop and windows station.
- virtual void DestroyAlternateDesktop() = 0;
-
- // Sets the integrity level of the process in the sandbox. Both the initial
- // token and the main token will be affected by this. This is valid only
- // on Vista. It is silently ignored on other OSes. If you set the integrity
- // level to a level higher than your current level, the sandbox will fail
- // to start.
- virtual ResultCode SetIntegrityLevel(IntegrityLevel level) = 0;
-
- // Sets the integrity level of the process in the sandbox. The integrity level
- // will not take effect before you call LowerToken. User Interface Privilege
- // Isolation is not affected by this setting and will remain off for the
- // process in the sandbox. This flag is valid on Vista only, it is silently
- // ignored on other OSes. If you set the integrity level to a level higher
- // than your current level, the sandbox will fail to start.
- virtual ResultCode SetDelayedIntegrityLevel(IntegrityLevel level) = 0;
-
- // Sets the interceptions to operate in strict mode. By default, interceptions
- // are performed in "relaxed" mode, where if something inside NTDLL.DLL is
- // already patched we attempt to intercept it anyway. Setting interceptions
- // to strict mode means that when we detect that the function is patched we'll
- // refuse to perform the interception.
- virtual void SetStrictInterceptions() = 0;
-
- // Adds a policy rule effective for processes spawned using this policy.
- // subsystem: One of the above enumerated windows subsystems.
- // semantics: One of the above enumerated FileSemantics.
- // pattern: A specific full path or a full path with wildcard patterns.
- // The valid wildcards are:
- // '*' : Matches zero or more character. Only one in series allowed.
- // '?' : Matches a single character. One or more in series are allowed.
- // Examples:
- // "c:\\documents and settings\\vince\\*.dmp"
- // "c:\\documents and settings\\*\\crashdumps\\*.dmp"
- // "c:\\temp\\app_log_?????_chrome.txt"
- virtual ResultCode AddRule(SubSystem subsystem, Semantics semantics,
- const wchar_t* pattern) = 0;
-
- // Adds a dll that will be unloaded in the target process before it gets
- // a chance to initialize itself. Typically, dlls that cause the target
- // to crash go here.
- virtual ResultCode AddDllToUnload(const wchar_t* dll_name) = 0;
-
- // Adds a handle that will be closed in the target process after lockdown.
- // A NULL value for handle_name indicates all handles of the specified type.
- // An empty string for handle_name indicates the handle is unnamed.
- virtual ResultCode AddKernelObjectToClose(const wchar_t* handle_type,
- const wchar_t* handle_name) = 0;
-};
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_SANDBOX_POLICY_H_
diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc
deleted file mode 100644
index 63e77d5..0000000
--- a/sandbox/win/src/sandbox_policy_base.cc
+++ /dev/null
@@ -1,542 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/sandbox_policy_base.h"
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "base/logging.h"
-#include "sandbox/win/src/filesystem_dispatcher.h"
-#include "sandbox/win/src/filesystem_policy.h"
-#include "sandbox/win/src/handle_dispatcher.h"
-#include "sandbox/win/src/handle_policy.h"
-#include "sandbox/win/src/job.h"
-#include "sandbox/win/src/interception.h"
-#include "sandbox/win/src/named_pipe_dispatcher.h"
-#include "sandbox/win/src/named_pipe_policy.h"
-#include "sandbox/win/src/policy_broker.h"
-#include "sandbox/win/src/policy_engine_processor.h"
-#include "sandbox/win/src/policy_low_level.h"
-#include "sandbox/win/src/process_thread_dispatcher.h"
-#include "sandbox/win/src/process_thread_policy.h"
-#include "sandbox/win/src/registry_dispatcher.h"
-#include "sandbox/win/src/registry_policy.h"
-#include "sandbox/win/src/restricted_token_utils.h"
-#include "sandbox/win/src/sandbox_policy.h"
-#include "sandbox/win/src/sync_dispatcher.h"
-#include "sandbox/win/src/sync_policy.h"
-#include "sandbox/win/src/target_process.h"
-#include "sandbox/win/src/window.h"
-
-namespace {
-// The standard windows size for one memory page.
-const size_t kOneMemPage = 4096;
-// The IPC and Policy shared memory sizes.
-const size_t kIPCMemSize = kOneMemPage * 2;
-const size_t kPolMemSize = kOneMemPage * 14;
-
-// Helper function to allocate space (on the heap) for policy.
-sandbox::PolicyGlobal* MakeBrokerPolicyMemory() {
- const size_t kTotalPolicySz = kPolMemSize;
- char* mem = new char[kTotalPolicySz];
- DCHECK(mem);
- memset(mem, 0, kTotalPolicySz);
- sandbox::PolicyGlobal* policy = reinterpret_cast<sandbox::PolicyGlobal*>(mem);
- policy->data_size = kTotalPolicySz - sizeof(sandbox::PolicyGlobal);
- return policy;
-}
-}
-
-namespace sandbox {
-
-SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level;
-
-// Initializes static members.
-HWINSTA PolicyBase::alternate_winstation_handle_ = NULL;
-HDESK PolicyBase::alternate_desktop_handle_ = NULL;
-
-PolicyBase::PolicyBase()
- : ref_count(1),
- lockdown_level_(USER_LOCKDOWN),
- initial_level_(USER_LOCKDOWN),
- job_level_(JOB_LOCKDOWN),
- ui_exceptions_(0),
- use_alternate_desktop_(false),
- use_alternate_winstation_(false),
- file_system_init_(false),
- relaxed_interceptions_(true),
- integrity_level_(INTEGRITY_LEVEL_LAST),
- delayed_integrity_level_(INTEGRITY_LEVEL_LAST),
- policy_maker_(NULL),
- policy_(NULL) {
- ::InitializeCriticalSection(&lock_);
- // Initialize the IPC dispatcher array.
- memset(&ipc_targets_, NULL, sizeof(ipc_targets_));
- Dispatcher* dispatcher = NULL;
-
- dispatcher = new FilesystemDispatcher(this);
- ipc_targets_[IPC_NTCREATEFILE_TAG] = dispatcher;
- ipc_targets_[IPC_NTOPENFILE_TAG] = dispatcher;
- ipc_targets_[IPC_NTSETINFO_RENAME_TAG] = dispatcher;
- ipc_targets_[IPC_NTQUERYATTRIBUTESFILE_TAG] = dispatcher;
- ipc_targets_[IPC_NTQUERYFULLATTRIBUTESFILE_TAG] = dispatcher;
-
- dispatcher = new NamedPipeDispatcher(this);
- ipc_targets_[IPC_CREATENAMEDPIPEW_TAG] = dispatcher;
-
- dispatcher = new ThreadProcessDispatcher(this);
- ipc_targets_[IPC_NTOPENTHREAD_TAG] = dispatcher;
- ipc_targets_[IPC_NTOPENPROCESS_TAG] = dispatcher;
- ipc_targets_[IPC_CREATEPROCESSW_TAG] = dispatcher;
- ipc_targets_[IPC_NTOPENPROCESSTOKEN_TAG] = dispatcher;
- ipc_targets_[IPC_NTOPENPROCESSTOKENEX_TAG] = dispatcher;
-
- dispatcher = new SyncDispatcher(this);
- ipc_targets_[IPC_CREATEEVENT_TAG] = dispatcher;
- ipc_targets_[IPC_OPENEVENT_TAG] = dispatcher;
-
- dispatcher = new RegistryDispatcher(this);
- ipc_targets_[IPC_NTCREATEKEY_TAG] = dispatcher;
- ipc_targets_[IPC_NTOPENKEY_TAG] = dispatcher;
-
- dispatcher = new HandleDispatcher(this);
- ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG] = dispatcher;
-}
-
-PolicyBase::~PolicyBase() {
- TargetSet::iterator it;
- for (it = targets_.begin(); it != targets_.end(); ++it) {
- TargetProcess* target = (*it);
- delete target;
- }
- delete ipc_targets_[IPC_NTCREATEFILE_TAG];
- delete ipc_targets_[IPC_CREATENAMEDPIPEW_TAG];
- delete ipc_targets_[IPC_NTOPENTHREAD_TAG];
- delete ipc_targets_[IPC_CREATEEVENT_TAG];
- delete ipc_targets_[IPC_NTCREATEKEY_TAG];
- delete ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG];
- delete policy_maker_;
- delete policy_;
- ::DeleteCriticalSection(&lock_);
-}
-
-void PolicyBase::AddRef() {
- ::InterlockedIncrement(&ref_count);
-}
-
-void PolicyBase::Release() {
- if (0 == ::InterlockedDecrement(&ref_count))
- delete this;
-}
-
-ResultCode PolicyBase::SetTokenLevel(TokenLevel initial, TokenLevel lockdown) {
- if (initial < lockdown) {
- return SBOX_ERROR_BAD_PARAMS;
- }
- initial_level_ = initial;
- lockdown_level_ = lockdown;
- return SBOX_ALL_OK;
-}
-
-ResultCode PolicyBase::SetJobLevel(JobLevel job_level, uint32 ui_exceptions) {
- job_level_ = job_level;
- ui_exceptions_ = ui_exceptions;
- return SBOX_ALL_OK;
-}
-
-ResultCode PolicyBase::SetAlternateDesktop(bool alternate_winstation) {
- use_alternate_desktop_ = true;
- use_alternate_winstation_ = alternate_winstation;
- return CreateAlternateDesktop(alternate_winstation);
-}
-
-std::wstring PolicyBase::GetAlternateDesktop() const {
- // No alternate desktop or winstation. Return an empty string.
- if (!use_alternate_desktop_ && !use_alternate_winstation_) {
- return std::wstring();
- }
-
- // The desktop and winstation should have been created by now.
- // If we hit this scenario, it means that the user ignored the failure
- // during SetAlternateDesktop, so we ignore it here too.
- if (use_alternate_desktop_ && !alternate_desktop_handle_) {
- return std::wstring();
- }
- if (use_alternate_winstation_ && (!alternate_desktop_handle_ ||
- !alternate_winstation_handle_)) {
- return std::wstring();
- }
-
- return GetFullDesktopName(alternate_winstation_handle_,
- alternate_desktop_handle_);
-}
-
-ResultCode PolicyBase::CreateAlternateDesktop(bool alternate_winstation) {
- if (alternate_winstation) {
- // Previously called with alternate_winstation = false?
- if (!alternate_winstation_handle_ && alternate_desktop_handle_)
- return SBOX_ERROR_UNSUPPORTED;
-
- // Check if it's already created.
- if (alternate_winstation_handle_ && alternate_desktop_handle_)
- return SBOX_ALL_OK;
-
- DCHECK(!alternate_winstation_handle_);
- // Create the window station.
- ResultCode result = CreateAltWindowStation(&alternate_winstation_handle_);
- if (SBOX_ALL_OK != result)
- return result;
-
- // Verify that everything is fine.
- if (!alternate_winstation_handle_ ||
- GetWindowObjectName(alternate_winstation_handle_).empty())
- return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
-
- // Create the destkop.
- result = CreateAltDesktop(alternate_winstation_handle_,
- &alternate_desktop_handle_);
- if (SBOX_ALL_OK != result)
- return result;
-
- // Verify that everything is fine.
- if (!alternate_desktop_handle_ ||
- GetWindowObjectName(alternate_desktop_handle_).empty())
- return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
- } else {
- // Previously called with alternate_winstation = true?
- if (alternate_winstation_handle_)
- return SBOX_ERROR_UNSUPPORTED;
-
- // Check if it already exists.
- if (alternate_desktop_handle_)
- return SBOX_ALL_OK;
-
- // Create the destkop.
- ResultCode result = CreateAltDesktop(NULL, &alternate_desktop_handle_);
- if (SBOX_ALL_OK != result)
- return result;
-
- // Verify that everything is fine.
- if (!alternate_desktop_handle_ ||
- GetWindowObjectName(alternate_desktop_handle_).empty())
- return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
- }
-
- return SBOX_ALL_OK;
-}
-
-void PolicyBase::DestroyAlternateDesktop() {
- if (alternate_desktop_handle_) {
- ::CloseDesktop(alternate_desktop_handle_);
- alternate_desktop_handle_ = NULL;
- }
-
- if (alternate_winstation_handle_) {
- ::CloseWindowStation(alternate_winstation_handle_);
- alternate_winstation_handle_ = NULL;
- }
-}
-
-ResultCode PolicyBase::SetIntegrityLevel(IntegrityLevel integrity_level) {
- integrity_level_ = integrity_level;
- return SBOX_ALL_OK;
-}
-
-ResultCode PolicyBase::SetDelayedIntegrityLevel(
- IntegrityLevel integrity_level) {
- delayed_integrity_level_ = integrity_level;
- return SBOX_ALL_OK;
-}
-
-void PolicyBase::SetStrictInterceptions() {
- relaxed_interceptions_ = false;
-}
-
-ResultCode PolicyBase::AddRule(SubSystem subsystem, Semantics semantics,
- const wchar_t* pattern) {
- if (NULL == policy_) {
- policy_ = MakeBrokerPolicyMemory();
- DCHECK(policy_);
- policy_maker_ = new LowLevelPolicy(policy_);
- DCHECK(policy_maker_);
- }
-
- switch (subsystem) {
- case SUBSYS_FILES: {
- if (!file_system_init_) {
- if (!FileSystemPolicy::SetInitialRules(policy_maker_))
- return SBOX_ERROR_BAD_PARAMS;
- file_system_init_ = true;
- }
- if (!FileSystemPolicy::GenerateRules(pattern, semantics, policy_maker_)) {
- NOTREACHED();
- return SBOX_ERROR_BAD_PARAMS;
- }
- break;
- }
- case SUBSYS_SYNC: {
- if (!SyncPolicy::GenerateRules(pattern, semantics, policy_maker_)) {
- NOTREACHED();
- return SBOX_ERROR_BAD_PARAMS;
- }
- break;
- }
- case SUBSYS_PROCESS: {
- if (lockdown_level_ < USER_INTERACTIVE &&
- TargetPolicy::PROCESS_ALL_EXEC == semantics) {
- // This is unsupported. This is a huge security risk to give full access
- // to a process handle.
- return SBOX_ERROR_UNSUPPORTED;
- }
- if (!ProcessPolicy::GenerateRules(pattern, semantics, policy_maker_)) {
- NOTREACHED();
- return SBOX_ERROR_BAD_PARAMS;
- }
- break;
- }
- case SUBSYS_NAMED_PIPES: {
- if (!NamedPipePolicy::GenerateRules(pattern, semantics, policy_maker_)) {
- NOTREACHED();
- return SBOX_ERROR_BAD_PARAMS;
- }
- break;
- }
- case SUBSYS_REGISTRY: {
- if (!RegistryPolicy::GenerateRules(pattern, semantics, policy_maker_)) {
- NOTREACHED();
- return SBOX_ERROR_BAD_PARAMS;
- }
- break;
- }
- case SUBSYS_HANDLES: {
- if (!HandlePolicy::GenerateRules(pattern, semantics, policy_maker_)) {
- NOTREACHED();
- return SBOX_ERROR_BAD_PARAMS;
- }
- break;
- }
- default: {
- return SBOX_ERROR_UNSUPPORTED;
- }
- }
-
- return SBOX_ALL_OK;
-}
-
-ResultCode PolicyBase::AddDllToUnload(const wchar_t* dll_name) {
- blacklisted_dlls_.push_back(std::wstring(dll_name));
- return SBOX_ALL_OK;
-}
-
-ResultCode PolicyBase::AddKernelObjectToClose(const char16* handle_type,
- const char16* handle_name) {
- return handle_closer_.AddHandle(handle_type, handle_name);
-}
-
-// When an IPC is ready in any of the targets we get called. We manage an array
-// of IPC dispatchers which are keyed on the IPC tag so we normally delegate
-// to the appropriate dispatcher unless we can handle the IPC call ourselves.
-Dispatcher* PolicyBase::OnMessageReady(IPCParams* ipc,
- CallbackGeneric* callback) {
- DCHECK(callback);
- static const IPCParams ping1 = {IPC_PING1_TAG, ULONG_TYPE};
- static const IPCParams ping2 = {IPC_PING2_TAG, INOUTPTR_TYPE};
-
- if (ping1.Matches(ipc) || ping2.Matches(ipc)) {
- *callback = reinterpret_cast<CallbackGeneric>(
- static_cast<Callback1>(&PolicyBase::Ping));
- return this;
- }
-
- Dispatcher* dispatch = GetDispatcher(ipc->ipc_tag);
- if (!dispatch) {
- NOTREACHED();
- return NULL;
- }
- return dispatch->OnMessageReady(ipc, callback);
-}
-
-// Delegate to the appropriate dispatcher.
-bool PolicyBase::SetupService(InterceptionManager* manager, int service) {
- if (IPC_PING1_TAG == service || IPC_PING2_TAG == service)
- return true;
-
- Dispatcher* dispatch = GetDispatcher(service);
- if (!dispatch) {
- NOTREACHED();
- return false;
- }
- return dispatch->SetupService(manager, service);
-}
-
-DWORD PolicyBase::MakeJobObject(HANDLE* job) {
- // Create the windows job object.
- Job job_obj;
- DWORD result = job_obj.Init(job_level_, NULL, ui_exceptions_);
- if (ERROR_SUCCESS != result) {
- return result;
- }
- *job = job_obj.Detach();
- return ERROR_SUCCESS;
-}
-
-DWORD PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) {
- // Create the 'naked' token. This will be the permanent token associated
- // with the process and therefore with any thread that is not impersonating.
- DWORD result = CreateRestrictedToken(lockdown, lockdown_level_,
- integrity_level_, PRIMARY);
- if (ERROR_SUCCESS != result) {
- return result;
- }
- // Create the 'better' token. We use this token as the one that the main
- // thread uses when booting up the process. It should contain most of
- // what we need (before reaching main( ))
- result = CreateRestrictedToken(initial, initial_level_,
- integrity_level_, IMPERSONATION);
- if (ERROR_SUCCESS != result) {
- ::CloseHandle(*lockdown);
- return result;
- }
- return SBOX_ALL_OK;
-}
-
-bool PolicyBase::AddTarget(TargetProcess* target) {
- if (NULL != policy_)
- policy_maker_->Done();
-
- if (!SetupAllInterceptions(target))
- return false;
-
- if (!SetupHandleCloser(target))
- return false;
-
- // Initialize the sandbox infrastructure for the target.
- if (ERROR_SUCCESS != target->Init(this, policy_, kIPCMemSize, kPolMemSize))
- return false;
-
- g_shared_delayed_integrity_level = delayed_integrity_level_;
- ResultCode ret = target->TransferVariable(
- "g_shared_delayed_integrity_level",
- &g_shared_delayed_integrity_level,
- sizeof(g_shared_delayed_integrity_level));
- g_shared_delayed_integrity_level = INTEGRITY_LEVEL_LAST;
- if (SBOX_ALL_OK != ret)
- return false;
-
- AutoLock lock(&lock_);
- targets_.push_back(target);
- return true;
-}
-
-bool PolicyBase::OnJobEmpty(HANDLE job) {
- AutoLock lock(&lock_);
- TargetSet::iterator it;
- for (it = targets_.begin(); it != targets_.end(); ++it) {
- if ((*it)->Job() == job)
- break;
- }
- if (it == targets_.end()) {
- return false;
- }
- TargetProcess* target = *it;
- targets_.erase(it);
- delete target;
- return true;
-}
-
-EvalResult PolicyBase::EvalPolicy(int service,
- CountedParameterSetBase* params) {
- if (NULL != policy_) {
- if (NULL == policy_->entry[service]) {
- // There is no policy for this particular service. This is not a big
- // deal.
- return DENY_ACCESS;
- }
- for (int i = 0; i < params->count; i++) {
- if (!params->parameters[i].IsValid()) {
- NOTREACHED();
- return SIGNAL_ALARM;
- }
- }
- PolicyProcessor pol_evaluator(policy_->entry[service]);
- PolicyResult result = pol_evaluator.Evaluate(kShortEval,
- params->parameters,
- params->count);
- if (POLICY_MATCH == result) {
- return pol_evaluator.GetAction();
- }
- DCHECK(POLICY_ERROR != result);
- }
-
- return DENY_ACCESS;
-}
-
-// We service IPC_PING_TAG message which is a way to test a round trip of the
-// IPC subsystem. We receive a integer cookie and we are expected to return the
-// cookie times two (or three) and the current tick count.
-bool PolicyBase::Ping(IPCInfo* ipc, void* arg1) {
- switch (ipc->ipc_tag) {
- case IPC_PING1_TAG: {
- IPCInt ipc_int(arg1);
- uint32 cookie = ipc_int.As32Bit();
- ipc->return_info.extended_count = 2;
- ipc->return_info.extended[0].unsigned_int = ::GetTickCount();
- ipc->return_info.extended[1].unsigned_int = 2 * cookie;
- return true;
- }
- case IPC_PING2_TAG: {
- CountedBuffer* io_buffer = reinterpret_cast<CountedBuffer*>(arg1);
- if (sizeof(uint32) != io_buffer->Size())
- return false;
-
- uint32* cookie = reinterpret_cast<uint32*>(io_buffer->Buffer());
- *cookie = (*cookie) * 3;
- return true;
- }
- default: return false;
- }
-}
-
-Dispatcher* PolicyBase::GetDispatcher(int ipc_tag) {
- if (ipc_tag >= IPC_LAST_TAG || ipc_tag <= IPC_UNUSED_TAG)
- return NULL;
-
- return ipc_targets_[ipc_tag];
-}
-
-bool PolicyBase::SetupAllInterceptions(TargetProcess* target) {
- InterceptionManager manager(target, relaxed_interceptions_);
-
- if (policy_) {
- for (int i = 0; i < IPC_LAST_TAG; i++) {
- if (policy_->entry[i] && !ipc_targets_[i]->SetupService(&manager, i))
- return false;
- }
- }
-
- if (!blacklisted_dlls_.empty()) {
- std::vector<std::wstring>::iterator it = blacklisted_dlls_.begin();
- for (; it != blacklisted_dlls_.end(); ++it) {
- manager.AddToUnloadModules(it->c_str());
- }
- }
-
- if (!handle_closer_.SetupHandleInterceptions(&manager))
- return false;
-
- if (!SetupBasicInterceptions(&manager))
- return false;
-
- if (!manager.InitializeInterceptions())
- return false;
-
- // Finally, setup imports on the target so the interceptions can work.
- return SetupNtdllImports(target);
-}
-
-bool PolicyBase::SetupHandleCloser(TargetProcess* target) {
- return handle_closer_.InitializeTargetHandles(target);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/sandbox_policy_base.h b/sandbox/win/src/sandbox_policy_base.h
deleted file mode 100644
index 8fdfe91..0000000
--- a/sandbox/win/src/sandbox_policy_base.h
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SANDBOX_POLICY_BASE_H_
-#define SANDBOX_SRC_SANDBOX_POLICY_BASE_H_
-
-#include <windows.h>
-
-#include <list>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/string16.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/handle_closer.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_engine_opcodes.h"
-#include "sandbox/win/src/policy_engine_params.h"
-#include "sandbox/win/src/sandbox_policy.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace sandbox {
-
-class LowLevelPolicy;
-class TargetProcess;
-struct PolicyGlobal;
-
-// We act as a policy dispatcher, implementing the handler for the "ping" IPC,
-// so we have to provide the appropriate handler on the OnMessageReady method.
-// There is a static_cast for the handler, and the compiler only performs the
-// cast if the first base class is Dispatcher.
-class PolicyBase : public Dispatcher, public TargetPolicy {
- public:
- PolicyBase();
-
- // TargetPolicy:
- virtual void AddRef() OVERRIDE;
- virtual void Release() OVERRIDE;
- virtual ResultCode SetTokenLevel(TokenLevel initial,
- TokenLevel lockdown) OVERRIDE;
- virtual ResultCode SetJobLevel(JobLevel job_level,
- uint32 ui_exceptions) OVERRIDE;
- virtual ResultCode SetAlternateDesktop(bool alternate_winstation) OVERRIDE;
- virtual std::wstring GetAlternateDesktop() const OVERRIDE;
- virtual ResultCode CreateAlternateDesktop(bool alternate_winstation) OVERRIDE;
- virtual void DestroyAlternateDesktop() OVERRIDE;
- virtual ResultCode SetIntegrityLevel(IntegrityLevel integrity_level) OVERRIDE;
- virtual ResultCode SetDelayedIntegrityLevel(
- IntegrityLevel integrity_level) OVERRIDE;
- virtual void SetStrictInterceptions() OVERRIDE;
- virtual ResultCode AddRule(SubSystem subsystem, Semantics semantics,
- const wchar_t* pattern) OVERRIDE;
- virtual ResultCode AddDllToUnload(const wchar_t* dll_name);
- virtual ResultCode AddKernelObjectToClose(const char16* handle_type,
- const char16* handle_name) OVERRIDE;
-
- // Dispatcher:
- virtual Dispatcher* OnMessageReady(IPCParams* ipc,
- CallbackGeneric* callback) OVERRIDE;
- virtual bool SetupService(InterceptionManager* manager, int service) OVERRIDE;
-
- // Creates a Job object with the level specified in a previous call to
- // SetJobLevel(). Returns the standard windows of ::GetLastError().
- DWORD MakeJobObject(HANDLE* job);
-
- // Creates the two tokens with the levels specified in a previous call to
- // SetTokenLevel(). Returns the standard windows of ::GetLastError().
- DWORD MakeTokens(HANDLE* initial, HANDLE* lockdown);
-
- // Adds a target process to the internal list of targets. Internally a
- // call to TargetProcess::Init() is issued.
- bool AddTarget(TargetProcess* target);
-
- // Called when there are no more active processes in a Job.
- // Removes a Job object associated with this policy and the target associated
- // with the job.
- bool OnJobEmpty(HANDLE job);
-
- EvalResult EvalPolicy(int service, CountedParameterSetBase* params);
-
- private:
- ~PolicyBase();
-
- // Test IPC providers.
- bool Ping(IPCInfo* ipc, void* cookie);
-
- // Returns a dispatcher from ipc_targets_.
- Dispatcher* GetDispatcher(int ipc_tag);
-
- // Sets up interceptions for a new target.
- bool SetupAllInterceptions(TargetProcess* target);
-
- // Sets up the handle closer for a new target.
- bool SetupHandleCloser(TargetProcess* target);
-
- // This lock synchronizes operations on the targets_ collection.
- CRITICAL_SECTION lock_;
- // Maintains the list of target process associated with this policy.
- // The policy takes ownership of them.
- typedef std::list<TargetProcess*> TargetSet;
- TargetSet targets_;
- // Standard object-lifetime reference counter.
- volatile LONG ref_count;
- // The user-defined global policy settings.
- TokenLevel lockdown_level_;
- TokenLevel initial_level_;
- JobLevel job_level_;
- uint32 ui_exceptions_;
- bool use_alternate_desktop_;
- bool use_alternate_winstation_;
- // Helps the file system policy initialization.
- bool file_system_init_;
- bool relaxed_interceptions_;
- IntegrityLevel integrity_level_;
- IntegrityLevel delayed_integrity_level_;
- // The array of objects that will answer IPC calls.
- Dispatcher* ipc_targets_[IPC_LAST_TAG];
- // Object in charge of generating the low level policy.
- LowLevelPolicy* policy_maker_;
- // Memory structure that stores the low level policy.
- PolicyGlobal* policy_;
- // The list of dlls to unload in the target process.
- std::vector<std::wstring> blacklisted_dlls_;
- // This is a map of handle-types to names that we need to close in the
- // target process. A null set means we need to close all handles of the
- // given type.
- HandleCloser handle_closer_;
-
- static HDESK alternate_desktop_handle_;
- static HWINSTA alternate_winstation_handle_;
-
- DISALLOW_COPY_AND_ASSIGN(PolicyBase);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_SANDBOX_POLICY_BASE_H_
diff --git a/sandbox/win/src/sandbox_types.h b/sandbox/win/src/sandbox_types.h
deleted file mode 100644
index ce9b767..0000000
--- a/sandbox/win/src/sandbox_types.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2006-2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SANDBOX_TYPES_H_
-#define SANDBOX_SRC_SANDBOX_TYPES_H_
-
-namespace sandbox {
-
-// Operation result codes returned by the sandbox API.
-enum ResultCode {
- SBOX_ALL_OK = 0,
- // Error is originating on the win32 layer. Call GetlastError() for more
- // information.
- SBOX_ERROR_GENERIC = 1,
- // An invalid combination of parameters was given to the API.
- SBOX_ERROR_BAD_PARAMS = 2,
- // The desired operation is not supported at this time.
- SBOX_ERROR_UNSUPPORTED = 3,
- // The request requires more memory that allocated or available.
- SBOX_ERROR_NO_SPACE = 4,
- // The ipc service requested does not exist.
- SBOX_ERROR_INVALID_IPC = 5,
- // The ipc service did not complete.
- SBOX_ERROR_FAILED_IPC = 6,
- // The requested handle was not found.
- SBOX_ERROR_NO_HANDLE = 7,
- // This function was not expected to be called at this time.
- SBOX_ERROR_UNEXPECTED_CALL = 8,
- // WaitForAllTargets is already called.
- SBOX_ERROR_WAIT_ALREADY_CALLED = 9,
- // A channel error prevented DoCall from executing.
- SBOX_ERROR_CHANNEL_ERROR = 10,
- // Failed to create the alternate desktop.
- SBOX_ERROR_CANNOT_CREATE_DESKTOP = 11,
- // Failed to create the alternate window station.
- SBOX_ERROR_CANNOT_CREATE_WINSTATION = 12,
- // Failed to switch back to the interactive window station.
- SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION = 13,
- // Placeholder for last item of the enum.
- SBOX_ERROR_LAST
-};
-
-// If the sandbox cannot create a secure environment for the target, the
-// target will be forcibly terminated. These are the process exit codes.
-enum TerminationCodes {
- SBOX_FATAL_INTEGRITY = 7006, // Could not set the integrity level.
- SBOX_FATAL_DROPTOKEN = 7007, // Could not lower the token.
- SBOX_FATAL_FLUSHANDLES = 7008, // Failed to flush registry handles.
- SBOX_FATAL_CACHEDISABLE = 7009, // Failed to forbid HCKU caching.
- SBOX_FATAL_CLOSEHANDLES = 7010 // Failed to close pending handles.
-};
-
-class BrokerServices;
-class TargetServices;
-
-// Contains the pointer to a target or broker service.
-struct SandboxInterfaceInfo {
- BrokerServices* broker_services;
- TargetServices* target_services;
-};
-
-#if SANDBOX_EXPORTS
-#define SANDBOX_INTERCEPT extern "C" __declspec(dllexport)
-#else
-#define SANDBOX_INTERCEPT extern "C"
-#endif
-
-enum InterceptionType {
- INTERCEPTION_INVALID = 0,
- INTERCEPTION_SERVICE_CALL, // Trampoline of an NT native call
- INTERCEPTION_EAT,
- INTERCEPTION_SIDESTEP, // Preamble patch
- INTERCEPTION_SMART_SIDESTEP, // Preamble patch but bypass internal calls
- INTERCEPTION_UNLOAD_MODULE, // Unload the module (don't patch)
- INTERCEPTION_LAST // Placeholder for last item in the enumeration
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_SANDBOX_TYPES_H_
diff --git a/sandbox/win/src/sandbox_utils.cc b/sandbox/win/src/sandbox_utils.cc
deleted file mode 100644
index 509c7c8..0000000
--- a/sandbox/win/src/sandbox_utils.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/sandbox_utils.h"
-
-#include <windows.h>
-
-#include "base/logging.h"
-#include "base/win/windows_version.h"
-#include "sandbox/win/src/internal_types.h"
-#include "sandbox/win/src/nt_internals.h"
-
-namespace sandbox {
-
-bool GetModuleHandleHelper(DWORD flags, const wchar_t* module_name,
- HMODULE* module) {
- DCHECK(module);
-
- HMODULE kernel32_base = ::GetModuleHandle(kKerneldllName);
- if (!kernel32_base) {
- NOTREACHED();
- return false;
- }
-
- GetModuleHandleExFunction get_module_handle_ex = reinterpret_cast<
- GetModuleHandleExFunction>(::GetProcAddress(kernel32_base,
- "GetModuleHandleExW"));
- if (get_module_handle_ex) {
- BOOL ret = get_module_handle_ex(flags, module_name, module);
- return (ret ? true : false);
- }
-
- if (!flags) {
- *module = ::LoadLibrary(module_name);
- } else if (flags & GET_MODULE_HANDLE_EX_FLAG_PIN) {
- NOTREACHED();
- return false;
- } else if (!(flags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)) {
- DCHECK((flags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT) ==
- GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT);
-
- *module = ::GetModuleHandle(module_name);
- } else {
- DCHECK((flags & (GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
- GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)) ==
- (GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
- GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS));
-
- MEMORY_BASIC_INFORMATION info = {0};
- size_t returned = VirtualQuery(module_name, &info, sizeof(info));
- if (sizeof(info) != returned)
- return false;
- *module = reinterpret_cast<HMODULE>(info.AllocationBase);
- }
- return true;
-}
-
-bool IsXPSP2OrLater() {
- base::win::Version version = base::win::GetVersion();
- return (version > base::win::VERSION_XP) ||
- ((version == base::win::VERSION_XP) &&
- (base::win::OSInfo::GetInstance()->service_pack().major >= 2));
-}
-
-void InitObjectAttribs(const std::wstring& name, ULONG attributes, HANDLE root,
- OBJECT_ATTRIBUTES* obj_attr, UNICODE_STRING* uni_name) {
- static RtlInitUnicodeStringFunction RtlInitUnicodeString;
- if (!RtlInitUnicodeString) {
- HMODULE ntdll = ::GetModuleHandle(kNtdllName);
- RtlInitUnicodeString = reinterpret_cast<RtlInitUnicodeStringFunction>(
- GetProcAddress(ntdll, "RtlInitUnicodeString"));
- DCHECK(RtlInitUnicodeString);
- }
- RtlInitUnicodeString(uni_name, name.c_str());
- InitializeObjectAttributes(obj_attr, uni_name, attributes, root, NULL);
-}
-
-}; // namespace sandbox
diff --git a/sandbox/win/src/sandbox_utils.h b/sandbox/win/src/sandbox_utils.h
deleted file mode 100644
index 8329698..0000000
--- a/sandbox/win/src/sandbox_utils.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SANDBOX_UTILS_H__
-#define SANDBOX_SRC_SANDBOX_UTILS_H__
-
-#include <windows.h>
-#include <string>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/nt_internals.h"
-
-namespace sandbox {
-
-typedef BOOL (WINAPI* GetModuleHandleExFunction)(DWORD flags,
- LPCWSTR module_name,
- HMODULE* module);
-
-// Windows XP provides a nice function in kernel32.dll called GetModuleHandleEx
-// This function allows us to verify if a function exported by the module
-// lies in the module itself.
-// As we need compatibility with windows 2000, we cannot use this function
-// by calling it by name. This helper function checks if the GetModuleHandleEx
-// function is exported by kernel32 and uses it, otherwise, implemets part of
-// the functionality exposed by GetModuleHandleEx.
-bool GetModuleHandleHelper(DWORD flags, const wchar_t* module_name,
- HMODULE* module);
-
-// Returns true if the current OS is Windows XP SP2 or later.
-bool IsXPSP2OrLater();
-
-void InitObjectAttribs(const std::wstring& name, ULONG attributes, HANDLE root,
- OBJECT_ATTRIBUTES* obj_attr, UNICODE_STRING* uni_name);
-
-}; // namespace sandbox
-
-#endif // SANDBOX_SRC_SANDBOX_UTILS_H__
diff --git a/sandbox/win/src/security_level.h b/sandbox/win/src/security_level.h
deleted file mode 100644
index 467f96f..0000000
--- a/sandbox/win/src/security_level.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SECURITY_LEVEL_H_
-#define SANDBOX_SRC_SECURITY_LEVEL_H_
-
-namespace sandbox {
-
-// List of all the integrity levels supported in the sandbox. This is used
-// only on Windows Vista. You can't set the integrity level of the process
-// in the sandbox to a level higher than yours.
-enum IntegrityLevel {
- INTEGRITY_LEVEL_SYSTEM,
- INTEGRITY_LEVEL_HIGH,
- INTEGRITY_LEVEL_MEDIUM,
- INTEGRITY_LEVEL_MEDIUM_LOW,
- INTEGRITY_LEVEL_LOW,
- INTEGRITY_LEVEL_BELOW_LOW,
- INTEGRITY_LEVEL_UNTRUSTED,
- INTEGRITY_LEVEL_LAST
-};
-
-// The Token level specifies a set of security profiles designed to
-// provide the bulk of the security of sandbox.
-//
-// TokenLevel |Restricting |Deny Only |Privileges|
-// |Sids |Sids | |
-// ----------------------------|--------------|----------------|----------|
-// USER_LOCKDOWN | Null Sid | All | None |
-// ----------------------------|--------------|----------------|----------|
-// USER_RESTRICTED | RESTRICTED | All | Traverse |
-// ----------------------------|--------------|----------------|----------|
-// USER_LIMITED | Users | All except: | Traverse |
-// | Everyone | Users | |
-// | RESTRICTED | Everyone | |
-// | | Interactive | |
-// ----------------------------|--------------|----------------|----------|
-// USER_INTERACTIVE | Users | All except: | Traverse |
-// | Everyone | Users | |
-// | RESTRICTED | Everyone | |
-// | Owner | Interactive | |
-// | | Local | |
-// | | Authent-users | |
-// | | User | |
-// ----------------------------|--------------|----------------|----------|
-// USER_NON_ADMIN | None | All except: | Traverse |
-// | | Users | |
-// | | Everyone | |
-// | | Interactive | |
-// | | Local | |
-// | | Authent-users | |
-// | | User | |
-// ----------------------------|--------------|----------------|----------|
-// USER_RESTRICTED_SAME_ACCESS | All | None | All |
-// ----------------------------|--------------|----------------|----------|
-// USER_UNPROTECTED | None | None | All |
-// ----------------------------|--------------|----------------|----------|
-//
-// The above restrictions are actually a transformation that is applied to
-// the existing broker process token. The resulting token that will be
-// applied to the target process depends both on the token level selected
-// and on the broker token itself.
-//
-// The LOCKDOWN and RESTRICTED are designed to allow access to almost
-// nothing that has security associated with and they are the recommended
-// levels to run sandboxed code specially if there is a chance that the
-// broker is process might be started by a user that belongs to the Admins
-// or power users groups.
-enum TokenLevel {
- USER_LOCKDOWN = 0,
- USER_RESTRICTED,
- USER_LIMITED,
- USER_INTERACTIVE,
- USER_NON_ADMIN,
- USER_RESTRICTED_SAME_ACCESS,
- USER_UNPROTECTED
-};
-
-// The Job level specifies a set of decreasing security profiles for the
-// Job object that the target process will be placed into.
-// This table summarizes the security associated with each level:
-//
-// JobLevel |General |Quota |
-// |restrictions |restrictions |
-// -----------------|---------------------------------- |--------------------|
-// JOB_UNPROTECTED | None | *Kill on Job close.|
-// -----------------|---------------------------------- |--------------------|
-// JOB_INTERACTIVE | *Forbid system-wide changes using | |
-// | SystemParametersInfo(). | *Kill on Job close.|
-// | *Forbid the creation/switch of | |
-// | Desktops. | |
-// | *Forbids calls to ExitWindows(). | |
-// -----------------|---------------------------------- |--------------------|
-// JOB_LIMITED_USER | Same as INTERACTIVE_USER plus: | *One active process|
-// | *Forbid changes to the display | limit. |
-// | settings. | *Kill on Job close.|
-// -----------------|---------------------------------- |--------------------|
-// JOB_RESTRICTED | Same as LIMITED_USER plus: | *One active process|
-// | * No read/write to the clipboard. | limit. |
-// | * No access to User Handles that | *Kill on Job close.|
-// | belong to other processes. | |
-// | * Forbid message broadcasts. | |
-// | * Forbid setting global hooks. | |
-// | * No access to the global atoms | |
-// | table. | |
-// -----------------|-----------------------------------|--------------------|
-// JOB_LOCKDOWN | Same as RESTRICTED | *One active process|
-// | | limit. |
-// | | *Kill on Job close.|
-// | | *Kill on unhandled |
-// | | exception. |
-// | | |
-// In the context of the above table, 'user handles' refers to the handles of
-// windows, bitmaps, menus, etc. Files, treads and registry handles are kernel
-// handles and are not affected by the job level settings.
-enum JobLevel {
- JOB_LOCKDOWN = 0,
- JOB_RESTRICTED,
- JOB_LIMITED_USER,
- JOB_INTERACTIVE,
- JOB_UNPROTECTED
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_SECURITY_LEVEL_H_
diff --git a/sandbox/win/src/service_resolver.cc b/sandbox/win/src/service_resolver.cc
deleted file mode 100644
index bae698c..0000000
--- a/sandbox/win/src/service_resolver.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/service_resolver.h"
-
-#include "base/logging.h"
-#include "base/win/pe_image.h"
-
-namespace sandbox {
-
-NTSTATUS ServiceResolverThunk::ResolveInterceptor(
- const void* interceptor_module,
- const char* interceptor_name,
- const void** address) {
- // After all, we are using a locally mapped version of the exe, so the
- // action is the same as for a target function.
- return ResolveTarget(interceptor_module, interceptor_name,
- const_cast<void**>(address));
-}
-
-// In this case all the work is done from the parent, so resolve is
-// just a simple GetProcAddress.
-NTSTATUS ServiceResolverThunk::ResolveTarget(const void* module,
- const char* function_name,
- void** address) {
- DCHECK(address);
- if (NULL == module)
- return STATUS_UNSUCCESSFUL;
-
- base::win::PEImage module_image(module);
- *address = module_image.GetProcAddress(function_name);
-
- if (NULL == *address) {
- NOTREACHED();
- return STATUS_UNSUCCESSFUL;
- }
-
- return STATUS_SUCCESS;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/service_resolver.h b/sandbox/win/src/service_resolver.h
deleted file mode 100644
index 3eb9e08..0000000
--- a/sandbox/win/src/service_resolver.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SERVICE_RESOLVER_H__
-#define SANDBOX_SRC_SERVICE_RESOLVER_H__
-
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/resolver.h"
-
-namespace sandbox {
-
-// This is the concrete resolver used to perform service-call type functions
-// inside ntdll.dll.
-class ServiceResolverThunk : public ResolverThunk {
- public:
- // The service resolver needs a child process to write to.
- ServiceResolverThunk(HANDLE process, bool relaxed)
- : process_(process), ntdll_base_(NULL), win2k_(false),
- relaxed_(relaxed), relative_jump_(0) {}
- virtual ~ServiceResolverThunk() {}
-
- // Implementation of Resolver::Setup.
- virtual NTSTATUS Setup(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes,
- size_t* storage_used);
-
- // Implementation of Resolver::ResolveInterceptor.
- virtual NTSTATUS ResolveInterceptor(const void* module,
- const char* function_name,
- const void** address);
-
- // Implementation of Resolver::ResolveTarget.
- virtual NTSTATUS ResolveTarget(const void* module,
- const char* function_name,
- void** address);
-
- // Implementation of Resolver::GetThunkSize.
- virtual size_t GetThunkSize() const;
-
- protected:
- // The unit test will use this member to allow local patch on a buffer.
- HMODULE ntdll_base_;
-
- // Handle of the child process.
- HANDLE process_;
-
- protected:
- // Keeps track of a Windows 2000 resolver.
- bool win2k_;
-
- private:
- // Returns true if the code pointer by target_ corresponds to the expected
- // type of function. Saves that code on the first part of the thunk pointed
- // by local_thunk (should be directly accessible from the parent).
- virtual bool IsFunctionAService(void* local_thunk) const;
-
- // Performs the actual patch of target_.
- // local_thunk must be already fully initialized, and the first part must
- // contain the original code. The real type of this buffer is ServiceFullThunk
- // (yes, private). remote_thunk (real type ServiceFullThunk), must be
- // allocated on the child, and will contain the thunk data, after this call.
- // Returns the apropriate status code.
- virtual NTSTATUS PerformPatch(void* local_thunk, void* remote_thunk);
-
- // Provides basically the same functionality as IsFunctionAService but it
- // continues even if it does not recognize the function code. remote_thunk
- // is the address of our memory on the child.
- bool SaveOriginalFunction(void* local_thunk, void* remote_thunk);
-
- // true if we are allowed to patch already-patched functions.
- bool relaxed_;
- ULONG relative_jump_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceResolverThunk);
-};
-
-// This is the concrete resolver used to perform service-call type functions
-// inside ntdll.dll on WOW64 (32 bit ntdll on 64 bit Vista).
-class Wow64ResolverThunk : public ServiceResolverThunk {
- public:
- // The service resolver needs a child process to write to.
- Wow64ResolverThunk(HANDLE process, bool relaxed)
- : ServiceResolverThunk(process, relaxed) {}
- virtual ~Wow64ResolverThunk() {}
-
- private:
- virtual bool IsFunctionAService(void* local_thunk) const;
-
- DISALLOW_COPY_AND_ASSIGN(Wow64ResolverThunk);
-};
-
-// This is the concrete resolver used to perform service-call type functions
-// inside ntdll.dll on WOW64 for Windows 8.
-class Wow64W8ResolverThunk : public ServiceResolverThunk {
- public:
- // The service resolver needs a child process to write to.
- Wow64W8ResolverThunk(HANDLE process, bool relaxed)
- : ServiceResolverThunk(process, relaxed) {}
- virtual ~Wow64W8ResolverThunk() {}
-
- private:
- virtual bool IsFunctionAService(void* local_thunk) const;
-
- DISALLOW_COPY_AND_ASSIGN(Wow64W8ResolverThunk);
-};
-
-// This is the concrete resolver used to perform service-call type functions
-// inside ntdll.dll on Windows 2000 and XP pre SP2.
-class Win2kResolverThunk : public ServiceResolverThunk {
- public:
- // The service resolver needs a child process to write to.
- Win2kResolverThunk(HANDLE process, bool relaxed)
- : ServiceResolverThunk(process, relaxed) {
- win2k_ = true;
- }
- virtual ~Win2kResolverThunk() {}
-
- private:
- virtual bool IsFunctionAService(void* local_thunk) const;
-
- DISALLOW_COPY_AND_ASSIGN(Win2kResolverThunk);
-};
-
-// This is the concrete resolver used to perform service-call type functions
-// inside ntdll.dll on Windows 8.
-class Win8ResolverThunk : public ServiceResolverThunk {
- public:
- // The service resolver needs a child process to write to.
- Win8ResolverThunk(HANDLE process, bool relaxed)
- : ServiceResolverThunk(process, relaxed) {}
- virtual ~Win8ResolverThunk() {}
-
- private:
- virtual bool IsFunctionAService(void* local_thunk) const;
-
- DISALLOW_COPY_AND_ASSIGN(Win8ResolverThunk);
-};
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_SERVICE_RESOLVER_H__
diff --git a/sandbox/win/src/service_resolver_32.cc b/sandbox/win/src/service_resolver_32.cc
deleted file mode 100644
index d4d2048..0000000
--- a/sandbox/win/src/service_resolver_32.cc
+++ /dev/null
@@ -1,424 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/service_resolver.h"
-
-#include "base/memory/scoped_ptr.h"
-#include "sandbox/win/src/sandbox_utils.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace {
-#pragma pack(push, 1)
-
-const BYTE kMovEax = 0xB8;
-const BYTE kMovEdx = 0xBA;
-const USHORT kMovEdxEsp = 0xD48B;
-const USHORT kCallPtrEdx = 0x12FF;
-const USHORT kCallEdx = 0xD2FF;
-const BYTE kCallEip = 0xE8;
-const BYTE kRet = 0xC2;
-const BYTE kRet2 = 0xC3;
-const BYTE kNop = 0x90;
-const USHORT kJmpEdx = 0xE2FF;
-const USHORT kXorEcx = 0xC933;
-const ULONG kLeaEdx = 0x0424548D;
-const ULONG kCallFs1 = 0xC015FF64;
-const USHORT kCallFs2 = 0;
-const BYTE kCallFs3 = 0;
-const BYTE kAddEsp1 = 0x83;
-const USHORT kAddEsp2 = 0x4C4;
-const BYTE kJmp32 = 0xE9;
-const USHORT kSysenter = 0x340F;
-
-const int kMaxService = 1000;
-
-// Service code for 32 bit systems.
-// NOTE: on win2003 "call dword ptr [edx]" is "call edx".
-struct ServiceEntry {
- // This struct contains roughly the following code:
- // 00 mov eax,25h
- // 05 mov edx,offset SharedUserData!SystemCallStub (7ffe0300)
- // 0a call dword ptr [edx]
- // 0c ret 2Ch
- // 0f nop
- BYTE mov_eax; // = B8
- ULONG service_id;
- BYTE mov_edx; // = BA
- ULONG stub;
- USHORT call_ptr_edx; // = FF 12
- BYTE ret; // = C2
- USHORT num_params;
- BYTE nop;
-};
-
-// Service code for 32 bit Windows 8.
-struct ServiceEntryW8 {
- // This struct contains the following code:
- // 00 b825000000 mov eax,25h
- // 05 e803000000 call eip+3
- // 0a c22c00 ret 2Ch
- // 0d 8bd4 mov edx,esp
- // 0f 0f34 sysenter
- // 11 c3 ret
- // 12 8bff mov edi,edi
- BYTE mov_eax; // = B8
- ULONG service_id;
- BYTE call_eip; // = E8
- ULONG call_offset;
- BYTE ret_p; // = C2
- USHORT num_params;
- USHORT mov_edx_esp; // = BD D4
- USHORT sysenter; // = 0F 34
- BYTE ret; // = C3
- USHORT nop;
-};
-
-// Service code for a 32 bit process running on a 64 bit os.
-struct Wow64Entry {
- // This struct may contain one of two versions of code:
- // 1. For XP, Vista and 2K3:
- // 00 b825000000 mov eax, 25h
- // 05 33c9 xor ecx, ecx
- // 07 8d542404 lea edx, [esp + 4]
- // 0b 64ff15c0000000 call dword ptr fs:[0C0h]
- // 12 c22c00 ret 2Ch
- //
- // 2. For Windows 7:
- // 00 b825000000 mov eax, 25h
- // 05 33c9 xor ecx, ecx
- // 07 8d542404 lea edx, [esp + 4]
- // 0b 64ff15c0000000 call dword ptr fs:[0C0h]
- // 12 83c404 add esp, 4
- // 15 c22c00 ret 2Ch
- //
- // So we base the structure on the bigger one:
- BYTE mov_eax; // = B8
- ULONG service_id;
- USHORT xor_ecx; // = 33 C9
- ULONG lea_edx; // = 8D 54 24 04
- ULONG call_fs1; // = 64 FF 15 C0
- USHORT call_fs2; // = 00 00
- BYTE call_fs3; // = 00
- BYTE add_esp1; // = 83 or ret
- USHORT add_esp2; // = C4 04 or num_params
- BYTE ret; // = C2
- USHORT num_params;
-};
-
-// Service code for a 32 bit process running on 64 bit Windows 8.
-struct Wow64EntryW8 {
- // 00 b825000000 mov eax, 25h
- // 05 64ff15c0000000 call dword ptr fs:[0C0h]
- // 0b c22c00 ret 2Ch
- // 0f 90 nop
- BYTE mov_eax; // = B8
- ULONG service_id;
- ULONG call_fs1; // = 64 FF 15 C0
- USHORT call_fs2; // = 00 00
- BYTE call_fs3; // = 00
- BYTE ret; // = C2
- USHORT num_params;
- BYTE nop;
-};
-
-// Make sure that relaxed patching works as expected.
-const size_t kMinServiceSize = offsetof(ServiceEntry, ret);
-COMPILE_ASSERT(sizeof(ServiceEntryW8) >= kMinServiceSize, wrong_service_len);
-COMPILE_ASSERT(sizeof(Wow64Entry) >= kMinServiceSize, wrong_service_len);
-COMPILE_ASSERT(sizeof(Wow64EntryW8) >= kMinServiceSize, wrong_service_len);
-
-struct ServiceFullThunk {
- union {
- ServiceEntry original;
- ServiceEntryW8 original_w8;
- Wow64Entry wow_64;
- Wow64EntryW8 wow_64_w8;
- };
- int internal_thunk; // Dummy member to the beginning of the internal thunk.
-};
-
-#pragma pack(pop)
-
-}; // namespace
-
-namespace sandbox {
-
-NTSTATUS ServiceResolverThunk::Setup(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes,
- size_t* storage_used) {
- NTSTATUS ret = Init(target_module, interceptor_module, target_name,
- interceptor_name, interceptor_entry_point,
- thunk_storage, storage_bytes);
- if (!NT_SUCCESS(ret))
- return ret;
-
- relative_jump_ = 0;
- size_t thunk_bytes = GetThunkSize();
- scoped_array<char> thunk_buffer(new char[thunk_bytes]);
- ServiceFullThunk* thunk = reinterpret_cast<ServiceFullThunk*>(
- thunk_buffer.get());
-
- if (!IsFunctionAService(&thunk->original) &&
- (!relaxed_ || !SaveOriginalFunction(&thunk->original, thunk_storage)))
- return STATUS_UNSUCCESSFUL;
-
- ret = PerformPatch(thunk, thunk_storage);
-
- if (NULL != storage_used)
- *storage_used = thunk_bytes;
-
- return ret;
-}
-
-size_t ServiceResolverThunk::GetThunkSize() const {
- return offsetof(ServiceFullThunk, internal_thunk) + GetInternalThunkSize();
-}
-
-bool ServiceResolverThunk::IsFunctionAService(void* local_thunk) const {
- ServiceEntry function_code;
- SIZE_T read;
- if (!::ReadProcessMemory(process_, target_, &function_code,
- sizeof(function_code), &read))
- return false;
-
- if (sizeof(function_code) != read)
- return false;
-
- if (kMovEax != function_code.mov_eax ||
- kMovEdx != function_code.mov_edx ||
- (kCallPtrEdx != function_code.call_ptr_edx &&
- kCallEdx != function_code.call_ptr_edx) ||
- kRet != function_code.ret)
- return false;
-
- // Find the system call pointer if we don't already have it.
- if (kCallEdx != function_code.call_ptr_edx) {
- DWORD ki_system_call;
- if (!::ReadProcessMemory(process_,
- bit_cast<const void*>(function_code.stub),
- &ki_system_call, sizeof(ki_system_call), &read))
- return false;
-
- if (sizeof(ki_system_call) != read)
- return false;
-
- HMODULE module_1, module_2;
- // last check, call_stub should point to a KiXXSystemCall function on ntdll
- if (!GetModuleHandleHelper(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
- GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- bit_cast<const wchar_t*>(ki_system_call),
- &module_1))
- return false;
-
- if (NULL != ntdll_base_) {
- // This path is only taken when running the unit tests. We want to be
- // able to patch a buffer in memory, so target_ is not inside ntdll.
- module_2 = ntdll_base_;
- } else {
- if (!GetModuleHandleHelper(
- GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
- GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
- reinterpret_cast<const wchar_t*>(target_),
- &module_2)) {
- return false;
- }
- }
-
- if (module_1 != module_2)
- return false;
- }
-
- // Save the verified code
- memcpy(local_thunk, &function_code, sizeof(function_code));
-
- return true;
-}
-
-NTSTATUS ServiceResolverThunk::PerformPatch(void* local_thunk,
- void* remote_thunk) {
- ServiceEntry intercepted_code;
- size_t bytes_to_write = sizeof(intercepted_code);
- ServiceFullThunk *full_local_thunk = reinterpret_cast<ServiceFullThunk*>(
- local_thunk);
- ServiceFullThunk *full_remote_thunk = reinterpret_cast<ServiceFullThunk*>(
- remote_thunk);
-
- // patch the original code
- memcpy(&intercepted_code, &full_local_thunk->original,
- sizeof(intercepted_code));
- intercepted_code.mov_eax = kMovEax;
- intercepted_code.service_id = full_local_thunk->original.service_id;
- intercepted_code.mov_edx = kMovEdx;
- intercepted_code.stub = bit_cast<ULONG>(&full_remote_thunk->internal_thunk);
- intercepted_code.call_ptr_edx = kJmpEdx;
- bytes_to_write = kMinServiceSize;
-
- if (relative_jump_) {
- intercepted_code.mov_eax = kJmp32;
- intercepted_code.service_id = relative_jump_;
- bytes_to_write = offsetof(ServiceEntry, mov_edx);
- }
-
- // setup the thunk
- SetInternalThunk(&full_local_thunk->internal_thunk, GetInternalThunkSize(),
- remote_thunk, interceptor_);
-
- size_t thunk_size = GetThunkSize();
-
- // copy the local thunk buffer to the child
- SIZE_T written;
- if (!::WriteProcessMemory(process_, remote_thunk, local_thunk,
- thunk_size, &written))
- return STATUS_UNSUCCESSFUL;
-
- if (thunk_size != written)
- return STATUS_UNSUCCESSFUL;
-
- // and now change the function to intercept, on the child
- if (NULL != ntdll_base_) {
- // running a unit test
- if (!::WriteProcessMemory(process_, target_, &intercepted_code,
- bytes_to_write, &written))
- return STATUS_UNSUCCESSFUL;
- } else {
- if (!WriteProtectedChildMemory(process_, target_, &intercepted_code,
- bytes_to_write))
- return STATUS_UNSUCCESSFUL;
- }
-
- return STATUS_SUCCESS;
-}
-
-bool ServiceResolverThunk::SaveOriginalFunction(void* local_thunk,
- void* remote_thunk) {
- ServiceEntry function_code;
- SIZE_T read;
- if (!::ReadProcessMemory(process_, target_, &function_code,
- sizeof(function_code), &read))
- return false;
-
- if (sizeof(function_code) != read)
- return false;
-
- if (kJmp32 == function_code.mov_eax) {
- // Plain old entry point patch. The relative jump address follows it.
- ULONG relative = function_code.service_id;
-
- // First, fix our copy of their patch.
- relative += bit_cast<ULONG>(target_) - bit_cast<ULONG>(remote_thunk);
-
- function_code.service_id = relative;
-
- // And now, remember how to re-patch it.
- ServiceFullThunk *full_thunk =
- reinterpret_cast<ServiceFullThunk*>(remote_thunk);
-
- const ULONG kJmp32Size = 5;
-
- relative_jump_ = bit_cast<ULONG>(&full_thunk->internal_thunk) -
- bit_cast<ULONG>(target_) - kJmp32Size;
- }
-
- // Save the verified code
- memcpy(local_thunk, &function_code, sizeof(function_code));
-
- return true;
-}
-
-bool Wow64ResolverThunk::IsFunctionAService(void* local_thunk) const {
- Wow64Entry function_code;
- SIZE_T read;
- if (!::ReadProcessMemory(process_, target_, &function_code,
- sizeof(function_code), &read))
- return false;
-
- if (sizeof(function_code) != read)
- return false;
-
- if (kMovEax != function_code.mov_eax || kXorEcx != function_code.xor_ecx ||
- kLeaEdx != function_code.lea_edx || kCallFs1 != function_code.call_fs1 ||
- kCallFs2 != function_code.call_fs2 || kCallFs3 != function_code.call_fs3)
- return false;
-
- if ((kAddEsp1 == function_code.add_esp1 &&
- kAddEsp2 == function_code.add_esp2 &&
- kRet == function_code.ret) || kRet == function_code.add_esp1) {
- // Save the verified code
- memcpy(local_thunk, &function_code, sizeof(function_code));
- return true;
- }
-
- return false;
-}
-
-bool Wow64W8ResolverThunk::IsFunctionAService(void* local_thunk) const {
- Wow64EntryW8 function_code;
- SIZE_T read;
- if (!::ReadProcessMemory(process_, target_, &function_code,
- sizeof(function_code), &read))
- return false;
-
- if (sizeof(function_code) != read)
- return false;
-
- if (kMovEax != function_code.mov_eax || kCallFs1 != function_code.call_fs1 ||
- kCallFs2 != function_code.call_fs2 ||
- kCallFs3 != function_code.call_fs3 || kRet != function_code.ret) {
- return false;
- }
-
- // Save the verified code
- memcpy(local_thunk, &function_code, sizeof(function_code));
- return true;
-}
-
-bool Win2kResolverThunk::IsFunctionAService(void* local_thunk) const {
- ServiceEntry function_code;
- SIZE_T read;
- if (!::ReadProcessMemory(process_, target_, &function_code,
- sizeof(function_code), &read))
- return false;
-
- if (sizeof(function_code) != read)
- return false;
-
- if (kMovEax != function_code.mov_eax ||
- function_code.service_id > kMaxService)
- return false;
-
- // Save the verified code
- memcpy(local_thunk, &function_code, sizeof(function_code));
-
- return true;
-}
-
-bool Win8ResolverThunk::IsFunctionAService(void* local_thunk) const {
- ServiceEntryW8 function_code;
- SIZE_T read;
- if (!::ReadProcessMemory(process_, target_, &function_code,
- sizeof(function_code), &read))
- return false;
-
- if (sizeof(function_code) != read)
- return false;
-
- if (kMovEax != function_code.mov_eax || kCallEip != function_code.call_eip ||
- function_code.call_offset != 3 || kRet != function_code.ret_p ||
- kMovEdxEsp != function_code.mov_edx_esp ||
- kSysenter != function_code.sysenter || kRet2 != function_code.ret) {
- return false;
- }
-
- // Save the verified code
- memcpy(local_thunk, &function_code, sizeof(function_code));
-
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/service_resolver_64.cc b/sandbox/win/src/service_resolver_64.cc
deleted file mode 100644
index b69d4d8..0000000
--- a/sandbox/win/src/service_resolver_64.cc
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/service_resolver.h"
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace {
-#pragma pack(push, 1)
-
-const ULONG kMmovR10EcxMovEax = 0xB8D18B4C;
-const USHORT kSyscall = 0x050F;
-const BYTE kRetNp = 0xC3;
-const ULONG64 kMov1 = 0x54894808244C8948;
-const ULONG64 kMov2 = 0x4C182444894C1024;
-const ULONG kMov3 = 0x20244C89;
-
-// Service code for 64 bit systems.
-struct ServiceEntry {
- // This struct contains roughly the following code:
- // 00 mov r10,rcx
- // 03 mov eax,52h
- // 08 syscall
- // 0a ret
- // 0b xchg ax,ax
- // 0e xchg ax,ax
-
- ULONG mov_r10_rcx_mov_eax; // = 4C 8B D1 B8
- ULONG service_id;
- USHORT syscall; // = 0F 05
- BYTE ret; // = C3
- BYTE pad; // = 66
- USHORT xchg_ax_ax1; // = 66 90
- USHORT xchg_ax_ax2; // = 66 90
-};
-
-// Service code for 64 bit Windows 8.
-struct ServiceEntryW8 {
- // This struct contains the following code:
- // 00 48894c2408 mov [rsp+8], rcx
- // 05 4889542410 mov [rsp+10], rdx
- // 0a 4c89442418 mov [rsp+18], r8
- // 0f 4c894c2420 mov [rsp+20], r9
- // 14 4c8bd1 mov r10,rcx
- // 17 b825000000 mov eax,25h
- // 1c 0f05 syscall
- // 1e c3 ret
- // 1f 90 nop
-
- ULONG64 mov_1; // = 48 89 4C 24 08 48 89 54
- ULONG64 mov_2; // = 24 10 4C 89 44 24 18 4C
- ULONG mov_3; // = 89 4C 24 20
- ULONG mov_r10_rcx_mov_eax; // = 4C 8B D1 B8
- ULONG service_id;
- USHORT syscall; // = 0F 05
- BYTE ret; // = C2
- BYTE nop; // = 90
-};
-
-// We don't have an internal thunk for x64.
-struct ServiceFullThunk {
- union {
- ServiceEntry original;
- ServiceEntryW8 original_w8;
- };
-};
-
-#pragma pack(pop)
-
-bool IsService(const void* source) {
- const ServiceEntry* service =
- reinterpret_cast<const ServiceEntry*>(source);
-
- return (kMmovR10EcxMovEax == service->mov_r10_rcx_mov_eax &&
- kSyscall == service->syscall && kRetNp == service->ret);
-}
-
-}; // namespace
-
-namespace sandbox {
-
-NTSTATUS ServiceResolverThunk::Setup(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes,
- size_t* storage_used) {
- NTSTATUS ret = Init(target_module, interceptor_module, target_name,
- interceptor_name, interceptor_entry_point,
- thunk_storage, storage_bytes);
- if (!NT_SUCCESS(ret))
- return ret;
-
- size_t thunk_bytes = GetThunkSize();
- scoped_array<char> thunk_buffer(new char[thunk_bytes]);
- ServiceFullThunk* thunk = reinterpret_cast<ServiceFullThunk*>(
- thunk_buffer.get());
-
- if (!IsFunctionAService(&thunk->original))
- return STATUS_UNSUCCESSFUL;
-
- ret = PerformPatch(thunk, thunk_storage);
-
- if (NULL != storage_used)
- *storage_used = thunk_bytes;
-
- return ret;
-}
-
-size_t ServiceResolverThunk::GetThunkSize() const {
- return sizeof(ServiceFullThunk);
-}
-
-bool ServiceResolverThunk::IsFunctionAService(void* local_thunk) const {
- ServiceFullThunk function_code;
- SIZE_T read;
- if (!::ReadProcessMemory(process_, target_, &function_code,
- sizeof(function_code), &read))
- return false;
-
- if (sizeof(function_code) != read)
- return false;
-
- if (!IsService(&function_code)) {
- // See if it's the Win8 signature.
- ServiceEntryW8* w8_service = &function_code.original_w8;
- if (!IsService(&w8_service->mov_r10_rcx_mov_eax) ||
- w8_service->mov_1 != kMov1 || w8_service->mov_1 != kMov1 ||
- w8_service->mov_1 != kMov1) {
- return false;
- }
- }
-
- // Save the verified code.
- memcpy(local_thunk, &function_code, sizeof(function_code));
-
- return true;
-}
-
-NTSTATUS ServiceResolverThunk::PerformPatch(void* local_thunk,
- void* remote_thunk) {
- ServiceFullThunk* full_local_thunk = reinterpret_cast<ServiceFullThunk*>(
- local_thunk);
- ServiceFullThunk* full_remote_thunk = reinterpret_cast<ServiceFullThunk*>(
- remote_thunk);
-
- // Patch the original code.
- ServiceEntry local_service;
- DCHECK_GE(GetInternalThunkSize(), sizeof(local_service));
- if (!SetInternalThunk(&local_service, sizeof(local_service), NULL,
- interceptor_))
- return STATUS_UNSUCCESSFUL;
-
- // Copy the local thunk buffer to the child.
- SIZE_T actual;
- if (!::WriteProcessMemory(process_, remote_thunk, local_thunk,
- sizeof(ServiceFullThunk), &actual))
- return STATUS_UNSUCCESSFUL;
-
- if (sizeof(ServiceFullThunk) != actual)
- return STATUS_UNSUCCESSFUL;
-
- // And now change the function to intercept, on the child.
- if (NULL != ntdll_base_) {
- // Running a unit test.
- if (!::WriteProcessMemory(process_, target_, &local_service,
- sizeof(local_service), &actual))
- return STATUS_UNSUCCESSFUL;
- } else {
- if (!WriteProtectedChildMemory(process_, target_, &local_service,
- sizeof(local_service)))
- return STATUS_UNSUCCESSFUL;
- }
-
- return STATUS_SUCCESS;
-}
-
-bool Wow64ResolverThunk::IsFunctionAService(void* local_thunk) const {
- NOTREACHED();
- return false;
-}
-
-bool Win2kResolverThunk::IsFunctionAService(void* local_thunk) const {
- NOTREACHED();
- return false;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/service_resolver_unittest.cc b/sandbox/win/src/service_resolver_unittest.cc
deleted file mode 100644
index 8c44202..0000000
--- a/sandbox/win/src/service_resolver_unittest.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains unit tests for ServiceResolverThunk.
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/win/windows_version.h"
-#include "sandbox/win/src/resolver.h"
-#include "sandbox/win/src/sandbox_utils.h"
-#include "sandbox/win/src/service_resolver.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-// This is the concrete resolver used to perform service-call type functions
-// inside ntdll.dll.
-template<typename T>
-class ResolverThunkTest : public T {
- public:
- // The service resolver needs a child process to write to.
- explicit ResolverThunkTest(bool relaxed)
- : T(::GetCurrentProcess(), relaxed) {}
-
- // Sets the interception target to the desired address.
- void set_target(void* target) {
- fake_target_ = target;
- }
-
- protected:
- // Overrides Resolver::Init
- virtual NTSTATUS Init(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes) {
- NTSTATUS ret = STATUS_SUCCESS;
- ret = ResolverThunk::Init(target_module, interceptor_module, target_name,
- interceptor_name, interceptor_entry_point,
- thunk_storage, storage_bytes);
- EXPECT_EQ(STATUS_SUCCESS, ret);
-
- target_ = fake_target_;
- ntdll_base_ = ::GetModuleHandle(L"ntdll.dll");
- return ret;
- };
-
- private:
- // Holds the address of the fake target.
- void* fake_target_;
-
- DISALLOW_COPY_AND_ASSIGN(ResolverThunkTest);
-};
-
-typedef ResolverThunkTest<sandbox::ServiceResolverThunk> WinXpResolverTest;
-
-#if !defined(_WIN64)
-typedef ResolverThunkTest<sandbox::Win2kResolverThunk> Win2kResolverTest;
-typedef ResolverThunkTest<sandbox::Win8ResolverThunk> Win8ResolverTest;
-typedef ResolverThunkTest<sandbox::Wow64ResolverThunk> Wow64ResolverTest;
-typedef ResolverThunkTest<sandbox::Wow64W8ResolverThunk> Wow64W8ResolverTest;
-#endif
-
-const BYTE kJump32 = 0xE9;
-
-void CheckJump(void* source, void* target) {
-#pragma pack(push)
-#pragma pack(1)
- struct Code {
- BYTE jump;
- ULONG delta;
- };
-#pragma pack(pop)
-
-#if defined(_WIN64)
- FAIL() << "Running 32-bit codepath";
-#else
- Code* patched = reinterpret_cast<Code*>(source);
- EXPECT_EQ(kJump32, patched->jump);
-
- ULONG source_addr = bit_cast<ULONG>(source);
- ULONG target_addr = bit_cast<ULONG>(target);
- EXPECT_EQ(target_addr + 19 - source_addr, patched->delta);
-#endif
-}
-
-NTSTATUS PatchNtdllWithResolver(const char* function, bool relaxed,
- sandbox::ServiceResolverThunk* resolver) {
- HMODULE ntdll_base = ::GetModuleHandle(L"ntdll.dll");
- EXPECT_TRUE(NULL != ntdll_base);
-
- void* target = ::GetProcAddress(ntdll_base, function);
- EXPECT_TRUE(NULL != target);
- if (NULL == target)
- return STATUS_UNSUCCESSFUL;
-
- BYTE service[50];
- memcpy(service, target, sizeof(service));
-
- static_cast<WinXpResolverTest*>(resolver)->set_target(service);
-
- // Any pointer will do as an interception_entry_point
- void* function_entry = resolver;
- size_t thunk_size = resolver->GetThunkSize();
- scoped_array<char> thunk(new char[thunk_size]);
- size_t used;
-
- NTSTATUS ret = resolver->Setup(ntdll_base, NULL, function, NULL,
- function_entry, thunk.get(), thunk_size,
- &used);
- if (NT_SUCCESS(ret)) {
- EXPECT_EQ(thunk_size, used);
- EXPECT_NE(0, memcmp(service, target, sizeof(service)));
- EXPECT_NE(kJump32, service[0]);
-
- if (relaxed) {
- // It's already patched, let's patch again, and simulate a direct patch.
- service[0] = kJump32;
- ret = resolver->Setup(ntdll_base, NULL, function, NULL, function_entry,
- thunk.get(), thunk_size, &used);
- CheckJump(service, thunk.get());
- }
- }
-
- return ret;
-}
-
-sandbox::ServiceResolverThunk* GetTestResolver(bool relaxed) {
-#if defined(_WIN64)
- return new WinXpResolverTest(relaxed);
-#else
- base::win::OSInfo* os_info = base::win::OSInfo::GetInstance();
- if (os_info->wow64_status() == base::win::OSInfo::WOW64_ENABLED) {
- if (os_info->version() >= base::win::VERSION_WIN8)
- return new Wow64W8ResolverTest(relaxed);
- return new Wow64ResolverTest(relaxed);
- }
-
- if (!sandbox::IsXPSP2OrLater())
- return new Win2kResolverTest(relaxed);
-
- if (os_info->version() >= base::win::VERSION_WIN8)
- return new Win8ResolverTest(relaxed);
-
- return new WinXpResolverTest(relaxed);
-#endif
-}
-
-NTSTATUS PatchNtdll(const char* function, bool relaxed) {
- sandbox::ServiceResolverThunk* resolver = GetTestResolver(relaxed);
-
- NTSTATUS ret = PatchNtdllWithResolver(function, relaxed, resolver);
- delete resolver;
- return ret;
-}
-
-TEST(ServiceResolverTest, PatchesServices) {
- NTSTATUS ret = PatchNtdll("NtClose", false);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtClose, last error: " << ::GetLastError();
-
- ret = PatchNtdll("NtCreateFile", false);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtCreateFile, last error: " <<
- ::GetLastError();
-
- ret = PatchNtdll("NtCreateMutant", false);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtCreateMutant, last error: " <<
- ::GetLastError();
-
- ret = PatchNtdll("NtMapViewOfSection", false);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtMapViewOfSection, last error: " <<
- ::GetLastError();
-}
-
-TEST(ServiceResolverTest, FailsIfNotService) {
-#if !defined(_WIN64)
- EXPECT_NE(STATUS_SUCCESS, PatchNtdll("RtlUlongByteSwap", false));
-#endif
-
- EXPECT_NE(STATUS_SUCCESS, PatchNtdll("LdrLoadDll", false));
-}
-
-TEST(ServiceResolverTest, PatchesPatchedServices) {
-// We don't support "relaxed mode" for Win64 apps.
-#if !defined(_WIN64)
- NTSTATUS ret = PatchNtdll("NtClose", true);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtClose, last error: " << ::GetLastError();
-
- ret = PatchNtdll("NtCreateFile", true);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtCreateFile, last error: " <<
- ::GetLastError();
-
- ret = PatchNtdll("NtCreateMutant", true);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtCreateMutant, last error: " <<
- ::GetLastError();
-
- ret = PatchNtdll("NtMapViewOfSection", true);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtMapViewOfSection, last error: " <<
- ::GetLastError();
-#endif
-}
-
-TEST(ServiceResolverTest, MultiplePatchedServices) {
-// We don't support "relaxed mode" for Win64 apps.
-#if !defined(_WIN64)
- sandbox::ServiceResolverThunk* resolver = GetTestResolver(true);
- NTSTATUS ret = PatchNtdllWithResolver("NtClose", true, resolver);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtClose, last error: " << ::GetLastError();
-
- ret = PatchNtdllWithResolver("NtCreateFile", true, resolver);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtCreateFile, last error: " <<
- ::GetLastError();
-
- ret = PatchNtdllWithResolver("NtCreateMutant", true, resolver);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtCreateMutant, last error: " <<
- ::GetLastError();
-
- ret = PatchNtdllWithResolver("NtMapViewOfSection", true, resolver);
- EXPECT_EQ(STATUS_SUCCESS, ret) << "NtMapViewOfSection, last error: " <<
- ::GetLastError();
- delete resolver;
-#endif
-}
-
-} // namespace
diff --git a/sandbox/win/src/shared_handles.cc b/sandbox/win/src/shared_handles.cc
deleted file mode 100644
index 423b67b..0000000
--- a/sandbox/win/src/shared_handles.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/shared_handles.h"
-
-namespace sandbox {
-
-// Note once again the the assumption here is that the shared memory is
-// initialized with zeros in the process that calls SetHandle and that
-// the process that calls GetHandle 'sees' this memory.
-
-SharedHandles::SharedHandles() {
- shared_.items = NULL;
- shared_.max_items = 0;
-}
-
-bool SharedHandles::Init(void* raw_mem, size_t size_bytes) {
- if (size_bytes < sizeof(shared_.items[0])) {
- // The shared memory is too small!
- return false;
- }
- shared_.items = static_cast<SharedItem*>(raw_mem);
- shared_.max_items = size_bytes / sizeof(shared_.items[0]);
- return true;
-}
-
-// Note that an empty slot is marked with a tag == 0 that is why is
-// not a valid imput tag
-bool SharedHandles::SetHandle(uint32 tag, HANDLE handle) {
- if (0 == tag) {
- // Invalid tag
- return false;
- }
- // Find empty slot and put the tag and the handle there
- SharedItem* empty_slot = FindByTag(0);
- if (NULL == empty_slot) {
- return false;
- }
- empty_slot->tag = tag;
- empty_slot->item = handle;
- return true;
-}
-
-bool SharedHandles::GetHandle(uint32 tag, HANDLE* handle) {
- if (0 == tag) {
- // Invalid tag
- return false;
- }
- SharedItem* found = FindByTag(tag);
- if (NULL == found) {
- return false;
- }
- *handle = found->item;
- return true;
-}
-
-SharedHandles::SharedItem* SharedHandles::FindByTag(uint32 tag) {
- for (size_t ix = 0; ix != shared_.max_items; ++ix) {
- if (tag == shared_.items[ix].tag) {
- return &shared_.items[ix];
- }
- }
- return NULL;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/shared_handles.h b/sandbox/win/src/shared_handles.h
deleted file mode 100644
index 2c76bfb..0000000
--- a/sandbox/win/src/shared_handles.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SHARED_HANDLES_H__
-#define SANDBOX_SRC_SHARED_HANDLES_H__
-
-#include "base/basictypes.h"
-
-#ifndef HANDLE
-// We can provide our own windows compatilble handle definition, but
-// in general we want to rely on the client of this api to include
-// the proper windows headers. Note that we don't want to bring the
-// whole <windows.h> into scope if we don't have to.
-typedef void* HANDLE;
-#endif
-
-namespace sandbox {
-
-// SharedHandles is a simple class to stash and find windows object handles
-// given a raw block of memory which is shared between two processes.
-// It addresses the need to communicate a handle value between two windows
-// processes given that they are already sharing some memory.
-//
-// This class is not exposed directly to users of the sanbox API, instead
-// we expose the wrapper methods TargetProcess::TransferHandle( ) and
-// TargetServices::GetTransferHandle()
-//
-// Use it for a small number of items, since internaly uses linear seach
-//
-// The use is very simple. Given a shared memory between proces A and B:
-// process A:
-// HANDLE handle = SomeFunction(..);
-// SharedHandles shared_handes;
-// shared_handles.Init(memory)
-// shared_handles.SetHandle(3, handle);
-//
-// process B:
-// SharedHandles shared_handes;
-// shared_handles.Init(memory)
-// HANDLE handle = shared_handles.GetHandle(3);
-//
-// Note that '3' in this example is a unique id, that must be agreed before
-// transfer
-//
-// Note2: While this class can be used in a single process, there are
-// better alternatives such as STL
-//
-// Note3: Under windows a kernel object handle in one process does not
-// make sense for another process unless there is a DuplicateHandle( )
-// call involved which this class DOES NOT do that for you.
-//
-// Note4: Under windows, shared memory when created is initialized to
-// zeros always. If you are not using shared memory it is your responsability
-// to zero it for the setter process and to copy it to the getter process.
-class SharedHandles {
- public:
- SharedHandles();
-
- // Initializes the shared memory for use.
- // Pass the shared memory base and size. It will internally compute
- // how many handles can it store. If initialization fails the return value
- // is false.
- bool Init(void* raw_mem, size_t size_bytes);
-
- // Sets a handle in the shared memory for transfer.
- // Parameters:
- // tag : an integer, different from zero that uniquely identfies the
- // handle to transfer.
- // handle: the handle value associated with 'tag' to tranfer
- // Returns false if there is not enough space in the shared memory for
- // this handle.
- bool SetHandle(uint32 tag, HANDLE handle);
-
- // Gets a handle previously stored by SetHandle.
- // Parameters:
- // tag: an integer different from zero that uniquely identfies the handle
- // to retrieve.
- // *handle: output handle value if the call was succesful.
- // If a handle with the provided tag is not found the return value is false.
- // If the tag is found the return value is true.
- bool GetHandle(uint32 tag, HANDLE* handle);
-
- private:
- // A single item is the tuple handle/tag
- struct SharedItem {
- uint32 tag;
- void* item;
- };
-
- // SharedMem is used to layout the memory as an array of SharedItems
- struct SharedMem {
- size_t max_items;
- SharedItem* items;
- };
-
- // Finds an Item tuple provided the handle tag.
- // Uses linear search because we expect the number of handles to be
- // small (say less than ~100).
- SharedItem* FindByTag(uint32 tag);
-
- SharedMem shared_;
- DISALLOW_COPY_AND_ASSIGN(SharedHandles);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_SHARED_HANDLES_H__
diff --git a/sandbox/win/src/sharedmem_ipc_client.cc b/sandbox/win/src/sharedmem_ipc_client.cc
deleted file mode 100644
index a9eb01f..0000000
--- a/sandbox/win/src/sharedmem_ipc_client.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string.h>
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/crosscall_params.h"
-#include "base/logging.h"
-
-namespace sandbox {
-
-// Get the base of the data buffer of the channel; this is where the input
-// parameters get serialized. Since they get serialized directly into the
-// channel we avoid one copy.
-void* SharedMemIPCClient::GetBuffer() {
- bool failure = false;
- size_t ix = LockFreeChannel(&failure);
- if (failure) {
- return NULL;
- }
- return reinterpret_cast<char*>(control_) +
- control_->channels[ix].channel_base;
-}
-
-// If we need to cancel an IPC before issuing DoCall
-// our client should call FreeBuffer with the same pointer
-// returned by GetBuffer.
-void SharedMemIPCClient::FreeBuffer(void* buffer) {
- size_t num = ChannelIndexFromBuffer(buffer);
- ChannelControl* channel = control_->channels;
- LONG result = ::InterlockedExchange(&channel[num].state, kFreeChannel);
- DCHECK(kFreeChannel != result);
- result;
-}
-
-// The constructor simply casts the shared memory to the internal
-// structures. This is a cheap step that is why this IPC object can
-// and should be constructed per call.
-SharedMemIPCClient::SharedMemIPCClient(void* shared_mem)
- : control_(reinterpret_cast<IPCControl*>(shared_mem)) {
- first_base_ = reinterpret_cast<char*>(shared_mem) +
- control_->channels[0].channel_base;
- // There must be at least one channel.
- DCHECK(0 != control_->channels_count);
-}
-
-// Do the IPC. At this point the channel should have already been
-// filled with the serialized input parameters.
-// We follow the pattern explained in the header file.
-ResultCode SharedMemIPCClient::DoCall(CrossCallParams* params,
- CrossCallReturn* answer) {
- if (!control_->server_alive)
- return SBOX_ERROR_CHANNEL_ERROR;
-
- size_t num = ChannelIndexFromBuffer(params->GetBuffer());
- ChannelControl* channel = control_->channels;
- // Note that the IPC tag goes outside the buffer as well inside
- // the buffer. This should enable the server to prioritize based on
- // IPC tags without having to de-serialize the entire message.
- channel[num].ipc_tag = params->GetTag();
-
- // Wait for the server to service this IPC call. After kIPCWaitTimeOut1
- // we check if the server_alive mutex was abandoned which will indicate
- // that the server has died.
-
- // While the atomic signaling and waiting is not a requirement, it
- // is nice because we save a trip to kernel.
- DWORD wait = ::SignalObjectAndWait(channel[num].ping_event,
- channel[num].pong_event,
- kIPCWaitTimeOut1, FALSE);
- if (WAIT_TIMEOUT == wait) {
- // The server is taking too long. Enter a loop were we check if the
- // server_alive mutex has been abandoned which would signal a server crash
- // or else we keep waiting for a response.
- while (true) {
- wait = ::WaitForSingleObject(control_->server_alive, 0);
- if (WAIT_TIMEOUT == wait) {
- // Server seems still alive. We already signaled so here we just wait.
- wait = ::WaitForSingleObject(channel[num].pong_event, kIPCWaitTimeOut1);
- if (WAIT_OBJECT_0 == wait) {
- // The server took a long time but responded.
- break;
- } else if (WAIT_TIMEOUT == wait) {
- continue;
- } else {
- return SBOX_ERROR_CHANNEL_ERROR;
- }
- } else {
- // The server has crashed and windows has signaled the mutex as
- // abandoned.
- ::InterlockedExchange(&channel[num].state, kAbandonnedChannel);
- control_->server_alive = 0;
- return SBOX_ERROR_CHANNEL_ERROR;
- }
- }
- } else if (WAIT_OBJECT_0 != wait) {
- // Probably the server crashed before the kIPCWaitTimeOut1 occurred.
- return SBOX_ERROR_CHANNEL_ERROR;
- }
-
- // The server has returned an answer, copy it and free the channel.
- memcpy(answer, params->GetCallReturn(), sizeof(CrossCallReturn));
-
- // Return the IPC state It can indicate that while the IPC has
- // completed some error in the Broker has caused to not return valid
- // results.
- return answer->call_outcome;
-}
-
-// Locking a channel is a simple as looping over all the channels
-// looking for one that is has state = kFreeChannel and atomically
-// swapping it to kBusyChannel.
-// If there is no free channel, then we must back off so some other
-// thread makes progress and frees a channel. To back off we sleep.
-size_t SharedMemIPCClient::LockFreeChannel(bool* severe_failure) {
- if (0 == control_->channels_count) {
- *severe_failure = true;
- return 0;
- }
- ChannelControl* channel = control_->channels;
- do {
- for (size_t ix = 0; ix != control_->channels_count; ++ix) {
- if (kFreeChannel == ::InterlockedCompareExchange(&channel[ix].state,
- kBusyChannel,
- kFreeChannel)) {
- *severe_failure = false;
- return ix;
- }
- }
- // We did not find any available channel, maybe the server is dead.
- DWORD wait = ::WaitForSingleObject(control_->server_alive,
- kIPCWaitTimeOut2);
- if (WAIT_TIMEOUT != wait) {
- // The server is dead and we outlive it enough to get in trouble.
- *severe_failure = true;
- return 0;
- }
- }
- while (true);
-}
-
-// Find out which channel we are from the pointer returned by GetBuffer.
-size_t SharedMemIPCClient::ChannelIndexFromBuffer(const void* buffer) {
- ptrdiff_t d = reinterpret_cast<const char*>(buffer) - first_base_;
- size_t num = d/kIPCChannelSize;
- DCHECK(num < control_->channels_count);
- return (num);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/sharedmem_ipc_client.h b/sandbox/win/src/sharedmem_ipc_client.h
deleted file mode 100644
index a0c5f2f..0000000
--- a/sandbox/win/src/sharedmem_ipc_client.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SHAREDMEM_IPC_CLIENT_H__
-#define SANDBOX_SRC_SHAREDMEM_IPC_CLIENT_H__
-
-#include "sandbox/win/src/crosscall_params.h"
-#include "sandbox/win/src/sandbox.h"
-
-// IPC transport implementation that uses shared memory.
-// This is the client side
-//
-// The shared memory is divided on blocks called channels, and potentially
-// it can perform as many concurrent IPC calls as channels. The IPC over
-// each channel is strictly synchronous for the client.
-//
-// Each channel as a channel control section associated with. Each control
-// section has two kernel events (known as ping and pong) and a integer
-// variable that maintains a state
-//
-// this is the state diagram of a channel:
-//
-// locked in service
-// kFreeChannel---------->BusyChannel-------------->kAckChannel
-// ^ |
-// |_________________________________________________|
-// answer ready
-//
-// The protocol is as follows:
-// 1) client finds a free channel: state = kFreeChannel
-// 2) does an atomic compare-and-swap, now state = BusyChannel
-// 3) client writes the data into the channel buffer
-// 4) client signals the ping event and waits (blocks) on the pong event
-// 5) eventually the server signals the pong event
-// 6) the client awakes and reads the answer from the same channel
-// 7) the client updates its InOut parameters with the new data from the
-// shared memory section.
-// 8) the client atomically sets the state = kFreeChannel
-//
-// In the shared memory the layout is as follows:
-//
-// [ channel count ]
-// [ channel control 0]
-// [ channel control 1]
-// [ channel control N]
-// [ channel buffer 0 ] 1024 bytes
-// [ channel buffer 1 ] 1024 bytes
-// [ channel buffer N ] 1024 bytes
-//
-// By default each channel buffer is 1024 bytes
-namespace sandbox {
-
-// the possible channel states as described above
-enum ChannelState {
- // channel is free
- kFreeChannel = 1,
- // IPC in progress client side
- kBusyChannel,
- // IPC in progress server side
- kAckChannel,
- // not used right now
- kReadyChannel,
- // IPC abandoned by client side
- kAbandonnedChannel
-};
-
-// The next two constants control the time outs for the IPC.
-const DWORD kIPCWaitTimeOut1 = 1000; // Milliseconds.
-const DWORD kIPCWaitTimeOut2 = 50; // Milliseconds.
-
-// the channel control structure
-struct ChannelControl {
- // points to be beginning of the channel buffer, where data goes
- size_t channel_base;
- // maintains the state from the ChannelState enumeration
- volatile LONG state;
- // the ping event is signaled by the client when the IPC data is ready on
- // the buffer
- HANDLE ping_event;
- // the client waits on the pong event for the IPC answer back
- HANDLE pong_event;
- // the IPC unique identifier
- uint32 ipc_tag;
-};
-
-struct IPCControl {
- // total number of channels available, some might be busy at a given time
- size_t channels_count;
- // handle to a shared mutex to detect when the server is dead
- HANDLE server_alive;
- // array of channel control structures
- ChannelControl channels[1];
-};
-
-// the actual shared memory IPC implementation class. This object is designed
-// to be lightweight so it can be constructed on-site (at the calling place)
-// wherever an IPC call is needed.
-class SharedMemIPCClient {
- public:
- // Creates the IPC client.
- // as parameter it takes the base address of the shared memory
- explicit SharedMemIPCClient(void* shared_mem);
-
- // locks a free channel and returns the channel buffer memory base. This call
- // blocks until there is a free channel
- void* GetBuffer();
-
- // releases the lock on the channel, for other to use. call this if you have
- // called GetBuffer and you want to abort but have not called yet DoCall()
- void FreeBuffer(void* buffer);
-
- // Performs the actual IPC call.
- // params: The blob of packed input parameters.
- // answer: upon IPC completion, it contains the server answer to the IPC.
- // If the return value is not SBOX_ERROR_CHANNEL_ERROR, the caller has to free
- // the channel.
- // returns ALL_OK if the IPC mechanism successfully delivered. You still need
- // to check on the answer structure to see the actual IPC result.
- ResultCode DoCall(CrossCallParams* params, CrossCallReturn* answer);
-
- private:
- // Returns the index of the first free channel. It sets 'severe_failure'
- // to true if there is an unrecoverable error that does not allow to
- // find a channel.
- size_t LockFreeChannel(bool* severe_failure);
- // Return the channel index given the address of the buffer.
- size_t ChannelIndexFromBuffer(const void* buffer);
- IPCControl* control_;
- // point to the first channel base
- char* first_base_;
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_SHAREDMEM_IPC_CLIENT_H__
diff --git a/sandbox/win/src/sharedmem_ipc_server.cc b/sandbox/win/src/sharedmem_ipc_server.cc
deleted file mode 100644
index e2a30c72..0000000
--- a/sandbox/win/src/sharedmem_ipc_server.cc
+++ /dev/null
@@ -1,410 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/callback.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "sandbox/win/src/sharedmem_ipc_server.h"
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/crosscall_params.h"
-#include "sandbox/win/src/crosscall_server.h"
-
-namespace sandbox {
-
-SharedMemIPCServer::SharedMemIPCServer(HANDLE target_process,
- DWORD target_process_id,
- HANDLE target_job,
- ThreadProvider* thread_provider,
- Dispatcher* dispatcher)
- : client_control_(NULL),
- thread_provider_(thread_provider),
- target_process_(target_process),
- target_process_id_(target_process_id),
- target_job_object_(target_job),
- call_dispatcher_(dispatcher) {
-}
-
-SharedMemIPCServer::~SharedMemIPCServer() {
- // Free the wait handles associated with the thread pool.
- if (!thread_provider_->UnRegisterWaits(this)) {
- // Better to leak than to crash.
- return;
- }
- // Free the IPC signal events.
- ServerContexts::iterator it;
- for (it = server_contexts_.begin(); it != server_contexts_.end(); ++it) {
- ServerControl* context = (*it);
- ::CloseHandle(context->ping_event);
- ::CloseHandle(context->pong_event);
- delete context;
- }
-}
-
-bool SharedMemIPCServer::Init(void* shared_mem, uint32 shared_size,
- uint32 channel_size) {
- // The shared memory needs to be at least as big as a channel.
- if (shared_size < channel_size) {
- return false;
- }
- // The channel size should be aligned.
- if (0 != (channel_size % 32)) {
- return false;
- }
-
- // Calculate how many channels we can fit in the shared memory.
- shared_size -= offsetof(IPCControl, channels);
- size_t channel_count = shared_size / (sizeof(ChannelControl) + channel_size);
-
- // If we cannot fit even one channel we bail out.
- if (0 == channel_count) {
- return false;
- }
- // Calculate the start of the first channel.
- size_t base_start = (sizeof(ChannelControl)* channel_count) +
- offsetof(IPCControl, channels);
-
- client_control_ = reinterpret_cast<IPCControl*>(shared_mem);
- client_control_->channels_count = 0;
-
- // This is the initialization that we do per-channel. Basically:
- // 1) make two events (ping & pong)
- // 2) create handles to the events for the client and the server.
- // 3) initialize the channel (client_context) with the state.
- // 4) initialize the server side of the channel (service_context).
- // 5) call the thread provider RegisterWait to register the ping events.
- for (size_t ix = 0; ix != channel_count; ++ix) {
- ChannelControl* client_context = &client_control_->channels[ix];
- ServerControl* service_context = new ServerControl;
- server_contexts_.push_back(service_context);
-
- if (!MakeEvents(&service_context->ping_event,
- &service_context->pong_event,
- &client_context->ping_event,
- &client_context->pong_event)) {
- return false;
- }
-
- client_context->channel_base = base_start;
- client_context->state = kFreeChannel;
-
- // Note that some of these values are available as members of this
- // object but we put them again into the service_context because we
- // will be called on a static method (ThreadPingEventReady)
- service_context->shared_base = reinterpret_cast<char*>(shared_mem);
- service_context->channel_size = channel_size;
- service_context->channel = client_context;
- service_context->channel_buffer = service_context->shared_base +
- client_context->channel_base;
- service_context->dispatcher = call_dispatcher_;
- service_context->target_info.process = target_process_;
- service_context->target_info.process_id = target_process_id_;
- service_context->target_info.job_object = target_job_object_;
- // Advance to the next channel.
- base_start += channel_size;
- // Register the ping event with the threadpool.
- thread_provider_->RegisterWait(this, service_context->ping_event,
- ThreadPingEventReady, service_context);
- }
-
- // We create a mutex that the server locks. If the server dies unexpectedly,
- // the thread that owns it will fail to release the lock and windows will
- // report to the target (when it tries to acquire it) that the wait was
- // abandoned. Note: We purposely leak the local handle because we want it to
- // be closed by Windows itself so it is properly marked as abandoned if the
- // server dies.
- if (!::DuplicateHandle(::GetCurrentProcess(),
- ::CreateMutexW(NULL, TRUE, NULL),
- target_process_, &client_control_->server_alive,
- SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, 0)) {
- return false;
- }
- // This last setting indicates to the client all is setup.
- client_control_->channels_count = channel_count;
- return true;
-}
-
-// Releases memory allocated for IPC arguments, if needed.
-void ReleaseArgs(const IPCParams* ipc_params, void* args[kMaxIpcParams]) {
- for (size_t i = 0; i < kMaxIpcParams; i++) {
- switch (ipc_params->args[i]) {
- case WCHAR_TYPE: {
- delete reinterpret_cast<std::wstring*>(args[i]);
- args[i] = NULL;
- break;
- }
- case INOUTPTR_TYPE: {
- delete reinterpret_cast<CountedBuffer*>(args[i]);
- args[i] = NULL;
- break;
- }
- default: break;
- }
- }
-}
-
-// Fills up the list of arguments (args and ipc_params) for an IPC call.
-bool GetArgs(CrossCallParamsEx* params, IPCParams* ipc_params,
- void* args[kMaxIpcParams]) {
- if (kMaxIpcParams < params->GetParamsCount())
- return false;
-
- for (uint32 i = 0; i < params->GetParamsCount(); i++) {
- uint32 size;
- ArgType type;
- args[i] = params->GetRawParameter(i, &size, &type);
- if (args[i]) {
- ipc_params->args[i] = type;
- switch (type) {
- case WCHAR_TYPE: {
- scoped_ptr<std::wstring> data(new std::wstring);
- if (!params->GetParameterStr(i, data.get())) {
- args[i] = 0;
- ReleaseArgs(ipc_params, args);
- return false;
- }
- args[i] = data.release();
- break;
- }
- case ULONG_TYPE: {
- uint32 data;
- if (!params->GetParameter32(i, &data)) {
- ReleaseArgs(ipc_params, args);
- return false;
- }
- IPCInt ipc_int(data);
- args[i] = ipc_int.AsVoidPtr();
- break;
- }
- case VOIDPTR_TYPE : {
- void* data;
- if (!params->GetParameterVoidPtr(i, &data)) {
- ReleaseArgs(ipc_params, args);
- return false;
- }
- args[i] = data;
- break;
- }
- case INOUTPTR_TYPE: {
- if (!args[i]) {
- ReleaseArgs(ipc_params, args);
- return false;
- }
- CountedBuffer* buffer = new CountedBuffer(args[i] , size);
- args[i] = buffer;
- break;
- }
- default: break;
- }
- }
- }
- return true;
-}
-
-bool SharedMemIPCServer::InvokeCallback(const ServerControl* service_context,
- void* ipc_buffer,
- CrossCallReturn* call_result) {
- // Set the default error code;
- SetCallError(SBOX_ERROR_INVALID_IPC, call_result);
- uint32 output_size = 0;
- // Parse, verify and copy the message. The handler operates on a copy
- // of the message so the client cannot play dirty tricks by changing the
- // data in the channel while the IPC is being processed.
- scoped_ptr<CrossCallParamsEx> params(
- CrossCallParamsEx::CreateFromBuffer(ipc_buffer,
- service_context->channel_size,
- &output_size));
- if (!params.get())
- return false;
-
- uint32 tag = params->GetTag();
- COMPILE_ASSERT(0 == INVALID_TYPE, Incorrect_type_enum);
- IPCParams ipc_params = {0};
- ipc_params.ipc_tag = tag;
-
- void* args[kMaxIpcParams];
- if (!GetArgs(params.get(), &ipc_params, args))
- return false;
-
- IPCInfo ipc_info = {0};
- ipc_info.ipc_tag = tag;
- ipc_info.client_info = &service_context->target_info;
- Dispatcher* dispatcher = service_context->dispatcher;
- DCHECK(dispatcher);
- bool error = true;
- Dispatcher* handler = NULL;
-
- Dispatcher::CallbackGeneric callback_generic;
- handler = dispatcher->OnMessageReady(&ipc_params, &callback_generic);
- if (handler) {
- switch (params->GetParamsCount()) {
- case 0: {
- // Ask the IPC dispatcher if she can service this IPC.
- Dispatcher::Callback0 callback =
- reinterpret_cast<Dispatcher::Callback0>(callback_generic);
- if (!(handler->*callback)(&ipc_info))
- break;
- error = false;
- break;
- }
- case 1: {
- Dispatcher::Callback1 callback =
- reinterpret_cast<Dispatcher::Callback1>(callback_generic);
- if (!(handler->*callback)(&ipc_info, args[0]))
- break;
- error = false;
- break;
- }
- case 2: {
- Dispatcher::Callback2 callback =
- reinterpret_cast<Dispatcher::Callback2>(callback_generic);
- if (!(handler->*callback)(&ipc_info, args[0], args[1]))
- break;
- error = false;
- break;
- }
- case 3: {
- Dispatcher::Callback3 callback =
- reinterpret_cast<Dispatcher::Callback3>(callback_generic);
- if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2]))
- break;
- error = false;
- break;
- }
- case 4: {
- Dispatcher::Callback4 callback =
- reinterpret_cast<Dispatcher::Callback4>(callback_generic);
- if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2],
- args[3]))
- break;
- error = false;
- break;
- }
- case 5: {
- Dispatcher::Callback5 callback =
- reinterpret_cast<Dispatcher::Callback5>(callback_generic);
- if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
- args[4]))
- break;
- error = false;
- break;
- }
- case 6: {
- Dispatcher::Callback6 callback =
- reinterpret_cast<Dispatcher::Callback6>(callback_generic);
- if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
- args[4], args[5]))
- break;
- error = false;
- break;
- }
- case 7: {
- Dispatcher::Callback7 callback =
- reinterpret_cast<Dispatcher::Callback7>(callback_generic);
- if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
- args[4], args[5], args[6]))
- break;
- error = false;
- break;
- }
- case 8: {
- Dispatcher::Callback8 callback =
- reinterpret_cast<Dispatcher::Callback8>(callback_generic);
- if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
- args[4], args[5], args[6], args[7]))
- break;
- error = false;
- break;
- }
- case 9: {
- Dispatcher::Callback9 callback =
- reinterpret_cast<Dispatcher::Callback9>(callback_generic);
- if (!(handler->*callback)(&ipc_info, args[0], args[1], args[2], args[3],
- args[4], args[5], args[6], args[7], args[8]))
- break;
- error = false;
- break;
- }
- default: {
- NOTREACHED();
- break;
- }
- }
- }
-
- if (error) {
- if (handler)
- SetCallError(SBOX_ERROR_FAILED_IPC, call_result);
- } else {
- memcpy(call_result, &ipc_info.return_info, sizeof(*call_result));
- SetCallSuccess(call_result);
- if (params->IsInOut()) {
- // Maybe the params got changed by the broker. We need to upadte the
- // memory section.
- memcpy(ipc_buffer, params.get(), output_size);
- }
- }
-
- ReleaseArgs(&ipc_params, args);
-
- return !error;
-}
-
-// This function gets called by a thread from the thread pool when a
-// ping event fires. The context is the same as passed in the RegisterWait()
-// call above.
-void __stdcall SharedMemIPCServer::ThreadPingEventReady(void* context,
- unsigned char) {
- if (NULL == context) {
- DCHECK(false);
- return;
- }
- ServerControl* service_context = reinterpret_cast<ServerControl*>(context);
- // Since the event fired, the channel *must* be busy. Change to kAckChannel
- // while we service it.
- LONG last_state =
- ::InterlockedCompareExchange(&service_context->channel->state,
- kAckChannel, kBusyChannel);
- if (kBusyChannel != last_state) {
- DCHECK(false);
- return;
- }
-
- // Prepare the result structure. At this point we will return some result
- // even if the IPC is invalid, malformed or has no handler.
- CrossCallReturn call_result = {0};
- void* buffer = service_context->channel_buffer;
-
- InvokeCallback(service_context, buffer, &call_result);
-
- // Copy the answer back into the channel and signal the pong event. This
- // should wake up the client so he can finish the the ipc cycle.
- CrossCallParams* call_params = reinterpret_cast<CrossCallParams*>(buffer);
- memcpy(call_params->GetCallReturn(), &call_result, sizeof(call_result));
- ::InterlockedExchange(&service_context->channel->state, kAckChannel);
- ::SetEvent(service_context->pong_event);
-}
-
-bool SharedMemIPCServer::MakeEvents(HANDLE* server_ping, HANDLE* server_pong,
- HANDLE* client_ping, HANDLE* client_pong) {
- // Note that the IPC client has no right to delete the events. That would
- // cause problems. The server *owns* the events.
- const DWORD kDesiredAccess = SYNCHRONIZE | EVENT_MODIFY_STATE;
-
- // The events are auto reset, and start not signaled.
- *server_ping = ::CreateEventW(NULL, FALSE, FALSE, NULL);
- if (!::DuplicateHandle(::GetCurrentProcess(), *server_ping, target_process_,
- client_ping, kDesiredAccess, FALSE, 0)) {
- return false;
- }
- *server_pong = ::CreateEventW(NULL, FALSE, FALSE, NULL);
- if (!::DuplicateHandle(::GetCurrentProcess(), *server_pong, target_process_,
- client_pong, kDesiredAccess, FALSE, 0)) {
- return false;
- }
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/sharedmem_ipc_server.h b/sandbox/win/src/sharedmem_ipc_server.h
deleted file mode 100644
index 94d6959..0000000
--- a/sandbox/win/src/sharedmem_ipc_server.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SHAREDMEM_IPC_SERVER_H_
-#define SANDBOX_SRC_SHAREDMEM_IPC_SERVER_H_
-
-#include <list>
-
-#include "base/basictypes.h"
-#include "base/gtest_prod_util.h"
-#include "sandbox/win/src/crosscall_params.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-
-// IPC transport implementation that uses shared memory.
-// This is the server side
-//
-// The server side has knowledge about the layout of the shared memory
-// and the state transitions. Both are explained in sharedmem_ipc_client.h
-//
-// As opposed to SharedMemIPClient, the Server object should be one for the
-// entire lifetime of the target process. The server is in charge of creating
-// the events (ping, pong) both for the client and for the target that are used
-// to signal the IPC and also in charge of setting the initial state of the
-// channels.
-//
-// When an IPC is ready, the server relies on being called by on the
-// ThreadPingEventReady callback. The IPC server then retrieves the buffer,
-// marshals it into a CrossCallParam object and calls the Dispatcher, who is in
-// charge of fulfilling the IPC request.
-namespace sandbox {
-
-// the shared memory implementation of the IPC server. There should be one
-// of these objects per target (IPC client) process
-class SharedMemIPCServer {
- public:
- // Creates the IPC server.
- // target_process: handle to the target process. It must be suspended.
- // target_process_id: process id of the target process.
- // target_job: the job object handle associated with the target process.
- // thread_provider: a thread provider object.
- // dispatcher: an object that can service IPC calls.
- SharedMemIPCServer(HANDLE target_process, DWORD target_process_id,
- HANDLE target_job, ThreadProvider* thread_provider,
- Dispatcher* dispatcher);
-
- ~SharedMemIPCServer();
-
- // Initializes the server structures, shared memory structures and
- // creates the kernels events used to signal the IPC.
- bool Init(void* shared_mem, uint32 shared_size, uint32 channel_size);
-
- private:
- // Allow tests to be marked DISABLED_. Note that FLAKY_ and FAILS_ prefixes
- // do not work with sandbox tests.
- FRIEND_TEST_ALL_PREFIXES(IPCTest, SharedMemServerTests);
- // When an event fires (IPC request). A thread from the ThreadProvider
- // will call this function. The context parameter should be the same as
- // provided when ThreadProvider::RegisterWait was called.
- static void __stdcall ThreadPingEventReady(void* context,
- unsigned char);
-
- // Makes the client and server events. This function is called once
- // per channel.
- bool MakeEvents(HANDLE* server_ping, HANDLE* server_pong,
- HANDLE* client_ping, HANDLE* client_pong);
-
- // A copy this structure is maintained per channel.
- // Note that a lot of the fields are just the same of what we have in the IPC
- // object itself. It is better to have the copies since we can dispatch in the
- // static method without worrying about converting back to a member function
- // call or about threading issues.
- struct ServerControl {
- // This channel server ping event.
- HANDLE ping_event;
- // This channel server pong event.
- HANDLE pong_event;
- // The size of this channel.
- uint32 channel_size;
- // The pointer to the actual channel data.
- char* channel_buffer;
- // The pointer to the base of the shared memory.
- char* shared_base;
- // A pointer to this channel's client-side control structure this structure
- // lives in the shared memory.
- ChannelControl* channel;
- // the IPC dispatcher associated with this channel.
- Dispatcher* dispatcher;
- // The target process information associated with this channel.
- ClientInfo target_info;
- };
-
- // Looks for the appropriate handler for this IPC and invokes it.
- static bool InvokeCallback(const ServerControl* service_context,
- void* ipc_buffer, CrossCallReturn* call_result);
-
- // Points to the shared memory channel control which lives at
- // the start of the shared section.
- IPCControl* client_control_;
-
- // Keeps track of the server side objects that are used to answer an IPC.
- typedef std::list<ServerControl*> ServerContexts;
- ServerContexts server_contexts_;
-
- // The thread provider provides the threads that call back into this object
- // when the IPC events fire.
- ThreadProvider* thread_provider_;
-
- // The IPC object is associated with a target process.
- HANDLE target_process_;
-
- // The target process id associated with the IPC object.
- DWORD target_process_id_;
-
- // The target object is inside a job too.
- HANDLE target_job_object_;
-
- // The dispatcher handles 'ready' IPC calls.
- Dispatcher* call_dispatcher_;
-
- DISALLOW_COPY_AND_ASSIGN(SharedMemIPCServer);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_SHAREDMEM_IPC_SERVER_H_
diff --git a/sandbox/win/src/sid.cc b/sandbox/win/src/sid.cc
deleted file mode 100644
index 261605d..0000000
--- a/sandbox/win/src/sid.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/sid.h"
-
-#include "base/logging.h"
-
-namespace sandbox {
-
-Sid::Sid(const SID *sid) {
- ::CopySid(SECURITY_MAX_SID_SIZE, sid_, const_cast<SID*>(sid));
-};
-
-Sid::Sid(WELL_KNOWN_SID_TYPE type) {
- DWORD size_sid = SECURITY_MAX_SID_SIZE;
- BOOL result = ::CreateWellKnownSid(type, NULL, sid_, &size_sid);
- DCHECK(result);
- DBG_UNREFERENCED_LOCAL_VARIABLE(result);
-}
-
-const SID *Sid::GetPSID() const {
- return reinterpret_cast<SID*>(const_cast<BYTE*>(sid_));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/sid.h b/sandbox/win/src/sid.h
deleted file mode 100644
index 4656859..0000000
--- a/sandbox/win/src/sid.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SID_H_
-#define SANDBOX_SRC_SID_H_
-
-#include <windows.h>
-
-namespace sandbox {
-
-// This class is used to hold and generate SIDS.
-class Sid {
- public:
- // Constructors initializing the object with the SID passed.
- // This is a converting constructor. It is not explicit.
- Sid(const SID *sid);
- Sid(WELL_KNOWN_SID_TYPE type);
-
- // Returns sid_.
- const SID *GetPSID() const;
-
- private:
- BYTE sid_[SECURITY_MAX_SID_SIZE];
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_SID_H_
diff --git a/sandbox/win/src/sid_unittest.cc b/sandbox/win/src/sid_unittest.cc
deleted file mode 100644
index 76d61e8..0000000
--- a/sandbox/win/src/sid_unittest.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains unit tests for the sid class.
-
-#define _ATL_NO_EXCEPTIONS
-#include <atlbase.h>
-#include <atlsecurity.h>
-
-#include "sandbox/win/src/sid.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace sandbox {
-
-// Calls ::EqualSid. This function exists only to simplify the calls to
-// ::EqualSid by removing the need to cast the input params.
-BOOL EqualSid(const SID *sid1, const SID *sid2) {
- return ::EqualSid(const_cast<SID*>(sid1), const_cast<SID*>(sid2));
-}
-
-// Tests the creation if a Sid
-TEST(SidTest, Constructors) {
- ATL::CSid sid_world = ATL::Sids::World();
- SID *sid_world_pointer = const_cast<SID*>(sid_world.GetPSID());
-
- // Check the SID* constructor
- Sid sid_sid_star(sid_world_pointer);
- ASSERT_TRUE(EqualSid(sid_world_pointer, sid_sid_star.GetPSID()));
-
- // Check the copy constructor
- Sid sid_copy(sid_sid_star);
- ASSERT_TRUE(EqualSid(sid_world_pointer, sid_copy.GetPSID()));
-
- // Note that the WELL_KNOWN_SID_TYPE constructor is tested in the GetPSID
- // test.
-}
-
-// Tests the method GetPSID
-TEST(SidTest, GetPSID) {
- // Check for non-null result;
- ASSERT_NE(static_cast<SID*>(NULL), Sid(::WinLocalSid).GetPSID());
- ASSERT_NE(static_cast<SID*>(NULL), Sid(::WinCreatorOwnerSid).GetPSID());
- ASSERT_NE(static_cast<SID*>(NULL), Sid(::WinBatchSid).GetPSID());
-
- ASSERT_TRUE(EqualSid(Sid(::WinNullSid).GetPSID(),
- ATL::Sids::Null().GetPSID()));
-
- ASSERT_TRUE(EqualSid(Sid(::WinWorldSid).GetPSID(),
- ATL::Sids::World().GetPSID()));
-
- ASSERT_TRUE(EqualSid(Sid(::WinDialupSid).GetPSID(),
- ATL::Sids::Dialup().GetPSID()));
-
- ASSERT_TRUE(EqualSid(Sid(::WinNetworkSid).GetPSID(),
- ATL::Sids::Network().GetPSID()));
-
- ASSERT_TRUE(EqualSid(Sid(::WinBuiltinAdministratorsSid).GetPSID(),
- ATL::Sids::Admins().GetPSID()));
-
- ASSERT_TRUE(EqualSid(Sid(::WinBuiltinUsersSid).GetPSID(),
- ATL::Sids::Users().GetPSID()));
-
- ASSERT_TRUE(EqualSid(Sid(::WinBuiltinGuestsSid).GetPSID(),
- ATL::Sids::Guests().GetPSID()));
-
- ASSERT_TRUE(EqualSid(Sid(::WinProxySid).GetPSID(),
- ATL::Sids::Proxy().GetPSID()));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/sidestep/ia32_modrm_map.cpp b/sandbox/win/src/sidestep/ia32_modrm_map.cpp
deleted file mode 100644
index 89bc189..0000000
--- a/sandbox/win/src/sidestep/ia32_modrm_map.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Table of relevant information about how to decode the ModR/M byte.
-// Based on information in the IA-32 Intel Architecture
-// Software Developer's Manual Volume 2: Instruction Set Reference.
-
-#include "sandbox/win/src/sidestep/mini_disassembler.h"
-#include "sandbox/win/src/sidestep/mini_disassembler_types.h"
-
-namespace sidestep {
-
-const ModrmEntry MiniDisassembler::s_ia16_modrm_map_[] = {
-// mod == 00
- /* r/m == 000 */ { false, false, OS_ZERO },
- /* r/m == 001 */ { false, false, OS_ZERO },
- /* r/m == 010 */ { false, false, OS_ZERO },
- /* r/m == 011 */ { false, false, OS_ZERO },
- /* r/m == 100 */ { false, false, OS_ZERO },
- /* r/m == 101 */ { false, false, OS_ZERO },
- /* r/m == 110 */ { true, false, OS_WORD },
- /* r/m == 111 */ { false, false, OS_ZERO },
-// mod == 01
- /* r/m == 000 */ { true, false, OS_BYTE },
- /* r/m == 001 */ { true, false, OS_BYTE },
- /* r/m == 010 */ { true, false, OS_BYTE },
- /* r/m == 011 */ { true, false, OS_BYTE },
- /* r/m == 100 */ { true, false, OS_BYTE },
- /* r/m == 101 */ { true, false, OS_BYTE },
- /* r/m == 110 */ { true, false, OS_BYTE },
- /* r/m == 111 */ { true, false, OS_BYTE },
-// mod == 10
- /* r/m == 000 */ { true, false, OS_WORD },
- /* r/m == 001 */ { true, false, OS_WORD },
- /* r/m == 010 */ { true, false, OS_WORD },
- /* r/m == 011 */ { true, false, OS_WORD },
- /* r/m == 100 */ { true, false, OS_WORD },
- /* r/m == 101 */ { true, false, OS_WORD },
- /* r/m == 110 */ { true, false, OS_WORD },
- /* r/m == 111 */ { true, false, OS_WORD },
-// mod == 11
- /* r/m == 000 */ { false, false, OS_ZERO },
- /* r/m == 001 */ { false, false, OS_ZERO },
- /* r/m == 010 */ { false, false, OS_ZERO },
- /* r/m == 011 */ { false, false, OS_ZERO },
- /* r/m == 100 */ { false, false, OS_ZERO },
- /* r/m == 101 */ { false, false, OS_ZERO },
- /* r/m == 110 */ { false, false, OS_ZERO },
- /* r/m == 111 */ { false, false, OS_ZERO }
-};
-
-const ModrmEntry MiniDisassembler::s_ia32_modrm_map_[] = {
-// mod == 00
- /* r/m == 000 */ { false, false, OS_ZERO },
- /* r/m == 001 */ { false, false, OS_ZERO },
- /* r/m == 010 */ { false, false, OS_ZERO },
- /* r/m == 011 */ { false, false, OS_ZERO },
- /* r/m == 100 */ { false, true, OS_ZERO },
- /* r/m == 101 */ { true, false, OS_DOUBLE_WORD },
- /* r/m == 110 */ { false, false, OS_ZERO },
- /* r/m == 111 */ { false, false, OS_ZERO },
-// mod == 01
- /* r/m == 000 */ { true, false, OS_BYTE },
- /* r/m == 001 */ { true, false, OS_BYTE },
- /* r/m == 010 */ { true, false, OS_BYTE },
- /* r/m == 011 */ { true, false, OS_BYTE },
- /* r/m == 100 */ { true, true, OS_BYTE },
- /* r/m == 101 */ { true, false, OS_BYTE },
- /* r/m == 110 */ { true, false, OS_BYTE },
- /* r/m == 111 */ { true, false, OS_BYTE },
-// mod == 10
- /* r/m == 000 */ { true, false, OS_DOUBLE_WORD },
- /* r/m == 001 */ { true, false, OS_DOUBLE_WORD },
- /* r/m == 010 */ { true, false, OS_DOUBLE_WORD },
- /* r/m == 011 */ { true, false, OS_DOUBLE_WORD },
- /* r/m == 100 */ { true, true, OS_DOUBLE_WORD },
- /* r/m == 101 */ { true, false, OS_DOUBLE_WORD },
- /* r/m == 110 */ { true, false, OS_DOUBLE_WORD },
- /* r/m == 111 */ { true, false, OS_DOUBLE_WORD },
-// mod == 11
- /* r/m == 000 */ { false, false, OS_ZERO },
- /* r/m == 001 */ { false, false, OS_ZERO },
- /* r/m == 010 */ { false, false, OS_ZERO },
- /* r/m == 011 */ { false, false, OS_ZERO },
- /* r/m == 100 */ { false, false, OS_ZERO },
- /* r/m == 101 */ { false, false, OS_ZERO },
- /* r/m == 110 */ { false, false, OS_ZERO },
- /* r/m == 111 */ { false, false, OS_ZERO },
-};
-
-}; // namespace sidestep
diff --git a/sandbox/win/src/sidestep/ia32_opcode_map.cpp b/sandbox/win/src/sidestep/ia32_opcode_map.cpp
deleted file mode 100644
index b7d8a60..0000000
--- a/sandbox/win/src/sidestep/ia32_opcode_map.cpp
+++ /dev/null
@@ -1,1159 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Opcode decoding maps. Based on the IA-32 Intel Architecture
-// Software Developer's Manual Volume 2: Instruction Set Reference. Idea
-// for how to lay out the tables in memory taken from the implementation
-// in the Bastard disassembly environment.
-
-#include "sandbox/win/src/sidestep/mini_disassembler.h"
-
-namespace sidestep {
-
-/*
-* This is the first table to be searched; the first field of each
-* Opcode in the table is either 0 to indicate you're in the
-* right table, or an index to the correct table, in the global
-* map g_pentiumOpcodeMap
-*/
-const Opcode s_first_opcode_byte[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xE */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF */ { 1, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x10 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x11 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x12 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x13 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x14 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x15 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x16 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x17 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x18 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x19 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1E */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1F */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x20 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x21 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x22 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x23 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x24 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x25 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x26 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x27 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "daa", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x28 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x29 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "das", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x30 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x31 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x32 */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x33 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x34 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x35 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x36 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x37 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "aaa", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x38 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x39 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3C */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3E */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "aas", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x40 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x41 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x42 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x43 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x44 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x45 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x46 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x47 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x48 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x49 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4A */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4B */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4C */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4E */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x50 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x51 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x52 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x53 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x54 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x55 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x56 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x57 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x58 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x59 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5A */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5B */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5C */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5D */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5E */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x60 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "pushad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x61 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "popad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x62 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_A, AM_NOT_USED, "bound", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x63 */ { 0, IT_GENERIC, AM_E | OT_W, AM_G | OT_W, AM_NOT_USED, "arpl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x64 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x65 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x66 */ { 0, IT_PREFIX_OPERAND, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x67 */ { 0, IT_PREFIX_ADDRESS, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x68 */ { 0, IT_GENERIC, AM_I | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x69 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_I | OT_V, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6A */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_I | OT_B, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6C */ { 0, IT_GENERIC, AM_Y | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "insb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6D */ { 0, IT_GENERIC, AM_Y | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "insd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6E */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_X | OT_B, AM_NOT_USED, "outsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6F */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_X | OT_V, AM_NOT_USED, "outsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x70 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x71 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x72 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x73 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x74 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x75 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x76 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x77 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "ja", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x78 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "js", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x79 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7A */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7B */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7C */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7D */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7E */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7F */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x80 */ { 2, IT_REFERENCE, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x81 */ { 3, IT_REFERENCE, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x82 */ { 4, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x83 */ { 5, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x84 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x85 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x86 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x87 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x88 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x89 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8A */ { 0, IT_GENERIC, AM_G | OT_B, AM_E | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8C */ { 0, IT_GENERIC, AM_E | OT_W, AM_S | OT_W, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8D */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_ADDRESS_MODE_M, AM_NOT_USED, "lea", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8E */ { 0, IT_GENERIC, AM_S | OT_W, AM_E | OT_W, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8F */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x90 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "nop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x91 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x92 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x93 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x94 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x95 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x96 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x97 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "xchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x98 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cwde", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x99 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cdq", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9A */ { 0, IT_JUMP, AM_A | OT_P, AM_NOT_USED, AM_NOT_USED, "callf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9B */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wait", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9C */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "pushfd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9D */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "popfd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9E */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sahf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9F */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lahf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA0 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_O | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA1 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_O | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA2 */ { 0, IT_GENERIC, AM_O | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA3 */ { 0, IT_GENERIC, AM_O | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA4 */ { 0, IT_GENERIC, AM_X | OT_B, AM_Y | OT_B, AM_NOT_USED, "movsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA5 */ { 0, IT_GENERIC, AM_X | OT_V, AM_Y | OT_V, AM_NOT_USED, "movsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA6 */ { 0, IT_GENERIC, AM_X | OT_B, AM_Y | OT_B, AM_NOT_USED, "cmpsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA7 */ { 0, IT_GENERIC, AM_X | OT_V, AM_Y | OT_V, AM_NOT_USED, "cmpsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA8 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAA */ { 0, IT_GENERIC, AM_Y | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "stosb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAB */ { 0, IT_GENERIC, AM_Y | OT_V, AM_REGISTER | OT_V, AM_NOT_USED, "stosd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_X| OT_B, AM_NOT_USED, "lodsb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_X| OT_V, AM_NOT_USED, "lodsd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAE */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_Y | OT_B, AM_NOT_USED, "scasb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_Y | OT_V, AM_NOT_USED, "scasd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB0 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB1 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB2 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB3 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB5 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB6 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB7 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB8 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB9 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBA */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBB */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBC */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBD */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBE */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBF */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC0 */ { 6, IT_REFERENCE, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC1 */ { 7, IT_REFERENCE, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC2 */ { 0, IT_RETURN, AM_I | OT_W, AM_NOT_USED, AM_NOT_USED, "ret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC3 */ { 0, IT_RETURN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC4 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_P, AM_NOT_USED, "les", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC5 */ { 0, IT_GENERIC, AM_G | OT_V, AM_M | OT_P, AM_NOT_USED, "lds", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC8 */ { 0, IT_GENERIC, AM_I | OT_W, AM_I | OT_B, AM_NOT_USED, "enter", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "leave", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCA */ { 0, IT_RETURN, AM_I | OT_W, AM_NOT_USED, AM_NOT_USED, "retf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCB */ { 0, IT_RETURN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "retf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCC */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "int3", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCD */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "int", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCE */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "into", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCF */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "iret", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD0 */ { 8, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD1 */ { 9, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD2 */ { 10, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD3 */ { 11, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD4 */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "aam", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD5 */ { 0, IT_GENERIC, AM_I | OT_B, AM_NOT_USED, AM_NOT_USED, "aad", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD7 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "xlat", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-
- // The following 8 lines would be references to the FPU tables, but we currently
- // do not support the FPU instructions in this disassembler.
-
- /* 0xD8 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD9 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xDA */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xDB */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xDC */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xDD */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xDE */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xDF */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-
-
- /* 0xE0 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loopnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xE1 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loopz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xE2 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "loop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xE3 */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jcxz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xE4 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xE5 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_I | OT_B, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xE6 */ { 0, IT_GENERIC, AM_I | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xE7 */ { 0, IT_GENERIC, AM_I | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xE8 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xE9 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xEA */ { 0, IT_JUMP, AM_A | OT_P, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xEB */ { 0, IT_JUMP, AM_J | OT_B, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xEC */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_REGISTER | OT_W, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xED */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_REGISTER | OT_W, AM_NOT_USED, "in", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xEE */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_REGISTER | OT_B, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xEF */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_REGISTER | OT_V, AM_NOT_USED, "out", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF0 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lock:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF2 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "repne:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF3 */ { 0, IT_PREFIX, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rep:", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF4 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "hlt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF5 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cmc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF6 */ { 12, IT_REFERENCE, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF7 */ { 13, IT_REFERENCE, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF8 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "stc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xFA */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cli", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xFB */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xFC */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xFD */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "std", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xFE */ { 14, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xFF */ { 15, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f[] = {
- /* 0x0 */ { 16, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 17, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "lar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "lsl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "invd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wbinvd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ud2", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xE */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x10 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "movups", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "movsd" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "movss" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "movupd" } },
- /* 0x11 */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movups", true,
- /* F2h */ { 0, IT_GENERIC, AM_W | OT_SD, AM_V | OT_SD, AM_NOT_USED, "movsd" },
- /* F3h */ { 0, IT_GENERIC, AM_W | OT_SS, AM_V | OT_SS, AM_NOT_USED, "movss" },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movupd" } },
- /* 0x12 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlps", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhlps" }, // only one of ...
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhlps" }, // ...these two is correct, Intel doesn't specify which
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_S, AM_NOT_USED, "movlpd" } },
- /* 0x13 */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movlps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movlpd" } },
- /* 0x14 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_Q, AM_NOT_USED, "unpcklps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_Q, AM_NOT_USED, "unpcklpd" } },
- /* 0x15 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_Q, AM_NOT_USED, "unpckhps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_Q, AM_NOT_USED, "unpckhpd" } },
- /* 0x16 */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movhps", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlhps" }, // only one of...
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movlhps" }, // ...these two is correct, Intel doesn't specify which
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movhpd" } },
- /* 0x17 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movhpd" } },
- /* 0x18 */ { 18, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x19 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1A */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1B */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1C */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1D */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1E */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1F */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x20 */ { 0, IT_GENERIC, AM_R | OT_D, AM_C | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x21 */ { 0, IT_GENERIC, AM_R | OT_D, AM_D | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x22 */ { 0, IT_GENERIC, AM_C | OT_D, AM_R | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x23 */ { 0, IT_GENERIC, AM_D | OT_D, AM_R | OT_D, AM_NOT_USED, "mov", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x24 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x25 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x26 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x27 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x28 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "movaps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "movapd" } },
- /* 0x29 */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movaps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movapd" } },
- /* 0x2A */ { 0, IT_GENERIC, AM_V | OT_PS, AM_Q | OT_Q, AM_NOT_USED, "cvtpi2ps", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_E | OT_D, AM_NOT_USED, "cvtsi2sd" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_E | OT_D, AM_NOT_USED, "cvtsi2ss" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_Q | OT_DQ, AM_NOT_USED, "cvtpi2pd" } },
- /* 0x2B */ { 0, IT_GENERIC, AM_W | OT_PS, AM_V | OT_PS, AM_NOT_USED, "movntps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_PD, AM_V | OT_PD, AM_NOT_USED, "movntpd" } },
- /* 0x2C */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_W | OT_PS, AM_NOT_USED, "cvttps2pi", true,
- /* F2h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SD, AM_NOT_USED, "cvttsd2si" },
- /* F3h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SS, AM_NOT_USED, "cvttss2si" },
- /* 66h */ { 0, IT_GENERIC, AM_Q | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvttpd2pi" } },
- /* 0x2D */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_W | OT_PS, AM_NOT_USED, "cvtps2pi", true,
- /* F2h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SD, AM_NOT_USED, "cvtsd2si" },
- /* F3h */ { 0, IT_GENERIC, AM_G | OT_D, AM_W | OT_SS, AM_NOT_USED, "cvtss2si" },
- /* 66h */ { 0, IT_GENERIC, AM_Q | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvtpd2pi" } },
- /* 0x2E */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "ucomiss", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "ucomisd" } },
- /* 0x2F */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_SS, AM_NOT_USED, "comiss", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "comisd" } },
- /* 0x30 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "wrmsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x31 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdtsc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x32 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdmsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x33 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rdpmc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x34 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sysenter", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x35 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "sysexit", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x36 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x37 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x38 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x39 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3A */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3B */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3C */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "movnti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3D */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3E */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3F */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x40 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x41 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x42 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x43 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x44 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x45 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x46 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x47 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmova", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x48 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x49 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4A */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4B */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4C */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4D */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4E */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4F */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "cmovg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x50 */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_PS, AM_NOT_USED, "movmskps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_PD, AM_NOT_USED, "movmskpd" } },
- /* 0x51 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "sqrtps", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "sqrtsd" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "sqrtss" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "sqrtpd" } },
- /* 0x52 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "rsqrtps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "rsqrtss" },
- /* 66h */ { 0 } },
- /* 0x53 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "rcpps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "rcpss" },
- /* 66h */ { 0 } },
- /* 0x54 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "andps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "andpd" } },
- /* 0x55 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "andnps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "andnpd" } },
- /* 0x56 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "orps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "orpd" } },
- /* 0x57 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "xorps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "xorpd" } },
- /* 0x58 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "addps", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "addsd" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "addss" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "addpd" } },
- /* 0x59 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "mulps", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "mulsd" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "mulss" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "mulpd" } },
- /* 0x5A */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PS, AM_NOT_USED, "cvtps2pd", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "cvtsd2ss" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "cvtss2sd" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PD, AM_NOT_USED, "cvtpd2ps" } },
- /* 0x5B */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_DQ, AM_NOT_USED, "cvtdq2ps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PS, AM_NOT_USED, "cvttps2dq" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PS, AM_NOT_USED, "cvtps2dq" } },
- /* 0x5C */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "subps", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "subsd" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "subss" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "subpd" } },
- /* 0x5D */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "minps", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "minsd" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "minss" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "minpd" } },
- /* 0x5E */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "divps", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "divsd" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "divss" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "divpd" } },
- /* 0x5F */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_NOT_USED, "maxps", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_NOT_USED, "maxsd" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_NOT_USED, "maxss" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_NOT_USED, "maxpd" } },
- /* 0x60 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpcklbw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklbw" } },
- /* 0x61 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpcklwd", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklwd" } },
- /* 0x62 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckldq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpckldq" } },
- /* 0x63 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packsswb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "packsswb" } },
- /* 0x64 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtb" } },
- /* 0x65 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtw" } },
- /* 0x66 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "pcmpgtd", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpgtd" } },
- /* 0x67 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packuswb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "packuswb" } },
- /* 0x68 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhbw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhbw" } },
- /* 0x69 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhwd", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhwd" } },
- /* 0x6A */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "punpckhdq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "punpckhdq" } },
- /* 0x6B */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "packssdw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_Q | OT_DQ, AM_NOT_USED, "packssdw" } },
- /* 0x6C */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklqdq" } },
- /* 0x6D */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "punpcklqdq" } },
- /* 0x6E */ { 0, IT_GENERIC, AM_P | OT_D, AM_E | OT_D, AM_NOT_USED, "movd", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_E | OT_D, AM_NOT_USED, "movd" } },
- /* 0x6F */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_D, AM_NOT_USED, "movq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "movdqu" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "movdqa" } },
- /* 0x70 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_I | OT_B, "pshuf", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshuflw" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshufhw" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_I | OT_B, "pshufd" } },
- /* 0x71 */ { 19, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x72 */ { 20, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x73 */ { 21, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x74 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqb" } },
- /* 0x75 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqw" } },
- /* 0x76 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pcmpeqd", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pcmpeqd" } },
- /* 0x77 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "emms", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-
- // The following six opcodes are escapes into the MMX stuff, which this disassembler does not support.
- /* 0x78 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x79 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7A */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7B */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7C */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7D */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-
- /* 0x7E */ { 0, IT_GENERIC, AM_E | OT_D, AM_P | OT_D, AM_NOT_USED, "movd", true,
- /* F2h */ { 0 },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movq" },
- /* 66h */ { 0, IT_GENERIC, AM_E | OT_D, AM_V | OT_DQ, AM_NOT_USED, "movd" } },
- /* 0x7F */ { 0, IT_GENERIC, AM_Q | OT_Q, AM_P | OT_Q, AM_NOT_USED, "movq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movdqu" },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movdqa" } },
- /* 0x80 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x81 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x82 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x83 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x84 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x85 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x86 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x87 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "ja", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x88 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "js", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x89 */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8A */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8B */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8C */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8D */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8E */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x8F */ { 0, IT_JUMP, AM_J | OT_V, AM_NOT_USED, AM_NOT_USED, "jg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x90 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "seto", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x91 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setno", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x92 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x93 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setnc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x94 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x95 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setnz", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x96 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setbe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x97 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "seta", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x98 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "sets", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x99 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setns", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9A */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setpe", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9B */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setpo", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9C */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9D */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setge", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9E */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setle", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x9F */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "setg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA0 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA1 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA2 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "cpuid", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "bt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B, "shld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B | AM_REGISTER, "shld", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA6 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA7 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA8 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xA9 */ { 0, IT_GENERIC, AM_REGISTER | OT_W, AM_NOT_USED, AM_NOT_USED, "pop", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAA */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "rsm", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAB */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "bts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAC */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B, "shrd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAD */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_I | OT_B | AM_REGISTER, "shrd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAE */ { 22, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xAF */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "cmpxchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "cmpxchg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB2 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lss", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "btr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB4 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lfs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB5 */ { 0, IT_GENERIC, AM_M | OT_P, AM_NOT_USED, AM_NOT_USED, "lgs", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB6 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_B, AM_NOT_USED, "movzx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB7 */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "movzx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB8 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xB9 */ { 0, IT_UNKNOWN, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ud1", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBA */ { 23, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBB */ { 0, IT_GENERIC, AM_E | OT_V, AM_G | OT_V, AM_NOT_USED, "btc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBC */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "bsf", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBD */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_V, AM_NOT_USED, "bsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBE */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_B, AM_NOT_USED, "movsx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xBF */ { 0, IT_GENERIC, AM_G | OT_V, AM_E | OT_W, AM_NOT_USED, "movsx", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_G | OT_B, AM_NOT_USED, "xadd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "xadd", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC2 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_I | OT_B, "cmpps", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_SD, AM_W | OT_SD, AM_I | OT_B, "cmpsd" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_SS, AM_W | OT_SS, AM_I | OT_B, "cmpss" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_I | OT_B, "cmppd" } },
- /* 0xC3 */ { 0, IT_GENERIC, AM_E | OT_D, AM_G | OT_D, AM_NOT_USED, "movnti", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_E | OT_D, AM_I | OT_B, "pinsrw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_E | OT_D, AM_I | OT_B, "pinsrw" } },
- /* 0xC5 */ { 0, IT_GENERIC, AM_G | OT_D, AM_P | OT_Q, AM_I | OT_B, "pextrw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_G | OT_D, AM_V | OT_DQ, AM_I | OT_B, "pextrw" } },
- /* 0xC6 */ { 0, IT_GENERIC, AM_V | OT_PS, AM_W | OT_PS, AM_I | OT_B, "shufps", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_PD, AM_I | OT_B, "shufpd" } },
- /* 0xC7 */ { 24, IT_REFERENCE, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC8 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xC9 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCA */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCB */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCC */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCD */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCE */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xCF */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "bswap", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xD1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrlw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrlw" } },
- /* 0xD2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrld", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrld" } },
- /* 0xD3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrlq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrlq" } },
- /* 0xD4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddq" } },
- /* 0xD5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmullw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmullw" } },
- /* 0xD6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "unused without prefix", true,
- /* F2h */ { 0, IT_GENERIC, AM_P | OT_Q, AM_W | OT_Q, AM_NOT_USED, "movdq2q" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_Q | OT_Q, AM_NOT_USED, "movq2dq" },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movq" } },
- /* 0xD7 */ { 0, IT_GENERIC, AM_G | OT_D, AM_P | OT_Q, AM_NOT_USED, "pmovmskb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_G | OT_D, AM_V | OT_DQ, AM_NOT_USED, "pmovmskb" } },
- /* 0xD8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubusb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubusb" } },
- /* 0xD9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubusw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubusw" } },
- /* 0xDA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pminub", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pminub" } },
- /* 0xDB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pand", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pand" } },
- /* 0xDC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddusb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddusb" } },
- /* 0xDD */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddusw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddusw" } },
- /* 0xDE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaxub", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaxub" } },
- /* 0xDF */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pandn", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pandn" } },
- /* 0xE0 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pavgb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pavgb" } },
- /* 0xE1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psraw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrqw" } },
- /* 0xE2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psrad", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psrad" } },
- /* 0xE3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pavgw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pavgw" } },
- /* 0xE4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmulhuw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmulhuw" } },
- /* 0xE5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmulhuw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmulhw" } },
- /* 0xE6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "not used without prefix", true,
- /* F2h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvtpd2dq" },
- /* F3h */ { 0, IT_GENERIC, AM_V | OT_PD, AM_W | OT_DQ, AM_NOT_USED, "cvtdq2pd" },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_PD, AM_NOT_USED, "cvttpd2dq" } },
- /* 0xE7 */ { 0, IT_GENERIC, AM_W | OT_Q, AM_V | OT_Q, AM_NOT_USED, "movntq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_V | OT_DQ, AM_NOT_USED, "movntdq" } },
- /* 0xE8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubsb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubsb" } },
- /* 0xE9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubsw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubsw" } },
- /* 0xEA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pminsw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pminsw" } },
- /* 0xEB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "por", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "por" } },
- /* 0xEC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddsb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddsb" } },
- /* 0xED */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddsw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddsw" } },
- /* 0xEE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaxsw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaxsw" } },
- /* 0xEF */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pxor", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pxor" } },
- /* 0xF0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0xF1 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psllw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psllw" } },
- /* 0xF2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pslld", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pslld" } },
- /* 0xF3 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psllq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psllq" } },
- /* 0xF4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmuludq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmuludq" } },
- /* 0xF5 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "pmaddwd", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "pmaddwd" } },
- /* 0xF6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psadbw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psadbw" } },
- /* 0xF7 */ { 0, IT_GENERIC, AM_P | OT_PI, AM_Q | OT_PI, AM_NOT_USED, "maskmovq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "maskmovdqu" } },
- /* 0xF8 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubb" } },
- /* 0xF9 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubw" } },
- /* 0xFA */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubd", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubd" } },
- /* 0xFB */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "psubq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "psubq" } },
- /* 0xFC */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddb", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddb" } },
- /* 0xFD */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddw" } },
- /* 0xFE */ { 0, IT_GENERIC, AM_P | OT_Q, AM_Q | OT_Q, AM_NOT_USED, "paddd", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_V | OT_DQ, AM_W | OT_DQ, AM_NOT_USED, "paddd" } },
- /* 0xFF */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f00[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "sldt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "str", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "lldt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "ltr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "verr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "verw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f01[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "sgdt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "sidt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "lgdt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_M | OT_S, AM_NOT_USED, AM_NOT_USED, "lidt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "smsw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_W, AM_NOT_USED, AM_NOT_USED, "lmsw", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_M | OT_B, AM_NOT_USED, AM_NOT_USED, "invlpg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f18[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_M | OT_ADDRESS_MODE_M, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_REGISTER | OT_D, AM_NOT_USED, AM_NOT_USED, "prefetch", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f71[] = {
- /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrlw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrlw" } },
- /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psraw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psraw" } },
- /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psllw", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_P | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psllw" } },
- /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f72[] = {
- /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrld", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrld" } },
- /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrad", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrad" } },
- /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "pslld", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslld" } },
- /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0f73[] = {
- /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psrlq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psrlq" } },
- /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_P | OT_Q, AM_I | OT_B, AM_NOT_USED, "psllq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "psllq" } },
- /* 0x7 */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslldq", true,
- /* F2h */ { 0 },
- /* F3h */ { 0 },
- /* 66h */ { 0, IT_GENERIC, AM_W | OT_DQ, AM_I | OT_B, AM_NOT_USED, "pslldq" } },
-};
-
-const Opcode s_opcode_byte_after_0fae[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "fxsave", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "fxrstor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "ldmxcsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "stmxcsr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "lfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "mfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, "clflush/sfence", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
-};
-
-const Opcode s_opcode_byte_after_0fba[] = {
- /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "bt", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "bts", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "btr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "btc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_0fc7[] = {
- /* 0x0 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_M | OT_Q, AM_NOT_USED, AM_NOT_USED, "cmpxch8b", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_80[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_81[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_82[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_83[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "add", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "or", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "adc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sbb", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "and", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sub", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "xor", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "cmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_c0[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_c1[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d0[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_IMPLICIT, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d1[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_IMPLICIT, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d2[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_B, AM_REGISTER | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_d3[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rol", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "ror", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rcl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "rcr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "shl", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "shr", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "sal", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_E | OT_V, AM_REGISTER | OT_B, AM_NOT_USED, "sar", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_f6[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_I | OT_B, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "not", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "neg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, OT_B | AM_REGISTER, AM_E | OT_B, AM_NOT_USED, "mul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, OT_B | AM_REGISTER, AM_E | OT_B, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_E | OT_B, AM_NOT_USED, "div", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_B, AM_E | OT_B, AM_NOT_USED, "idiv", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_f7[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_I | OT_V, AM_NOT_USED, "test", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "not", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "neg", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "mul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "imul", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "div", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_GENERIC, AM_REGISTER | OT_V, AM_E | OT_V, AM_NOT_USED, "idiv", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_fe[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_B, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-const Opcode s_opcode_byte_after_ff[] = {
- /* 0x0 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "inc", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x1 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "dec", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x2 */ { 0, IT_JUMP, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x3 */ { 0, IT_JUMP, AM_E | OT_P, AM_NOT_USED, AM_NOT_USED, "call", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x4 */ { 0, IT_JUMP, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x5 */ { 0, IT_JUMP, AM_E | OT_P, AM_NOT_USED, AM_NOT_USED, "jmp", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x6 */ { 0, IT_GENERIC, AM_E | OT_V, AM_NOT_USED, AM_NOT_USED, "push", false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } },
- /* 0x7 */ { 0, IT_UNUSED, AM_NOT_USED, AM_NOT_USED, AM_NOT_USED, 0, false, /* F2h */ { 0 }, /* F3h */ { 0 }, /* 66h */ { 0 } }
-};
-
-/*
-* A table of all the other tables, containing some extra information, e.g.
-* how to mask out the byte we're looking at.
-*/
-const OpcodeTable MiniDisassembler::s_ia32_opcode_map_[]={
- // One-byte opcodes and jumps to larger
- /* 0 */ {s_first_opcode_byte, 0, 0xff, 0, 0xff},
- // Two-byte opcodes (second byte)
- /* 1 */ {s_opcode_byte_after_0f, 0, 0xff, 0, 0xff},
- // Start of tables for opcodes using ModR/M bits as extension
- /* 2 */ {s_opcode_byte_after_80, 3, 0x07, 0, 0x07},
- /* 3 */ {s_opcode_byte_after_81, 3, 0x07, 0, 0x07},
- /* 4 */ {s_opcode_byte_after_82, 3, 0x07, 0, 0x07},
- /* 5 */ {s_opcode_byte_after_83, 3, 0x07, 0, 0x07},
- /* 6 */ {s_opcode_byte_after_c0, 3, 0x07, 0, 0x07},
- /* 7 */ {s_opcode_byte_after_c1, 3, 0x07, 0, 0x07},
- /* 8 */ {s_opcode_byte_after_d0, 3, 0x07, 0, 0x07},
- /* 9 */ {s_opcode_byte_after_d1, 3, 0x07, 0, 0x07},
- /* 10 */ {s_opcode_byte_after_d2, 3, 0x07, 0, 0x07},
- /* 11 */ {s_opcode_byte_after_d3, 3, 0x07, 0, 0x07},
- /* 12 */ {s_opcode_byte_after_f6, 3, 0x07, 0, 0x07},
- /* 13 */ {s_opcode_byte_after_f7, 3, 0x07, 0, 0x07},
- /* 14 */ {s_opcode_byte_after_fe, 3, 0x07, 0, 0x01},
- /* 15 */ {s_opcode_byte_after_ff, 3, 0x07, 0, 0x07},
- /* 16 */ {s_opcode_byte_after_0f00, 3, 0x07, 0, 0x07},
- /* 17 */ {s_opcode_byte_after_0f01, 3, 0x07, 0, 0x07},
- /* 18 */ {s_opcode_byte_after_0f18, 3, 0x07, 0, 0x07},
- /* 19 */ {s_opcode_byte_after_0f71, 3, 0x07, 0, 0x07},
- /* 20 */ {s_opcode_byte_after_0f72, 3, 0x07, 0, 0x07},
- /* 21 */ {s_opcode_byte_after_0f73, 3, 0x07, 0, 0x07},
- /* 22 */ {s_opcode_byte_after_0fae, 3, 0x07, 0, 0x07},
- /* 23 */ {s_opcode_byte_after_0fba, 3, 0x07, 0, 0x07},
- /* 24 */ {s_opcode_byte_after_0fc7, 3, 0x07, 0, 0x01}
-};
-
-}; // namespace sidestep
diff --git a/sandbox/win/src/sidestep/mini_disassembler.cpp b/sandbox/win/src/sidestep/mini_disassembler.cpp
deleted file mode 100644
index 1e8e0bd..0000000
--- a/sandbox/win/src/sidestep/mini_disassembler.cpp
+++ /dev/null
@@ -1,395 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implementation of MiniDisassembler.
-
-#ifdef _WIN64
-#error The code in this file should not be used on 64-bit Windows.
-#endif
-
-#include "sandbox/win/src/sidestep/mini_disassembler.h"
-
-namespace sidestep {
-
-MiniDisassembler::MiniDisassembler(bool operand_default_is_32_bits,
- bool address_default_is_32_bits)
- : operand_default_is_32_bits_(operand_default_is_32_bits),
- address_default_is_32_bits_(address_default_is_32_bits) {
- Initialize();
-}
-
-MiniDisassembler::MiniDisassembler()
- : operand_default_is_32_bits_(true),
- address_default_is_32_bits_(true) {
- Initialize();
-}
-
-InstructionType MiniDisassembler::Disassemble(
- unsigned char* start_byte,
- unsigned int* instruction_bytes) {
- // Clean up any state from previous invocations.
- Initialize();
-
- // Start by processing any prefixes.
- unsigned char* current_byte = start_byte;
- unsigned int size = 0;
- InstructionType instruction_type = ProcessPrefixes(current_byte, &size);
-
- if (IT_UNKNOWN == instruction_type)
- return instruction_type;
-
- current_byte += size;
- size = 0;
-
- // Invariant: We have stripped all prefixes, and the operand_is_32_bits_
- // and address_is_32_bits_ flags are correctly set.
-
- instruction_type = ProcessOpcode(current_byte, 0, &size);
-
- // Check for error processing instruction
- if ((IT_UNKNOWN == instruction_type_) || (IT_UNUSED == instruction_type_)) {
- return IT_UNKNOWN;
- }
-
- current_byte += size;
-
- // Invariant: operand_bytes_ indicates the total size of operands
- // specified by the opcode and/or ModR/M byte and/or SIB byte.
- // pCurrentByte points to the first byte after the ModR/M byte, or after
- // the SIB byte if it is present (i.e. the first byte of any operands
- // encoded in the instruction).
-
- // We get the total length of any prefixes, the opcode, and the ModR/M and
- // SIB bytes if present, by taking the difference of the original starting
- // address and the current byte (which points to the first byte of the
- // operands if present, or to the first byte of the next instruction if
- // they are not). Adding the count of bytes in the operands encoded in
- // the instruction gives us the full length of the instruction in bytes.
- *instruction_bytes += operand_bytes_ + (current_byte - start_byte);
-
- // Return the instruction type, which was set by ProcessOpcode().
- return instruction_type_;
-}
-
-void MiniDisassembler::Initialize() {
- operand_is_32_bits_ = operand_default_is_32_bits_;
- address_is_32_bits_ = address_default_is_32_bits_;
- operand_bytes_ = 0;
- have_modrm_ = false;
- should_decode_modrm_ = false;
- instruction_type_ = IT_UNKNOWN;
- got_f2_prefix_ = false;
- got_f3_prefix_ = false;
- got_66_prefix_ = false;
-}
-
-InstructionType MiniDisassembler::ProcessPrefixes(unsigned char* start_byte,
- unsigned int* size) {
- InstructionType instruction_type = IT_GENERIC;
- const Opcode& opcode = s_ia32_opcode_map_[0].table_[*start_byte];
-
- switch (opcode.type_) {
- case IT_PREFIX_ADDRESS:
- address_is_32_bits_ = !address_default_is_32_bits_;
- goto nochangeoperand;
- case IT_PREFIX_OPERAND:
- operand_is_32_bits_ = !operand_default_is_32_bits_;
- nochangeoperand:
- case IT_PREFIX:
-
- if (0xF2 == (*start_byte))
- got_f2_prefix_ = true;
- else if (0xF3 == (*start_byte))
- got_f3_prefix_ = true;
- else if (0x66 == (*start_byte))
- got_66_prefix_ = true;
-
- instruction_type = opcode.type_;
- (*size)++;
- // we got a prefix, so add one and check next byte
- ProcessPrefixes(start_byte + 1, size);
- default:
- break; // not a prefix byte
- }
-
- return instruction_type;
-}
-
-InstructionType MiniDisassembler::ProcessOpcode(unsigned char* start_byte,
- unsigned int table_index,
- unsigned int* size) {
- const OpcodeTable& table = s_ia32_opcode_map_[table_index]; // Get our table
- unsigned char current_byte = (*start_byte) >> table.shift_;
- current_byte = current_byte & table.mask_; // Mask out the bits we will use
-
- // Check whether the byte we have is inside the table we have.
- if (current_byte < table.min_lim_ || current_byte > table.max_lim_) {
- instruction_type_ = IT_UNKNOWN;
- return instruction_type_;
- }
-
- const Opcode& opcode = table.table_[current_byte];
- if (IT_UNUSED == opcode.type_) {
- // This instruction is not used by the IA-32 ISA, so we indicate
- // this to the user. Probably means that we were pointed to
- // a byte in memory that was not the start of an instruction.
- instruction_type_ = IT_UNUSED;
- return instruction_type_;
- } else if (IT_REFERENCE == opcode.type_) {
- // We are looking at an opcode that has more bytes (or is continued
- // in the ModR/M byte). Recursively find the opcode definition in
- // the table for the opcode's next byte.
- (*size)++;
- ProcessOpcode(start_byte + 1, opcode.table_index_, size);
- return instruction_type_;
- }
-
- const SpecificOpcode* specific_opcode = reinterpret_cast<
- const SpecificOpcode*>(&opcode);
- if (opcode.is_prefix_dependent_) {
- if (got_f2_prefix_ && opcode.opcode_if_f2_prefix_.mnemonic_ != 0) {
- specific_opcode = &opcode.opcode_if_f2_prefix_;
- } else if (got_f3_prefix_ && opcode.opcode_if_f3_prefix_.mnemonic_ != 0) {
- specific_opcode = &opcode.opcode_if_f3_prefix_;
- } else if (got_66_prefix_ && opcode.opcode_if_66_prefix_.mnemonic_ != 0) {
- specific_opcode = &opcode.opcode_if_66_prefix_;
- }
- }
-
- // Inv: The opcode type is known.
- instruction_type_ = specific_opcode->type_;
-
- // Let's process the operand types to see if we have any immediate
- // operands, and/or a ModR/M byte.
-
- ProcessOperand(specific_opcode->flag_dest_);
- ProcessOperand(specific_opcode->flag_source_);
- ProcessOperand(specific_opcode->flag_aux_);
-
- // Inv: We have processed the opcode and incremented operand_bytes_
- // by the number of bytes of any operands specified by the opcode
- // that are stored in the instruction (not registers etc.). Now
- // we need to return the total number of bytes for the opcode and
- // for the ModR/M or SIB bytes if they are present.
-
- if (table.mask_ != 0xff) {
- if (have_modrm_) {
- // we're looking at a ModR/M byte so we're not going to
- // count that into the opcode size
- ProcessModrm(start_byte, size);
- return IT_GENERIC;
- } else {
- // need to count the ModR/M byte even if it's just being
- // used for opcode extension
- (*size)++;
- return IT_GENERIC;
- }
- } else {
- if (have_modrm_) {
- // The ModR/M byte is the next byte.
- (*size)++;
- ProcessModrm(start_byte + 1, size);
- return IT_GENERIC;
- } else {
- (*size)++;
- return IT_GENERIC;
- }
- }
-}
-
-bool MiniDisassembler::ProcessOperand(int flag_operand) {
- bool succeeded = true;
- if (AM_NOT_USED == flag_operand)
- return succeeded;
-
- // Decide what to do based on the addressing mode.
- switch (flag_operand & AM_MASK) {
- // No ModR/M byte indicated by these addressing modes, and no
- // additional (e.g. immediate) parameters.
- case AM_A: // Direct address
- case AM_F: // EFLAGS register
- case AM_X: // Memory addressed by the DS:SI register pair
- case AM_Y: // Memory addressed by the ES:DI register pair
- case AM_IMPLICIT: // Parameter is implicit, occupies no space in
- // instruction
- break;
-
- // There is a ModR/M byte but it does not necessarily need
- // to be decoded.
- case AM_C: // reg field of ModR/M selects a control register
- case AM_D: // reg field of ModR/M selects a debug register
- case AM_G: // reg field of ModR/M selects a general register
- case AM_P: // reg field of ModR/M selects an MMX register
- case AM_R: // mod field of ModR/M may refer only to a general register
- case AM_S: // reg field of ModR/M selects a segment register
- case AM_T: // reg field of ModR/M selects a test register
- case AM_V: // reg field of ModR/M selects a 128-bit XMM register
- have_modrm_ = true;
- break;
-
- // In these addressing modes, there is a ModR/M byte and it needs to be
- // decoded. No other (e.g. immediate) params than indicated in ModR/M.
- case AM_E: // Operand is either a general-purpose register or memory,
- // specified by ModR/M byte
- case AM_M: // ModR/M byte will refer only to memory
- case AM_Q: // Operand is either an MMX register or memory (complex
- // evaluation), specified by ModR/M byte
- case AM_W: // Operand is either a 128-bit XMM register or memory (complex
- // eval), specified by ModR/M byte
- have_modrm_ = true;
- should_decode_modrm_ = true;
- break;
-
- // These addressing modes specify an immediate or an offset value
- // directly, so we need to look at the operand type to see how many
- // bytes.
- case AM_I: // Immediate data.
- case AM_J: // Jump to offset.
- case AM_O: // Operand is at offset.
- switch (flag_operand & OT_MASK) {
- case OT_B: // Byte regardless of operand-size attribute.
- operand_bytes_ += OS_BYTE;
- break;
- case OT_C: // Byte or word, depending on operand-size attribute.
- if (operand_is_32_bits_)
- operand_bytes_ += OS_WORD;
- else
- operand_bytes_ += OS_BYTE;
- break;
- case OT_D: // Doubleword, regardless of operand-size attribute.
- operand_bytes_ += OS_DOUBLE_WORD;
- break;
- case OT_DQ: // Double-quadword, regardless of operand-size attribute.
- operand_bytes_ += OS_DOUBLE_QUAD_WORD;
- break;
- case OT_P: // 32-bit or 48-bit pointer, depending on operand-size
- // attribute.
- if (operand_is_32_bits_)
- operand_bytes_ += OS_48_BIT_POINTER;
- else
- operand_bytes_ += OS_32_BIT_POINTER;
- break;
- case OT_PS: // 128-bit packed single-precision floating-point data.
- operand_bytes_ += OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING;
- break;
- case OT_Q: // Quadword, regardless of operand-size attribute.
- operand_bytes_ += OS_QUAD_WORD;
- break;
- case OT_S: // 6-byte pseudo-descriptor.
- operand_bytes_ += OS_PSEUDO_DESCRIPTOR;
- break;
- case OT_SD: // Scalar Double-Precision Floating-Point Value
- case OT_PD: // Unaligned packed double-precision floating point value
- operand_bytes_ += OS_DOUBLE_PRECISION_FLOATING;
- break;
- case OT_SS:
- // Scalar element of a 128-bit packed single-precision
- // floating data.
- // We simply return enItUnknown since we don't have to support
- // floating point
- succeeded = false;
- break;
- case OT_V: // Word or doubleword, depending on operand-size attribute.
- if (operand_is_32_bits_)
- operand_bytes_ += OS_DOUBLE_WORD;
- else
- operand_bytes_ += OS_WORD;
- break;
- case OT_W: // Word, regardless of operand-size attribute.
- operand_bytes_ += OS_WORD;
- break;
-
- // Can safely ignore these.
- case OT_A: // Two one-word operands in memory or two double-word
- // operands in memory
- case OT_PI: // Quadword MMX technology register (e.g. mm0)
- case OT_SI: // Doubleword integer register (e.g., eax)
- break;
-
- default:
- break;
- }
- break;
-
- default:
- break;
- }
-
- return succeeded;
-}
-
-bool MiniDisassembler::ProcessModrm(unsigned char* start_byte,
- unsigned int* size) {
- // If we don't need to decode, we just return the size of the ModR/M
- // byte (there is never a SIB byte in this case).
- if (!should_decode_modrm_) {
- (*size)++;
- return true;
- }
-
- // We never care about the reg field, only the combination of the mod
- // and r/m fields, so let's start by packing those fields together into
- // 5 bits.
- unsigned char modrm = (*start_byte);
- unsigned char mod = modrm & 0xC0; // mask out top two bits to get mod field
- modrm = modrm & 0x07; // mask out bottom 3 bits to get r/m field
- mod = mod >> 3; // shift the mod field to the right place
- modrm = mod | modrm; // combine the r/m and mod fields as discussed
- mod = mod >> 3; // shift the mod field to bits 2..0
-
- // Invariant: modrm contains the mod field in bits 4..3 and the r/m field
- // in bits 2..0, and mod contains the mod field in bits 2..0
-
- const ModrmEntry* modrm_entry = 0;
- if (address_is_32_bits_)
- modrm_entry = &s_ia32_modrm_map_[modrm];
- else
- modrm_entry = &s_ia16_modrm_map_[modrm];
-
- // Invariant: modrm_entry points to information that we need to decode
- // the ModR/M byte.
-
- // Add to the count of operand bytes, if the ModR/M byte indicates
- // that some operands are encoded in the instruction.
- if (modrm_entry->is_encoded_in_instruction_)
- operand_bytes_ += modrm_entry->operand_size_;
-
- // Process the SIB byte if necessary, and return the count
- // of ModR/M and SIB bytes.
- if (modrm_entry->use_sib_byte_) {
- (*size)++;
- return ProcessSib(start_byte + 1, mod, size);
- } else {
- (*size)++;
- return true;
- }
-}
-
-bool MiniDisassembler::ProcessSib(unsigned char* start_byte,
- unsigned char mod,
- unsigned int* size) {
- // get the mod field from the 2..0 bits of the SIB byte
- unsigned char sib_base = (*start_byte) & 0x07;
- if (0x05 == sib_base) {
- switch (mod) {
- case 0x00: // mod == 00
- case 0x02: // mod == 10
- operand_bytes_ += OS_DOUBLE_WORD;
- break;
- case 0x01: // mod == 01
- operand_bytes_ += OS_BYTE;
- break;
- case 0x03: // mod == 11
- // According to the IA-32 docs, there does not seem to be a disp
- // value for this value of mod
- default:
- break;
- }
- }
-
- (*size)++;
- return true;
-}
-
-}; // namespace sidestep
diff --git a/sandbox/win/src/sidestep/mini_disassembler.h b/sandbox/win/src/sidestep/mini_disassembler.h
deleted file mode 100644
index 202c4ec..0000000
--- a/sandbox/win/src/sidestep/mini_disassembler.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Definition of MiniDisassembler.
-
-#ifndef SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__
-#define SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__
-
-#include "sandbox/win/src/sidestep/mini_disassembler_types.h"
-
-namespace sidestep {
-
-// This small disassembler is very limited
-// in its functionality, and in fact does only the bare minimum required by the
-// preamble patching utility. It may be useful for other purposes, however.
-//
-// The limitations include at least the following:
-// -# No support for coprocessor opcodes, MMX, etc.
-// -# No machine-readable identification of opcodes or decoding of
-// assembly parameters. The name of the opcode (as a string) is given,
-// however, to aid debugging.
-//
-// You may ask what this little disassembler actually does, then? The answer is
-// that it does the following, which is exactly what the patching utility needs:
-// -# Indicates if opcode is a jump (any kind) or a return (any kind)
-// because this is important for the patching utility to determine if
-// a function is too short or there are jumps too early in it for it
-// to be preamble patched.
-// -# The opcode length is always calculated, so that the patching utility
-// can figure out where the next instruction starts, and whether it
-// already has enough instructions to replace with the absolute jump
-// to the patching code.
-//
-// The usage is quite simple; just create a MiniDisassembler and use its
-// Disassemble() method.
-//
-// If you would like to extend this disassembler, please refer to the
-// IA-32 Intel Architecture Software Developer's Manual Volume 2:
-// Instruction Set Reference for information about operand decoding
-// etc.
-class MiniDisassembler {
- public:
-
- // Creates a new instance and sets defaults.
- //
- // operand_default_32_bits: If true, the default operand size is
- // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits.
- // address_default_32_bits: If true, the default address size is
- // set to 32 bits, which is the default under Win32. Otherwise it is 16 bits.
- MiniDisassembler(bool operand_default_32_bits,
- bool address_default_32_bits);
-
- // Equivalent to MiniDisassembler(true, true);
- MiniDisassembler();
-
- // Attempts to disassemble a single instruction starting from the
- // address in memory it is pointed to.
- //
- // start: Address where disassembly should start.
- // instruction_bytes: Variable that will be incremented by
- // the length in bytes of the instruction.
- // Returns enItJump, enItReturn or enItGeneric on success. enItUnknown
- // if unable to disassemble, enItUnused if this seems to be an unused
- // opcode. In the last two (error) cases, cbInstruction will be set
- // to 0xffffffff.
- //
- // Postcondition: This instance of the disassembler is ready to be used again,
- // with unchanged defaults from creation time.
- InstructionType Disassemble(unsigned char* start,
- unsigned int* instruction_bytes);
-
- private:
-
- // Makes the disassembler ready for reuse.
- void Initialize();
-
- // Sets the flags for address and operand sizes.
- // Returns Number of prefix bytes.
- InstructionType ProcessPrefixes(unsigned char* start, unsigned int* size);
-
- // Sets the flag for whether we have ModR/M, and increments
- // operand_bytes_ if any are specifies by the opcode directly.
- // Returns Number of opcode bytes.
- InstructionType ProcessOpcode(unsigned char* start,
- unsigned int table,
- unsigned int* size);
-
- // Checks the type of the supplied operand. Increments
- // operand_bytes_ if it directly indicates an immediate etc.
- // operand. Asserts have_modrm_ if the operand specifies
- // a ModR/M byte.
- bool ProcessOperand(int flag_operand);
-
- // Increments operand_bytes_ by size specified by ModR/M and
- // by SIB if present.
- // Returns 0 in case of error, 1 if there is just a ModR/M byte,
- // 2 if there is a ModR/M byte and a SIB byte.
- bool ProcessModrm(unsigned char* start, unsigned int* size);
-
- // Processes the SIB byte that it is pointed to.
- // start: Pointer to the SIB byte.
- // mod: The mod field from the ModR/M byte.
- // Returns 1 to indicate success (indicates 1 SIB byte)
- bool ProcessSib(unsigned char* start, unsigned char mod, unsigned int* size);
-
- // The instruction type we have decoded from the opcode.
- InstructionType instruction_type_;
-
- // Counts the number of bytes that is occupied by operands in
- // the current instruction (note: we don't care about how large
- // operands stored in registers etc. are).
- unsigned int operand_bytes_;
-
- // True iff there is a ModR/M byte in this instruction.
- bool have_modrm_;
-
- // True iff we need to decode the ModR/M byte (sometimes it just
- // points to a register, we can tell by the addressing mode).
- bool should_decode_modrm_;
-
- // Current operand size is 32 bits if true, 16 bits if false.
- bool operand_is_32_bits_;
-
- // Default operand size is 32 bits if true, 16 bits if false.
- bool operand_default_is_32_bits_;
-
- // Current address size is 32 bits if true, 16 bits if false.
- bool address_is_32_bits_;
-
- // Default address size is 32 bits if true, 16 bits if false.
- bool address_default_is_32_bits_;
-
- // Huge big opcode table based on the IA-32 manual, defined
- // in Ia32OpcodeMap.cpp
- static const OpcodeTable s_ia32_opcode_map_[];
-
- // Somewhat smaller table to help with decoding ModR/M bytes
- // when 16-bit addressing mode is being used. Defined in
- // Ia32ModrmMap.cpp
- static const ModrmEntry s_ia16_modrm_map_[];
-
- // Somewhat smaller table to help with decoding ModR/M bytes
- // when 32-bit addressing mode is being used. Defined in
- // Ia32ModrmMap.cpp
- static const ModrmEntry s_ia32_modrm_map_[];
-
- // Indicators of whether we got certain prefixes that certain
- // silly Intel instructions depend on in nonstandard ways for
- // their behaviors.
- bool got_f2_prefix_, got_f3_prefix_, got_66_prefix_;
-};
-
-}; // namespace sidestep
-
-#endif // SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_H__
diff --git a/sandbox/win/src/sidestep/mini_disassembler_types.h b/sandbox/win/src/sidestep/mini_disassembler_types.h
deleted file mode 100644
index 1c10626..0000000
--- a/sandbox/win/src/sidestep/mini_disassembler_types.h
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Several simple types used by the disassembler and some of the patching
-// mechanisms.
-
-#ifndef SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__
-#define SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__
-
-namespace sidestep {
-
-// Categories of instructions that we care about
-enum InstructionType {
- // This opcode is not used
- IT_UNUSED,
- // This disassembler does not recognize this opcode (error)
- IT_UNKNOWN,
- // This is not an instruction but a reference to another table
- IT_REFERENCE,
- // This byte is a prefix byte that we can ignore
- IT_PREFIX,
- // This is a prefix byte that switches to the nondefault address size
- IT_PREFIX_ADDRESS,
- // This is a prefix byte that switches to the nondefault operand size
- IT_PREFIX_OPERAND,
- // A jump or call instruction
- IT_JUMP,
- // A return instruction
- IT_RETURN,
- // Any other type of instruction (in this case we don't care what it is)
- IT_GENERIC,
-};
-
-// Lists IA-32 operand sizes in multiples of 8 bits
-enum OperandSize {
- OS_ZERO = 0,
- OS_BYTE = 1,
- OS_WORD = 2,
- OS_DOUBLE_WORD = 4,
- OS_QUAD_WORD = 8,
- OS_DOUBLE_QUAD_WORD = 16,
- OS_32_BIT_POINTER = 32/8,
- OS_48_BIT_POINTER = 48/8,
- OS_SINGLE_PRECISION_FLOATING = 32/8,
- OS_DOUBLE_PRECISION_FLOATING = 64/8,
- OS_DOUBLE_EXTENDED_PRECISION_FLOATING = 80/8,
- OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING = 128/8,
- OS_PSEUDO_DESCRIPTOR = 6
-};
-
-// Operand addressing methods from the IA-32 manual. The enAmMask value
-// is a mask for the rest. The other enumeration values are named for the
-// names given to the addressing methods in the manual, e.g. enAm_D is for
-// the D addressing method.
-//
-// The reason we use a full 4 bytes and a mask, is that we need to combine
-// these flags with the enOperandType to store the details
-// on the operand in a single integer.
-enum AddressingMethod {
- AM_NOT_USED = 0, // This operand is not used for this instruction
- AM_MASK = 0x00FF0000, // Mask for the rest of the values in this enumeration
- AM_A = 0x00010000, // A addressing type
- AM_C = 0x00020000, // C addressing type
- AM_D = 0x00030000, // D addressing type
- AM_E = 0x00040000, // E addressing type
- AM_F = 0x00050000, // F addressing type
- AM_G = 0x00060000, // G addressing type
- AM_I = 0x00070000, // I addressing type
- AM_J = 0x00080000, // J addressing type
- AM_M = 0x00090000, // M addressing type
- AM_O = 0x000A0000, // O addressing type
- AM_P = 0x000B0000, // P addressing type
- AM_Q = 0x000C0000, // Q addressing type
- AM_R = 0x000D0000, // R addressing type
- AM_S = 0x000E0000, // S addressing type
- AM_T = 0x000F0000, // T addressing type
- AM_V = 0x00100000, // V addressing type
- AM_W = 0x00110000, // W addressing type
- AM_X = 0x00120000, // X addressing type
- AM_Y = 0x00130000, // Y addressing type
- AM_REGISTER = 0x00140000, // Specific register is always used as this op
- AM_IMPLICIT = 0x00150000, // An implicit, fixed value is used
-};
-
-// Operand types from the IA-32 manual. The enOtMask value is
-// a mask for the rest. The rest of the values are named for the
-// names given to these operand types in the manual, e.g. enOt_ps
-// is for the ps operand type in the manual.
-//
-// The reason we use a full 4 bytes and a mask, is that we need
-// to combine these flags with the enAddressingMethod to store the details
-// on the operand in a single integer.
-enum OperandType {
- OT_MASK = 0xFF000000,
- OT_A = 0x01000000,
- OT_B = 0x02000000,
- OT_C = 0x03000000,
- OT_D = 0x04000000,
- OT_DQ = 0x05000000,
- OT_P = 0x06000000,
- OT_PI = 0x07000000,
- OT_PS = 0x08000000, // actually unsupported for (we don't know its size)
- OT_Q = 0x09000000,
- OT_S = 0x0A000000,
- OT_SS = 0x0B000000,
- OT_SI = 0x0C000000,
- OT_V = 0x0D000000,
- OT_W = 0x0E000000,
- OT_SD = 0x0F000000, // scalar double-precision floating-point value
- OT_PD = 0x10000000, // double-precision floating point
- // dummy "operand type" for address mode M - which doesn't specify
- // operand type
- OT_ADDRESS_MODE_M = 0x80000000
-};
-
-// Everything that's in an Opcode (see below) except the three
-// alternative opcode structs for different prefixes.
-struct SpecificOpcode {
- // Index to continuation table, or 0 if this is the last
- // byte in the opcode.
- int table_index_;
-
- // The opcode type
- InstructionType type_;
-
- // Description of the type of the dest, src and aux operands,
- // put together from an enOperandType flag and an enAddressingMethod
- // flag.
- int flag_dest_;
- int flag_source_;
- int flag_aux_;
-
- // We indicate the mnemonic for debugging purposes
- const char* mnemonic_;
-};
-
-// The information we keep in our tables about each of the different
-// valid instructions recognized by the IA-32 architecture.
-struct Opcode {
- // Index to continuation table, or 0 if this is the last
- // byte in the opcode.
- int table_index_;
-
- // The opcode type
- InstructionType type_;
-
- // Description of the type of the dest, src and aux operands,
- // put together from an enOperandType flag and an enAddressingMethod
- // flag.
- int flag_dest_;
- int flag_source_;
- int flag_aux_;
-
- // We indicate the mnemonic for debugging purposes
- const char* mnemonic_;
-
- // Alternative opcode info if certain prefixes are specified.
- // In most cases, all of these are zeroed-out. Only used if
- // bPrefixDependent is true.
- bool is_prefix_dependent_;
- SpecificOpcode opcode_if_f2_prefix_;
- SpecificOpcode opcode_if_f3_prefix_;
- SpecificOpcode opcode_if_66_prefix_;
-};
-
-// Information about each table entry.
-struct OpcodeTable {
- // Table of instruction entries
- const Opcode* table_;
- // How many bytes left to shift ModR/M byte <b>before</b> applying mask
- unsigned char shift_;
- // Mask to apply to byte being looked at before comparing to table
- unsigned char mask_;
- // Minimum/maximum indexes in table.
- unsigned char min_lim_;
- unsigned char max_lim_;
-};
-
-// Information about each entry in table used to decode ModR/M byte.
-struct ModrmEntry {
- // Is the operand encoded as bytes in the instruction (rather than
- // if it's e.g. a register in which case it's just encoded in the
- // ModR/M byte)
- bool is_encoded_in_instruction_;
-
- // Is there a SIB byte? In this case we always need to decode it.
- bool use_sib_byte_;
-
- // What is the size of the operand (only important if it's encoded
- // in the instruction)?
- OperandSize operand_size_;
-};
-
-}; // namespace sidestep
-
-#endif // SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__
diff --git a/sandbox/win/src/sidestep/preamble_patcher.h b/sandbox/win/src/sidestep/preamble_patcher.h
deleted file mode 100644
index 18cf7f8..0000000
--- a/sandbox/win/src/sidestep/preamble_patcher.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Definition of PreamblePatcher
-
-#ifndef SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__
-#define SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__
-
-namespace sidestep {
-
-// Maximum size of the preamble stub. We overwrite at least the first 5
-// bytes of the function. Considering the worst case scenario, we need 4
-// bytes + the max instruction size + 5 more bytes for our jump back to
-// the original code. With that in mind, 32 is a good number :)
-const size_t kMaxPreambleStubSize = 32;
-
-// Possible results of patching/unpatching
-enum SideStepError {
- SIDESTEP_SUCCESS = 0,
- SIDESTEP_INVALID_PARAMETER,
- SIDESTEP_INSUFFICIENT_BUFFER,
- SIDESTEP_JUMP_INSTRUCTION,
- SIDESTEP_FUNCTION_TOO_SMALL,
- SIDESTEP_UNSUPPORTED_INSTRUCTION,
- SIDESTEP_NO_SUCH_MODULE,
- SIDESTEP_NO_SUCH_FUNCTION,
- SIDESTEP_ACCESS_DENIED,
- SIDESTEP_UNEXPECTED,
-};
-
-// Implements a patching mechanism that overwrites the first few bytes of
-// a function preamble with a jump to our hook function, which is then
-// able to call the original function via a specially-made preamble-stub
-// that imitates the action of the original preamble.
-//
-// Note that there are a number of ways that this method of patching can
-// fail. The most common are:
-// - If there is a jump (jxx) instruction in the first 5 bytes of
-// the function being patched, we cannot patch it because in the
-// current implementation we do not know how to rewrite relative
-// jumps after relocating them to the preamble-stub. Note that
-// if you really really need to patch a function like this, it
-// would be possible to add this functionality (but at some cost).
-// - If there is a return (ret) instruction in the first 5 bytes
-// we cannot patch the function because it may not be long enough
-// for the jmp instruction we use to inject our patch.
-// - If there is another thread currently executing within the bytes
-// that are copied to the preamble stub, it will crash in an undefined
-// way.
-//
-// If you get any other error than the above, you're either pointing the
-// patcher at an invalid instruction (e.g. into the middle of a multi-
-// byte instruction, or not at memory containing executable instructions)
-// or, there may be a bug in the disassembler we use to find
-// instruction boundaries.
-class PreamblePatcher {
- public:
- // Patches target_function to point to replacement_function using a provided
- // preamble_stub of stub_size bytes.
- // Returns An error code indicating the result of patching.
- template <class T>
- static SideStepError Patch(T target_function, T replacement_function,
- void* preamble_stub, size_t stub_size) {
- return RawPatchWithStub(target_function, replacement_function,
- reinterpret_cast<unsigned char*>(preamble_stub),
- stub_size, NULL);
- }
-
- private:
-
- // Patches a function by overwriting its first few bytes with
- // a jump to a different function. This is similar to the RawPatch
- // function except that it uses the stub allocated by the caller
- // instead of allocating it.
- //
- // To use this function, you first have to call VirtualProtect to make the
- // target function writable at least for the duration of the call.
- //
- // target_function: A pointer to the function that should be
- // patched.
- //
- // replacement_function: A pointer to the function that should
- // replace the target function. The replacement function must have
- // exactly the same calling convention and parameters as the original
- // function.
- //
- // preamble_stub: A pointer to a buffer where the preamble stub
- // should be copied. The size of the buffer should be sufficient to
- // hold the preamble bytes.
- //
- // stub_size: Size in bytes of the buffer allocated for the
- // preamble_stub
- //
- // bytes_needed: Pointer to a variable that receives the minimum
- // number of bytes required for the stub. Can be set to NULL if you're
- // not interested.
- //
- // Returns An error code indicating the result of patching.
- static SideStepError RawPatchWithStub(void* target_function,
- void *replacement_function,
- unsigned char* preamble_stub,
- size_t stub_size,
- size_t* bytes_needed);
-};
-
-}; // namespace sidestep
-
-#endif // SANDBOX_SRC_SIDESTEP_PREAMBLE_PATCHER_H__
diff --git a/sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp b/sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp
deleted file mode 100644
index 999d76b..0000000
--- a/sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implementation of PreamblePatcher
-
-#include "sandbox/win/src/sidestep/preamble_patcher.h"
-
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/sidestep/mini_disassembler.h"
-
-// Definitions of assembly statements we need
-#define ASM_JMP32REL 0xE9
-#define ASM_INT3 0xCC
-
-namespace {
-
-// Very basic memcpy. We are copying 4 to 12 bytes most of the time, so there
-// is no attempt to optimize this code or have a general purpose function.
-// We don't want to call the crt from this code.
-inline void* RawMemcpy(void* destination, const void* source, size_t bytes) {
- const char* from = reinterpret_cast<const char*>(source);
- char* to = reinterpret_cast<char*>(destination);
-
- for (size_t i = 0; i < bytes ; i++)
- to[i] = from[i];
-
- return destination;
-}
-
-// Very basic memset. We are filling 1 to 7 bytes most of the time, so there
-// is no attempt to optimize this code or have a general purpose function.
-// We don't want to call the crt from this code.
-inline void* RawMemset(void* destination, int value, size_t bytes) {
- char* to = reinterpret_cast<char*>(destination);
-
- for (size_t i = 0; i < bytes ; i++)
- to[i] = static_cast<char>(value);
-
- return destination;
-}
-
-} // namespace
-
-#define ASSERT(a, b) DCHECK_NT(a)
-
-namespace sidestep {
-
-SideStepError PreamblePatcher::RawPatchWithStub(
- void* target_function,
- void* replacement_function,
- unsigned char* preamble_stub,
- size_t stub_size,
- size_t* bytes_needed) {
- if ((NULL == target_function) ||
- (NULL == replacement_function) ||
- (NULL == preamble_stub)) {
- ASSERT(false, (L"Invalid parameters - either pTargetFunction or "
- L"pReplacementFunction or pPreambleStub were NULL."));
- return SIDESTEP_INVALID_PARAMETER;
- }
-
- // TODO(V7:joi) Siggi and I just had a discussion and decided that both
- // patching and unpatching are actually unsafe. We also discussed a
- // method of making it safe, which is to freeze all other threads in the
- // process, check their thread context to see if their eip is currently
- // inside the block of instructions we need to copy to the stub, and if so
- // wait a bit and try again, then unfreeze all threads once we've patched.
- // Not implementing this for now since we're only using SideStep for unit
- // testing, but if we ever use it for production code this is what we
- // should do.
- //
- // NOTE: Stoyan suggests we can write 8 or even 10 bytes atomically using
- // FPU instructions, and on newer processors we could use cmpxchg8b or
- // cmpxchg16b. So it might be possible to do the patching/unpatching
- // atomically and avoid having to freeze other threads. Note though, that
- // doing it atomically does not help if one of the other threads happens
- // to have its eip in the middle of the bytes you change while you change
- // them.
- unsigned char* target = reinterpret_cast<unsigned char*>(target_function);
-
- // Let's disassemble the preamble of the target function to see if we can
- // patch, and to see how much of the preamble we need to take. We need 5
- // bytes for our jmp instruction, so let's find the minimum number of
- // instructions to get 5 bytes.
- MiniDisassembler disassembler;
- unsigned int preamble_bytes = 0;
- while (preamble_bytes < 5) {
- InstructionType instruction_type =
- disassembler.Disassemble(target + preamble_bytes, &preamble_bytes);
- if (IT_JUMP == instruction_type) {
- ASSERT(false, (L"Unable to patch because there is a jump instruction "
- L"in the first 5 bytes."));
- return SIDESTEP_JUMP_INSTRUCTION;
- } else if (IT_RETURN == instruction_type) {
- ASSERT(false, (L"Unable to patch because function is too short"));
- return SIDESTEP_FUNCTION_TOO_SMALL;
- } else if (IT_GENERIC != instruction_type) {
- ASSERT(false, (L"Disassembler encountered unsupported instruction "
- L"(either unused or unknown"));
- return SIDESTEP_UNSUPPORTED_INSTRUCTION;
- }
- }
-
- if (NULL != bytes_needed)
- *bytes_needed = preamble_bytes + 5;
-
- // Inv: preamble_bytes is the number of bytes (at least 5) that we need to
- // take from the preamble to have whole instructions that are 5 bytes or more
- // in size total. The size of the stub required is cbPreamble + size of
- // jmp (5)
- if (preamble_bytes + 5 > stub_size) {
- NOTREACHED_NT();
- return SIDESTEP_INSUFFICIENT_BUFFER;
- }
-
- // First, copy the preamble that we will overwrite.
- RawMemcpy(reinterpret_cast<void*>(preamble_stub),
- reinterpret_cast<void*>(target), preamble_bytes);
-
- // Now, make a jmp instruction to the rest of the target function (minus the
- // preamble bytes we moved into the stub) and copy it into our preamble-stub.
- // find address to jump to, relative to next address after jmp instruction
-#pragma warning(push)
-#pragma warning(disable:4244)
- // This assignment generates a warning because it is 32 bit specific.
- int relative_offset_to_target_rest
- = ((reinterpret_cast<unsigned char*>(target) + preamble_bytes) -
- (preamble_stub + preamble_bytes + 5));
-#pragma warning(pop)
- // jmp (Jump near, relative, displacement relative to next instruction)
- preamble_stub[preamble_bytes] = ASM_JMP32REL;
- // copy the address
- RawMemcpy(reinterpret_cast<void*>(preamble_stub + preamble_bytes + 1),
- reinterpret_cast<void*>(&relative_offset_to_target_rest), 4);
-
- // Inv: preamble_stub points to assembly code that will execute the
- // original function by first executing the first cbPreamble bytes of the
- // preamble, then jumping to the rest of the function.
-
- // Overwrite the first 5 bytes of the target function with a jump to our
- // replacement function.
- // (Jump near, relative, displacement relative to next instruction)
- target[0] = ASM_JMP32REL;
-
- // Find offset from instruction after jmp, to the replacement function.
-#pragma warning(push)
-#pragma warning(disable:4244)
- int offset_to_replacement_function =
- reinterpret_cast<unsigned char*>(replacement_function) -
- reinterpret_cast<unsigned char*>(target) - 5;
-#pragma warning(pop)
- // complete the jmp instruction
- RawMemcpy(reinterpret_cast<void*>(target + 1),
- reinterpret_cast<void*>(&offset_to_replacement_function), 4);
- // Set any remaining bytes that were moved to the preamble-stub to INT3 so
- // as not to cause confusion (otherwise you might see some strange
- // instructions if you look at the disassembly, or even invalid
- // instructions). Also, by doing this, we will break into the debugger if
- // some code calls into this portion of the code. If this happens, it
- // means that this function cannot be patched using this patcher without
- // further thought.
- if (preamble_bytes > 5) {
- RawMemset(reinterpret_cast<void*>(target + 5), ASM_INT3,
- preamble_bytes - 5);
- }
-
- // Inv: The memory pointed to by target_function now points to a relative
- // jump instruction that jumps over to the preamble_stub. The preamble
- // stub contains the first stub_size bytes of the original target
- // function's preamble code, followed by a relative jump back to the next
- // instruction after the first cbPreamble bytes.
-
- return SIDESTEP_SUCCESS;
-}
-
-}; // namespace sidestep
-
-#undef ASSERT
diff --git a/sandbox/win/src/sidestep_resolver.cc b/sandbox/win/src/sidestep_resolver.cc
deleted file mode 100644
index 47c0f56..0000000
--- a/sandbox/win/src/sidestep_resolver.cc
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/sidestep_resolver.h"
-
-#include "base/win/pe_image.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/sidestep/preamble_patcher.h"
-
-namespace {
-
-const size_t kSizeOfSidestepStub = sidestep::kMaxPreambleStubSize;
-
-struct SidestepThunk {
- char sidestep[kSizeOfSidestepStub]; // Storage for the sidestep stub.
- int internal_thunk; // Dummy member to the beginning of the internal thunk.
-};
-
-struct SmartThunk {
- const void* module_base; // Target module's base.
- const void* interceptor; // Real interceptor.
- SidestepThunk sidestep; // Standard sidestep thunk.
-};
-
-} // namespace
-
-namespace sandbox {
-
-NTSTATUS SidestepResolverThunk::Setup(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes,
- size_t* storage_used) {
- NTSTATUS ret = Init(target_module, interceptor_module, target_name,
- interceptor_name, interceptor_entry_point,
- thunk_storage, storage_bytes);
- if (!NT_SUCCESS(ret))
- return ret;
-
- SidestepThunk* thunk = reinterpret_cast<SidestepThunk*>(thunk_storage);
-
- size_t internal_bytes = storage_bytes - kSizeOfSidestepStub;
- if (!SetInternalThunk(&thunk->internal_thunk, internal_bytes, thunk_storage,
- interceptor_))
- return STATUS_BUFFER_TOO_SMALL;
-
- AutoProtectMemory memory;
- memory.ChangeProtection(target_, kSizeOfSidestepStub, PAGE_READWRITE);
-
- sidestep::SideStepError rv = sidestep::PreamblePatcher::Patch(
- target_, reinterpret_cast<void*>(&thunk->internal_thunk), thunk_storage,
- kSizeOfSidestepStub);
-
- if (sidestep::SIDESTEP_INSUFFICIENT_BUFFER == rv)
- return STATUS_BUFFER_TOO_SMALL;
-
- if (sidestep::SIDESTEP_SUCCESS != rv)
- return STATUS_UNSUCCESSFUL;
-
- if (storage_used)
- *storage_used = GetThunkSize();
-
- return ret;
-}
-
-size_t SidestepResolverThunk::GetThunkSize() const {
- return GetInternalThunkSize() + kSizeOfSidestepStub;
-}
-
-// This is basically a wrapper around the normal sidestep patch that extends
-// the thunk to use a chained interceptor. It uses the fact that
-// SetInternalThunk generates the code to pass as the first parameter whatever
-// it receives as original_function; we let SidestepResolverThunk set this value
-// to its saved code, and then we change it to our thunk data.
-NTSTATUS SmartSidestepResolverThunk::Setup(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes,
- size_t* storage_used) {
- if (storage_bytes < GetThunkSize())
- return STATUS_BUFFER_TOO_SMALL;
-
- SmartThunk* thunk = reinterpret_cast<SmartThunk*>(thunk_storage);
- thunk->module_base = target_module;
-
- NTSTATUS ret;
- if (interceptor_entry_point) {
- thunk->interceptor = interceptor_entry_point;
- } else {
- ret = ResolveInterceptor(interceptor_module, interceptor_name,
- &thunk->interceptor);
- if (!NT_SUCCESS(ret))
- return ret;
- }
-
- // Perform a standard sidestep patch on the last part of the thunk, but point
- // to our internal smart interceptor.
- size_t standard_bytes = storage_bytes - offsetof(SmartThunk, sidestep);
- ret = SidestepResolverThunk::Setup(target_module, interceptor_module,
- target_name, NULL, &SmartStub,
- &thunk->sidestep, standard_bytes, NULL);
- if (!NT_SUCCESS(ret))
- return ret;
-
- // Fix the internal thunk to pass the whole buffer to the interceptor.
- SetInternalThunk(&thunk->sidestep.internal_thunk, GetInternalThunkSize(),
- thunk_storage, &SmartStub);
-
- if (storage_used)
- *storage_used = GetThunkSize();
-
- return ret;
-}
-
-size_t SmartSidestepResolverThunk::GetThunkSize() const {
- return GetInternalThunkSize() + kSizeOfSidestepStub +
- offsetof(SmartThunk, sidestep);
-}
-
-// This code must basically either call the intended interceptor or skip the
-// call and invoke instead the original function. In any case, we are saving
-// the registers that may be trashed by our c++ code.
-//
-// This function is called with a first parameter inserted by us, that points
-// to our SmartThunk. When we call the interceptor we have to replace this
-// parameter with the one expected by that function (stored inside our
-// structure); on the other hand, when we skip the interceptor we have to remove
-// that extra argument before calling the original function.
-//
-// When we skip the interceptor, the transformation of the stack looks like:
-// On Entry: On Use: On Exit:
-// [param 2] = first real argument [param 2] (esp+1c) [param 2]
-// [param 1] = our SmartThunk [param 1] (esp+18) [ret address]
-// [ret address] = real caller [ret address] (esp+14) [xxx]
-// [xxx] [addr to jump to] (esp+10) [xxx]
-// [xxx] [saved eax] [xxx]
-// [xxx] [saved ebx] [xxx]
-// [xxx] [saved ecx] [xxx]
-// [xxx] [saved edx] [xxx]
-__declspec(naked)
-void SmartSidestepResolverThunk::SmartStub() {
- __asm {
- push eax // Space for the jump.
- push eax // Save registers.
- push ebx
- push ecx
- push edx
- mov ebx, [esp + 0x18] // First parameter = SmartThunk.
- mov edx, [esp + 0x14] // Get the return address.
- mov eax, [ebx]SmartThunk.module_base
- push edx
- push eax
- call SmartSidestepResolverThunk::IsInternalCall
- add esp, 8
-
- test eax, eax
- lea edx, [ebx]SmartThunk.sidestep // The original function.
- jz call_interceptor
-
- // Skip this call
- mov ecx, [esp + 0x14] // Return address.
- mov [esp + 0x18], ecx // Remove first parameter.
- mov [esp + 0x10], edx
- pop edx // Restore registers.
- pop ecx
- pop ebx
- pop eax
- ret 4 // Jump to original function.
-
- call_interceptor:
- mov ecx, [ebx]SmartThunk.interceptor
- mov [esp + 0x18], edx // Replace first parameter.
- mov [esp + 0x10], ecx
- pop edx // Restore registers.
- pop ecx
- pop ebx
- pop eax
- ret // Jump to original function.
- }
-}
-
-bool SmartSidestepResolverThunk::IsInternalCall(const void* base,
- void* return_address) {
- DCHECK_NT(base);
- DCHECK_NT(return_address);
-
- base::win::PEImage pe(base);
- if (pe.GetImageSectionFromAddr(return_address))
- return true;
- return false;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/sidestep_resolver.h b/sandbox/win/src/sidestep_resolver.h
deleted file mode 100644
index 30d8cb3..0000000
--- a/sandbox/win/src/sidestep_resolver.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SIDESTEP_RESOLVER_H__
-#define SANDBOX_SRC_SIDESTEP_RESOLVER_H__
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/resolver.h"
-
-namespace sandbox {
-
-// This is the concrete resolver used to perform sidestep interceptions.
-class SidestepResolverThunk : public ResolverThunk {
- public:
- SidestepResolverThunk() {}
- virtual ~SidestepResolverThunk() {}
-
- // Implementation of Resolver::Setup.
- virtual NTSTATUS Setup(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes,
- size_t* storage_used);
-
- // Implementation of Resolver::GetThunkSize.
- virtual size_t GetThunkSize() const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(SidestepResolverThunk);
-};
-
-// This is the concrete resolver used to perform smart sidestep interceptions.
-// This means basically a sidestep interception that skips the interceptor when
-// the caller resides on the same dll being intercepted. It is intended as
-// a helper only, because that determination is not infallible.
-class SmartSidestepResolverThunk : public SidestepResolverThunk {
- public:
- SmartSidestepResolverThunk() {}
- virtual ~SmartSidestepResolverThunk() {}
-
- // Implementation of Resolver::Setup.
- virtual NTSTATUS Setup(const void* target_module,
- const void* interceptor_module,
- const char* target_name,
- const char* interceptor_name,
- const void* interceptor_entry_point,
- void* thunk_storage,
- size_t storage_bytes,
- size_t* storage_used);
-
- // Implementation of Resolver::GetThunkSize.
- virtual size_t GetThunkSize() const;
-
- private:
- // Performs the actual call to the interceptor if the conditions are correct
- // (as determined by IsInternalCall).
- static void SmartStub();
-
- // Returns true if return_address is inside the module loaded at base.
- static bool IsInternalCall(const void* base, void* return_address);
-
- DISALLOW_COPY_AND_ASSIGN(SmartSidestepResolverThunk);
-};
-
-} // namespace sandbox
-
-
-#endif // SANDBOX_SRC_SIDESTEP_RESOLVER_H__
diff --git a/sandbox/win/src/sync_dispatcher.cc b/sandbox/win/src/sync_dispatcher.cc
deleted file mode 100644
index eb1c1e4..0000000
--- a/sandbox/win/src/sync_dispatcher.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/sync_dispatcher.h"
-
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/interception.h"
-#include "sandbox/win/src/interceptors.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_broker.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sync_interception.h"
-#include "sandbox/win/src/sync_policy.h"
-
-namespace sandbox {
-
-SyncDispatcher::SyncDispatcher(PolicyBase* policy_base)
- : policy_base_(policy_base) {
- static const IPCCall create_params = {
- {IPC_CREATEEVENT_TAG, WCHAR_TYPE, ULONG_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(&SyncDispatcher::CreateEvent)
- };
-
- static const IPCCall open_params = {
- {IPC_OPENEVENT_TAG, WCHAR_TYPE, ULONG_TYPE, ULONG_TYPE},
- reinterpret_cast<CallbackGeneric>(&SyncDispatcher::OpenEvent)
- };
-
- ipc_calls_.push_back(create_params);
- ipc_calls_.push_back(open_params);
-}
-
-bool SyncDispatcher::SetupService(InterceptionManager* manager,
- int service) {
- if (IPC_CREATEEVENT_TAG == service)
- return INTERCEPT_EAT(manager, L"kernel32.dll", CreateEventW,
- CREATE_EVENT_ID, 20);
-
- if (IPC_OPENEVENT_TAG == service)
- return INTERCEPT_EAT(manager, L"kernel32.dll", OpenEventW,
- OPEN_EVENT_ID, 16);
-
- return false;
-}
-
-bool SyncDispatcher::CreateEvent(IPCInfo* ipc, std::wstring* name,
- DWORD manual_reset, DWORD initial_state) {
- const wchar_t* event_name = name->c_str();
- CountedParameterSet<NameBased> params;
- params[NameBased::NAME] = ParamPickerMake(event_name);
-
- EvalResult result = policy_base_->EvalPolicy(IPC_CREATEEVENT_TAG,
- params.GetBase());
- HANDLE handle = NULL;
- DWORD ret = SyncPolicy::CreateEventAction(result, *ipc->client_info, *name,
- manual_reset, initial_state,
- &handle);
- // Return operation status on the IPC.
- ipc->return_info.win32_result = ret;
- ipc->return_info.handle = handle;
- return true;
-}
-
-bool SyncDispatcher::OpenEvent(IPCInfo* ipc, std::wstring* name,
- DWORD desired_access, DWORD inherit_handle) {
- const wchar_t* event_name = name->c_str();
-
- CountedParameterSet<OpenEventParams> params;
- params[OpenEventParams::NAME] = ParamPickerMake(event_name);
- params[OpenEventParams::ACCESS] = ParamPickerMake(desired_access);
-
- EvalResult result = policy_base_->EvalPolicy(IPC_OPENEVENT_TAG,
- params.GetBase());
- HANDLE handle = NULL;
- DWORD ret = SyncPolicy::OpenEventAction(result, *ipc->client_info, *name,
- desired_access, inherit_handle,
- &handle);
- // Return operation status on the IPC.
- ipc->return_info.win32_result = ret;
- ipc->return_info.handle = handle;
- return true;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/sync_dispatcher.h b/sandbox/win/src/sync_dispatcher.h
deleted file mode 100644
index 13c8b9d3..0000000
--- a/sandbox/win/src/sync_dispatcher.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SYNC_DISPATCHER_H_
-#define SANDBOX_SRC_SYNC_DISPATCHER_H_
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/sandbox_policy_base.h"
-
-namespace sandbox {
-
-// This class handles sync-related IPC calls.
-class SyncDispatcher : public Dispatcher {
- public:
- explicit SyncDispatcher(PolicyBase* policy_base);
- ~SyncDispatcher() {}
-
- // Dispatcher interface.
- virtual bool SetupService(InterceptionManager* manager, int service);
-
-private:
- // Processes IPC requests coming from calls to CreateEvent in the target.
- bool CreateEvent(IPCInfo* ipc, std::wstring* name, DWORD manual_reset,
- DWORD initial_state);
-
- // Processes IPC requests coming from calls to OpenEvent in the target.
- bool OpenEvent(IPCInfo* ipc, std::wstring* name, DWORD desired_access,
- DWORD inherit_handle);
-
- PolicyBase* policy_base_;
- DISALLOW_COPY_AND_ASSIGN(SyncDispatcher);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_SYNC_DISPATCHER_H_
diff --git a/sandbox/win/src/sync_interception.cc b/sandbox/win/src/sync_interception.cc
deleted file mode 100644
index d235723..0000000
--- a/sandbox/win/src/sync_interception.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/sync_interception.h"
-
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/policy_target.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "sandbox/win/src/target_services.h"
-
-namespace sandbox {
-
-HANDLE WINAPI TargetCreateEventW(CreateEventWFunction orig_CreateEvent,
- LPSECURITY_ATTRIBUTES security_attributes,
- BOOL manual_reset, BOOL initial_state,
- LPCWSTR name) {
- // Check if the process can create it first.
- HANDLE handle = orig_CreateEvent(security_attributes, manual_reset,
- initial_state, name);
- DWORD original_error = ::GetLastError();
- if (NULL != handle)
- return handle;
-
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return NULL;
-
- do {
- if (security_attributes)
- break;
-
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- CountedParameterSet<NameBased> params;
- params[NameBased::NAME] = ParamPickerMake(name);
-
- if (!QueryBroker(IPC_CREATEEVENT_TAG, params.GetBase()))
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_CREATEEVENT_TAG, name, manual_reset,
- initial_state, &answer);
-
- if (SBOX_ALL_OK != code)
- break;
-
- ::SetLastError(answer.win32_result);
- return answer.handle;
- } while (false);
-
- ::SetLastError(original_error);
- return NULL;
-}
-
-// Interception of OpenEventW on the child process.
-// It should never be called directly
-HANDLE WINAPI TargetOpenEventW(OpenEventWFunction orig_OpenEvent,
- ACCESS_MASK desired_access, BOOL inherit_handle,
- LPCWSTR name) {
- // Check if the process can open it first.
- HANDLE handle = orig_OpenEvent(desired_access, inherit_handle, name);
- DWORD original_error = ::GetLastError();
- if (NULL != handle)
- return handle;
-
- // We don't trust that the IPC can work this early.
- if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
- return NULL;
-
- do {
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory)
- break;
-
- uint32 inherit_handle_ipc = inherit_handle;
- CountedParameterSet<OpenEventParams> params;
- params[OpenEventParams::NAME] = ParamPickerMake(name);
- params[OpenEventParams::ACCESS] = ParamPickerMake(desired_access);
-
- if (!QueryBroker(IPC_OPENEVENT_TAG, params.GetBase()))
- break;
-
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
- ResultCode code = CrossCall(ipc, IPC_OPENEVENT_TAG, name, desired_access,
- inherit_handle_ipc, &answer);
-
- if (SBOX_ALL_OK != code)
- break;
-
- ::SetLastError(answer.win32_result);
- return answer.handle;
- } while (false);
-
- ::SetLastError(original_error);
- return NULL;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/sync_interception.h b/sandbox/win/src/sync_interception.h
deleted file mode 100644
index 6c5c46e..0000000
--- a/sandbox/win/src/sync_interception.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-#ifndef SANDBOX_SRC_SYNC_INTERCEPTION_H__
-#define SANDBOX_SRC_SYNC_INTERCEPTION_H__
-
-namespace sandbox {
-
-extern "C" {
-
-typedef HANDLE (WINAPI *CreateEventWFunction) (
- LPSECURITY_ATTRIBUTES lpEventAttributes,
- DWORD dwDesiredAccess,
- BOOL bInheritHandle,
- LPCWSTR lpName);
-
-typedef HANDLE (WINAPI *OpenEventWFunction) (
- BOOL bManualReset,
- BOOL bInitialState,
- LPCWSTR lpName);
-
-// Interception of CreateEvent on the child process.
-SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateEventW(
- CreateEventWFunction orig_CreateEvent,
- LPSECURITY_ATTRIBUTES security_attributes, BOOL manual_reset,
- BOOL initial_state, LPCWSTR name);
-
-// Interception of OpenEvent on the child process.
-SANDBOX_INTERCEPT HANDLE WINAPI TargetOpenEventW(
- OpenEventWFunction orig_OpenEvent, ACCESS_MASK desired_access,
- BOOL inherit_handle, LPCWSTR name);
-
-} // extern "C"
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_SYNC_INTERCEPTION_H__
diff --git a/sandbox/win/src/sync_policy.cc b/sandbox/win/src/sync_policy.cc
deleted file mode 100644
index 926fc52..0000000
--- a/sandbox/win/src/sync_policy.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "sandbox/win/src/sync_policy.h"
-
-#include "base/logging.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/policy_engine_opcodes.h"
-#include "sandbox/win/src/policy_params.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/sandbox_utils.h"
-
-namespace sandbox {
-
-bool SyncPolicy::GenerateRules(const wchar_t* name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy) {
- std::wstring mod_name(name);
- if (mod_name.empty()) {
- return false;
- }
-
- if (TargetPolicy::EVENTS_ALLOW_ANY != semantics &&
- TargetPolicy::EVENTS_ALLOW_READONLY != semantics) {
- // Other flags are not valid for sync policy yet.
- NOTREACHED();
- return false;
- }
-
- // Add the open rule.
- EvalResult result = ASK_BROKER;
- PolicyRule open(result);
-
- if (!open.AddStringMatch(IF, OpenEventParams::NAME, name, CASE_INSENSITIVE))
- return false;
-
- if (TargetPolicy::EVENTS_ALLOW_READONLY == semantics) {
- // We consider all flags that are not known to be readonly as potentially
- // used for write.
- DWORD allowed_flags = SYNCHRONIZE | GENERIC_READ | READ_CONTROL;
- DWORD restricted_flags = ~allowed_flags;
- open.AddNumberMatch(IF_NOT, OpenEventParams::ACCESS, restricted_flags, AND);
- }
-
- if (!policy->AddRule(IPC_OPENEVENT_TAG, &open))
- return false;
-
- // If it's not a read only, add the create rule.
- if (TargetPolicy::EVENTS_ALLOW_READONLY != semantics) {
- PolicyRule create(result);
- if (!create.AddStringMatch(IF, NameBased::NAME, name, CASE_INSENSITIVE))
- return false;
-
- if (!policy->AddRule(IPC_CREATEEVENT_TAG, &create))
- return false;
- }
-
- return true;
-}
-
-DWORD SyncPolicy::CreateEventAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &event_name,
- uint32 manual_reset,
- uint32 initial_state,
- HANDLE *handle) {
- // The only action supported is ASK_BROKER which means create the requested
- // file as specified.
- if (ASK_BROKER != eval_result)
- return false;
-
- HANDLE local_handle = ::CreateEvent(NULL, manual_reset, initial_state,
- event_name.c_str());
- if (NULL == local_handle)
- return ::GetLastError();
-
- if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
- client_info.process, handle, 0, FALSE,
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- ::CloseHandle(local_handle);
- return ERROR_ACCESS_DENIED;
- }
- return ERROR_SUCCESS;
-}
-
-DWORD SyncPolicy::OpenEventAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &event_name,
- uint32 desired_access,
- uint32 inherit_handle,
- HANDLE *handle) {
- // The only action supported is ASK_BROKER which means create the requested
- // file as specified.
- if (ASK_BROKER != eval_result)
- return false;
-
- HANDLE local_handle = ::OpenEvent(desired_access, FALSE,
- event_name.c_str());
- if (NULL == local_handle)
- return ::GetLastError();
-
- if (!::DuplicateHandle(::GetCurrentProcess(), local_handle,
- client_info.process, handle, 0, inherit_handle,
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
- ::CloseHandle(local_handle);
- return ERROR_ACCESS_DENIED;
- }
- return ERROR_SUCCESS;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/sync_policy.h b/sandbox/win/src/sync_policy.h
deleted file mode 100644
index 2b8b422..0000000
--- a/sandbox/win/src/sync_policy.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_SYNC_POLICY_H__
-#define SANDBOX_SRC_SYNC_POLICY_H__
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/policy_low_level.h"
-#include "sandbox/win/src/sandbox_policy.h"
-
-namespace sandbox {
-
-enum EvalResult;
-
-// This class centralizes most of the knowledge related to sync policy
-class SyncPolicy {
- public:
- // Creates the required low-level policy rules to evaluate a high-level
- // policy rule for sync calls, in particular open or create actions.
- // name is the sync object name, semantics is the desired semantics for the
- // open or create and policy is the policy generator to which the rules are
- // going to be added.
- static bool GenerateRules(const wchar_t* name,
- TargetPolicy::Semantics semantics,
- LowLevelPolicy* policy);
-
- // Performs the desired policy action on a request.
- // client_info is the target process that is making the request and
- // eval_result is the desired policy action to accomplish.
- static DWORD CreateEventAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &event_name,
- uint32 manual_reset,
- uint32 initial_state,
- HANDLE *handle);
- static DWORD OpenEventAction(EvalResult eval_result,
- const ClientInfo& client_info,
- const std::wstring &event_name,
- uint32 desired_access,
- uint32 inherit_handle,
- HANDLE *handle);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_SYNC_POLICY_H__
diff --git a/sandbox/win/src/sync_policy_test.cc b/sandbox/win/src/sync_policy_test.cc
deleted file mode 100644
index 6490175..0000000
--- a/sandbox/win/src/sync_policy_test.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/win/scoped_handle.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_policy.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/tests/common/controller.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace sandbox {
-
-SBOX_TESTS_COMMAND int Event_Open(int argc, wchar_t **argv) {
- if (argc != 2)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- DWORD desired_access = SYNCHRONIZE;
- if (L'f' == argv[0][0])
- desired_access = EVENT_ALL_ACCESS;
-
- base::win::ScopedHandle event_open(::OpenEvent(
- desired_access, FALSE, argv[1]));
- DWORD error_open = ::GetLastError();
-
- if (event_open.Get())
- return SBOX_TEST_SUCCEEDED;
-
- if (ERROR_ACCESS_DENIED == error_open ||
- ERROR_BAD_PATHNAME == error_open)
- return SBOX_TEST_DENIED;
-
- return SBOX_TEST_FAILED;
-}
-
-SBOX_TESTS_COMMAND int Event_CreateOpen(int argc, wchar_t **argv) {
- if (argc < 2 || argc > 3)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- wchar_t *event_name = NULL;
- if (3 == argc)
- event_name = argv[2];
-
- BOOL manual_reset = FALSE;
- BOOL initial_state = FALSE;
- if (L't' == argv[0][0])
- manual_reset = TRUE;
- if (L't' == argv[1][0])
- initial_state = TRUE;
-
- base::win::ScopedHandle event_create(::CreateEvent(
- NULL, manual_reset, initial_state, event_name));
- DWORD error_create = ::GetLastError();
- base::win::ScopedHandle event_open;
- if (event_name)
- event_open.Set(::OpenEvent(EVENT_ALL_ACCESS, FALSE, event_name));
-
- if (event_create.Get()) {
- DWORD wait = ::WaitForSingleObject(event_create.Get(), 0);
- if (initial_state && WAIT_OBJECT_0 != wait)
- return SBOX_TEST_FAILED;
-
- if (!initial_state && WAIT_TIMEOUT != wait)
- return SBOX_TEST_FAILED;
- }
-
- if (event_name) {
- // Both event_open and event_create have to be valid.
- if (event_open.Get() && event_create)
- return SBOX_TEST_SUCCEEDED;
-
- if (event_open.Get() && !event_create || !event_open.Get() && event_create)
- return SBOX_TEST_FAILED;
- } else {
- // Only event_create has to be valid.
- if (event_create.Get())
- return SBOX_TEST_SUCCEEDED;
- }
-
- if (ERROR_ACCESS_DENIED == error_create ||
- ERROR_BAD_PATHNAME == error_create)
- return SBOX_TEST_DENIED;
-
- return SBOX_TEST_FAILED;
-}
-
-// Tests the creation of events using all the possible combinations.
-TEST(SyncPolicyTest, TestEvent) {
- TestRunner runner;
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_SYNC,
- TargetPolicy::EVENTS_ALLOW_ANY,
- L"test1"));
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_SYNC,
- TargetPolicy::EVENTS_ALLOW_ANY,
- L"test2"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_CreateOpen f f"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_CreateOpen t f"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_CreateOpen f t"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_CreateOpen t t"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_CreateOpen f f test1"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_CreateOpen t f test2"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_CreateOpen f t test1"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_CreateOpen t t test2"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_CreateOpen f f test3"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_CreateOpen t f test4"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_CreateOpen f t test3"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_CreateOpen t t test4"));
-}
-
-// Tests opening events with read only access.
-TEST(SyncPolicyTest, TestEventReadOnly) {
- TestRunner runner;
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_SYNC,
- TargetPolicy::EVENTS_ALLOW_READONLY,
- L"test1"));
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_SYNC,
- TargetPolicy::EVENTS_ALLOW_READONLY,
- L"test2"));
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_SYNC,
- TargetPolicy::EVENTS_ALLOW_READONLY,
- L"test5"));
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_SYNC,
- TargetPolicy::EVENTS_ALLOW_READONLY,
- L"test6"));
-
- base::win::ScopedHandle handle1(::CreateEvent(NULL, FALSE, FALSE, L"test1"));
- base::win::ScopedHandle handle2(::CreateEvent(NULL, FALSE, FALSE, L"test2"));
- base::win::ScopedHandle handle3(::CreateEvent(NULL, FALSE, FALSE, L"test3"));
- base::win::ScopedHandle handle4(::CreateEvent(NULL, FALSE, FALSE, L"test4"));
-
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_CreateOpen f f"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_CreateOpen t f"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_Open f test1"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Event_Open s test2"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_Open f test3"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_Open s test4"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_CreateOpen f f test5"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_CreateOpen t f test6"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_CreateOpen f t test5"));
- EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Event_CreateOpen t t test6"));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/target_interceptions.cc b/sandbox/win/src/target_interceptions.cc
deleted file mode 100644
index e6b0dcf..0000000
--- a/sandbox/win/src/target_interceptions.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/target_interceptions.h"
-
-#include "sandbox/win/src/interception_agent.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-#include "sandbox/win/src/target_services.h"
-
-namespace sandbox {
-
-SANDBOX_INTERCEPT NtExports g_nt;
-
-// Hooks NtMapViewOfSection to detect the load of DLLs. If hot patching is
-// required for this dll, this functions patches it.
-NTSTATUS WINAPI TargetNtMapViewOfSection(
- NtMapViewOfSectionFunction orig_MapViewOfSection, HANDLE section,
- HANDLE process, PVOID *base, ULONG_PTR zero_bits, SIZE_T commit_size,
- PLARGE_INTEGER offset, PSIZE_T view_size, SECTION_INHERIT inherit,
- ULONG allocation_type, ULONG protect) {
- NTSTATUS ret = orig_MapViewOfSection(section, process, base, zero_bits,
- commit_size, offset, view_size, inherit,
- allocation_type, protect);
-
- static int s_load_count = 0;
- if (1 == s_load_count) {
- SandboxFactory::GetTargetServices()->GetState()->SetKernel32Loaded();
- s_load_count = 2;
- }
-
- do {
- if (!NT_SUCCESS(ret))
- break;
-
- if (!InitHeap())
- break;
-
- if (!IsSameProcess(process))
- break;
-
- if (!IsValidImageSection(section, base, offset, view_size))
- break;
-
- UINT image_flags;
- UNICODE_STRING* module_name =
- GetImageInfoFromModule(reinterpret_cast<HMODULE>(*base), &image_flags);
- UNICODE_STRING* file_name = GetBackingFilePath(*base);
-
- if ((!module_name) && (image_flags & MODULE_HAS_CODE)) {
- // If the module has no exports we retrieve the module name from the
- // full path of the mapped section.
- module_name = ExtractModuleName(file_name);
- }
-
- InterceptionAgent* agent = InterceptionAgent::GetInterceptionAgent();
-
- if (agent) {
- if (!agent->OnDllLoad(file_name, module_name, *base)) {
- // Interception agent is demanding to un-map the module.
- g_nt.UnmapViewOfSection(process, *base);
- ret = STATUS_UNSUCCESSFUL;
- }
- }
-
- if (module_name)
- operator delete(module_name, NT_ALLOC);
-
- if (file_name)
- operator delete(file_name, NT_ALLOC);
-
- } while (false);
-
- if (!s_load_count)
- s_load_count = 1;
-
- return ret;
-}
-
-NTSTATUS WINAPI TargetNtUnmapViewOfSection(
- NtUnmapViewOfSectionFunction orig_UnmapViewOfSection, HANDLE process,
- PVOID base) {
- NTSTATUS ret = orig_UnmapViewOfSection(process, base);
-
- if (!NT_SUCCESS(ret))
- return ret;
-
- if (!IsSameProcess(process))
- return ret;
-
- InterceptionAgent* agent = InterceptionAgent::GetInterceptionAgent();
-
- if (agent)
- agent->OnDllUnload(base);
-
- return ret;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/target_interceptions.h b/sandbox/win/src/target_interceptions.h
deleted file mode 100644
index f4805fe..0000000
--- a/sandbox/win/src/target_interceptions.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/nt_internals.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-#ifndef SANDBOX_SRC_TARGET_INTERCEPTIONS_H__
-#define SANDBOX_SRC_TARGET_INTERCEPTIONS_H__
-
-namespace sandbox {
-
-extern "C" {
-
-// Interception of NtMapViewOfSection on the child process.
-// It should never be called directly. This function provides the means to
-// detect dlls being loaded, so we can patch them if needed.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtMapViewOfSection(
- NtMapViewOfSectionFunction orig_MapViewOfSection, HANDLE section,
- HANDLE process, PVOID *base, ULONG_PTR zero_bits, SIZE_T commit_size,
- PLARGE_INTEGER offset, PSIZE_T view_size, SECTION_INHERIT inherit,
- ULONG allocation_type, ULONG protect);
-
-// Interception of NtUnmapViewOfSection on the child process.
-// It should never be called directly. This function provides the means to
-// detect dlls being unloaded, so we can clean up our interceptions.
-SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtUnmapViewOfSection(
- NtUnmapViewOfSectionFunction orig_UnmapViewOfSection, HANDLE process,
- PVOID base);
-
-} // extern "C"
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_TARGET_INTERCEPTIONS_H__
diff --git a/sandbox/win/src/target_process.cc b/sandbox/win/src/target_process.cc
deleted file mode 100644
index 601d80b..0000000
--- a/sandbox/win/src/target_process.cc
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/target_process.h"
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/win/pe_image.h"
-#include "base/win/windows_version.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/policy_low_level.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/sharedmem_ipc_server.h"
-
-namespace {
-
-void CopyPolicyToTarget(const void* source, size_t size, void* dest) {
- if (!source || !size)
- return;
- memcpy(dest, source, size);
- sandbox::PolicyGlobal* policy =
- reinterpret_cast<sandbox::PolicyGlobal*>(dest);
-
- size_t offset = reinterpret_cast<size_t>(source);
-
- for (size_t i = 0; i < sandbox::kMaxServiceCount; i++) {
- size_t buffer = reinterpret_cast<size_t>(policy->entry[i]);
- if (buffer) {
- buffer -= offset;
- policy->entry[i] = reinterpret_cast<sandbox::PolicyBuffer*>(buffer);
- }
- }
-}
-
-// Reserve a random range at the bottom of the address space in the target
-// process to prevent predictable alocations at low addresses.
-void PoisonLowerAddressRange(HANDLE process) {
- unsigned int limit;
- rand_s(&limit);
- char* ptr = 0;
- const size_t kMask64k = 0xFFFF;
- // Random range (512k-16.5mb) in 64k steps.
- const char* end = ptr + ((((limit % 16384) + 512) * 1024) & ~kMask64k);
- while (ptr < end) {
- MEMORY_BASIC_INFORMATION memory_info;
- if (!::VirtualQueryEx(process, ptr, &memory_info, sizeof(memory_info)))
- break;
- size_t size = std::min((memory_info.RegionSize + kMask64k) & ~kMask64k,
- static_cast<SIZE_T>(end - ptr));
- if (ptr && memory_info.State == MEM_FREE)
- ::VirtualAllocEx(process, ptr, size, MEM_RESERVE, PAGE_NOACCESS);
- ptr += size;
- }
-}
-
-}
-
-namespace sandbox {
-
-SANDBOX_INTERCEPT HANDLE g_shared_section;
-SANDBOX_INTERCEPT size_t g_shared_IPC_size;
-SANDBOX_INTERCEPT size_t g_shared_policy_size;
-
-// Returns the address of the main exe module in memory taking in account
-// address space layout randomization.
-void* GetBaseAddress(const wchar_t* exe_name, void* entry_point) {
- HMODULE exe = ::LoadLibrary(exe_name);
- if (NULL == exe)
- return exe;
-
- base::win::PEImage pe(exe);
- if (!pe.VerifyMagic()) {
- ::FreeLibrary(exe);
- return exe;
- }
- PIMAGE_NT_HEADERS nt_header = pe.GetNTHeaders();
- char* base = reinterpret_cast<char*>(entry_point) -
- nt_header->OptionalHeader.AddressOfEntryPoint;
-
- ::FreeLibrary(exe);
- return base;
-}
-
-
-TargetProcess::TargetProcess(HANDLE initial_token, HANDLE lockdown_token,
- HANDLE job, ThreadProvider* thread_pool)
- // This object owns everything initialized here except thread_pool and
- // the job_ handle. The Job handle is closed by BrokerServices and results
- // eventually in a call to our dtor.
- : lockdown_token_(lockdown_token),
- initial_token_(initial_token),
- job_(job),
- thread_pool_(thread_pool),
- base_address_(NULL) {
-}
-
-TargetProcess::~TargetProcess() {
- DWORD exit_code = 0;
- // Give a chance to the process to die. In most cases the JOB_KILL_ON_CLOSE
- // will take effect only when the context changes. As far as the testing went,
- // this wait was enough to switch context and kill the processes in the job.
- // If this process is already dead, the function will return without waiting.
- // TODO(nsylvain): If the process is still alive at the end, we should kill
- // it. http://b/893891
- // For now, this wait is there only to do a best effort to prevent some leaks
- // from showing up in purify.
- ::WaitForSingleObject(sandbox_process_info_.process_handle(), 50);
- if (!::GetExitCodeProcess(sandbox_process_info_.process_handle(),
- &exit_code) || (STILL_ACTIVE == exit_code)) {
- // It is an error to destroy this object while the target process is still
- // alive because we need to destroy the IPC subsystem and cannot risk to
- // have an IPC reach us after this point.
- shared_section_.Take();
- SharedMemIPCServer* server = ipc_server_.release();
- sandbox_process_info_.TakeProcessHandle();
- return;
- }
-
- // ipc_server_ references our process handle, so make sure the former is shut
- // down before the latter is closed (by ScopedProcessInformation).
- ipc_server_.reset();
-}
-
-// Creates the target (child) process suspended and assigns it to the job
-// object.
-DWORD TargetProcess::Create(const wchar_t* exe_path,
- const wchar_t* command_line,
- const wchar_t* desktop,
- base::win::ScopedProcessInformation* target_info) {
- exe_name_.reset(_wcsdup(exe_path));
-
- // the command line needs to be writable by CreateProcess().
- scoped_ptr_malloc<wchar_t> cmd_line(_wcsdup(command_line));
- scoped_ptr_malloc<wchar_t> desktop_name(desktop ? _wcsdup(desktop) : NULL);
-
- // Start the target process suspended.
- DWORD flags =
- CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS;
-
- if (base::win::GetVersion() < base::win::VERSION_WIN8) {
- // Windows 8 implements nested jobs, but for older systems we need to
- // break out of any job we're in to enforce our restrictions.
- flags |= CREATE_BREAKAWAY_FROM_JOB;
- }
-
- STARTUPINFO startup_info = {sizeof(STARTUPINFO)};
- if (desktop) {
- startup_info.lpDesktop = desktop_name.get();
- }
-
- base::win::ScopedProcessInformation process_info;
-
- if (!::CreateProcessAsUserW(lockdown_token_,
- exe_path,
- cmd_line.get(),
- NULL, // No security attribute.
- NULL, // No thread attribute.
- FALSE, // Do not inherit handles.
- flags,
- NULL, // Use the environment of the caller.
- NULL, // Use current directory of the caller.
- &startup_info,
- process_info.Receive())) {
- return ::GetLastError();
- }
- lockdown_token_.Close();
-
- PoisonLowerAddressRange(process_info.process_handle());
-
- DWORD win_result = ERROR_SUCCESS;
-
- // Assign the suspended target to the windows job object
- if (!::AssignProcessToJobObject(job_, process_info.process_handle())) {
- win_result = ::GetLastError();
- // It might be a security breach if we let the target run outside the job
- // so kill it before it causes damage
- ::TerminateProcess(process_info.process_handle(), 0);
- return win_result;
- }
-
- // Change the token of the main thread of the new process for the
- // impersonation token with more rights. This allows the target to start;
- // otherwise it will crash too early for us to help.
- {
- HANDLE temp_thread = process_info.thread_handle();
- if (!::SetThreadToken(&temp_thread, initial_token_)) {
- win_result = ::GetLastError();
- ::TerminateProcess(process_info.process_handle(), 0);
- return win_result;
- }
- initial_token_.Close();
- }
-
- CONTEXT context;
- context.ContextFlags = CONTEXT_ALL;
- if (!::GetThreadContext(process_info.thread_handle(), &context)) {
- win_result = ::GetLastError();
- ::TerminateProcess(process_info.process_handle(), 0);
- return win_result;
- }
-
-#if defined(_WIN64)
- void* entry_point = reinterpret_cast<void*>(context.Rcx);
-#else
-#pragma warning(push)
-#pragma warning(disable: 4312)
- // This cast generates a warning because it is 32 bit specific.
- void* entry_point = reinterpret_cast<void*>(context.Eax);
-#pragma warning(pop)
-#endif // _WIN64
-
- if (!target_info->DuplicateFrom(process_info)) {
- win_result = ::GetLastError(); // This may or may not be correct.
- ::TerminateProcess(process_info.process_handle(), 0);
- return win_result;
- }
-
- base_address_ = GetBaseAddress(exe_path, entry_point);
- sandbox_process_info_.Swap(&process_info);
- return win_result;
-}
-
-ResultCode TargetProcess::TransferVariable(const char* name, void* address,
- size_t size) {
- if (!sandbox_process_info_.IsValid())
- return SBOX_ERROR_UNEXPECTED_CALL;
-
- void* child_var = address;
-
-#if SANDBOX_EXPORTS
- HMODULE module = ::LoadLibrary(exe_name_.get());
- if (NULL == module)
- return SBOX_ERROR_GENERIC;
-
- child_var = ::GetProcAddress(module, name);
- ::FreeLibrary(module);
-
- if (NULL == child_var)
- return SBOX_ERROR_GENERIC;
-
- size_t offset = reinterpret_cast<char*>(child_var) -
- reinterpret_cast<char*>(module);
- child_var = reinterpret_cast<char*>(MainModule()) + offset;
-#else
- UNREFERENCED_PARAMETER(name);
-#endif
-
- SIZE_T written;
- if (!::WriteProcessMemory(sandbox_process_info_.process_handle(),
- child_var, address, size, &written))
- return SBOX_ERROR_GENERIC;
-
- if (written != size)
- return SBOX_ERROR_GENERIC;
-
- return SBOX_ALL_OK;
-}
-
-// Construct the IPC server and the IPC dispatcher. When the target does
-// an IPC it will eventually call the dispatcher.
-DWORD TargetProcess::Init(Dispatcher* ipc_dispatcher, void* policy,
- uint32 shared_IPC_size, uint32 shared_policy_size) {
- // We need to map the shared memory on the target. This is necessary for
- // any IPC that needs to take place, even if the target has not yet hit
- // the main( ) function or even has initialized the CRT. So here we set
- // the handle to the shared section. The target on the first IPC must do
- // the rest, which boils down to calling MapViewofFile()
-
- // We use this single memory pool for IPC and for policy.
- DWORD shared_mem_size = static_cast<DWORD>(shared_IPC_size +
- shared_policy_size);
- shared_section_.Set(::CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
- PAGE_READWRITE | SEC_COMMIT,
- 0, shared_mem_size, NULL));
- if (!shared_section_.IsValid()) {
- return ::GetLastError();
- }
-
- DWORD access = FILE_MAP_READ | FILE_MAP_WRITE;
- HANDLE target_shared_section;
- if (!::DuplicateHandle(::GetCurrentProcess(), shared_section_,
- sandbox_process_info_.process_handle(),
- &target_shared_section, access, FALSE, 0)) {
- return ::GetLastError();
- }
-
- void* shared_memory = ::MapViewOfFile(shared_section_,
- FILE_MAP_WRITE|FILE_MAP_READ,
- 0, 0, 0);
- if (NULL == shared_memory) {
- return ::GetLastError();
- }
-
- CopyPolicyToTarget(policy, shared_policy_size,
- reinterpret_cast<char*>(shared_memory) + shared_IPC_size);
-
- ResultCode ret;
- // Set the global variables in the target. These are not used on the broker.
- g_shared_section = target_shared_section;
- ret = TransferVariable("g_shared_section", &g_shared_section,
- sizeof(g_shared_section));
- g_shared_section = NULL;
- if (SBOX_ALL_OK != ret) {
- return (SBOX_ERROR_GENERIC == ret)?
- ::GetLastError() : ERROR_INVALID_FUNCTION;
- }
- g_shared_IPC_size = shared_IPC_size;
- ret = TransferVariable("g_shared_IPC_size", &g_shared_IPC_size,
- sizeof(g_shared_IPC_size));
- g_shared_IPC_size = 0;
- if (SBOX_ALL_OK != ret) {
- return (SBOX_ERROR_GENERIC == ret) ?
- ::GetLastError() : ERROR_INVALID_FUNCTION;
- }
- g_shared_policy_size = shared_policy_size;
- ret = TransferVariable("g_shared_policy_size", &g_shared_policy_size,
- sizeof(g_shared_policy_size));
- g_shared_policy_size = 0;
- if (SBOX_ALL_OK != ret) {
- return (SBOX_ERROR_GENERIC == ret) ?
- ::GetLastError() : ERROR_INVALID_FUNCTION;
- }
-
- ipc_server_.reset(
- new SharedMemIPCServer(sandbox_process_info_.process_handle(),
- sandbox_process_info_.process_id(),
- job_, thread_pool_, ipc_dispatcher));
-
- if (!ipc_server_->Init(shared_memory, shared_IPC_size, kIPCChannelSize))
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // After this point we cannot use this handle anymore.
- ::CloseHandle(sandbox_process_info_.TakeThreadHandle());
-
- return ERROR_SUCCESS;
-}
-
-void TargetProcess::Terminate() {
- if (!sandbox_process_info_.IsValid())
- return;
-
- ::TerminateProcess(sandbox_process_info_.process_handle(), 0);
-}
-
-
-TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address) {
- TargetProcess* target = new TargetProcess(NULL, NULL, NULL, NULL);
- target->sandbox_process_info_.Receive()->hProcess = process;
- target->base_address_ = base_address;
- return target;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/target_process.h b/sandbox/win/src/target_process.h
deleted file mode 100644
index 311fa84..0000000
--- a/sandbox/win/src/target_process.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_TARGET_PROCESS_H__
-#define SANDBOX_SRC_TARGET_PROCESS_H__
-
-#include <windows.h>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/win/scoped_handle.h"
-#include "base/win/scoped_process_information.h"
-#include "sandbox/win/src/crosscall_server.h"
-#include "sandbox/win/src/sandbox_types.h"
-
-namespace sandbox {
-
-class SharedMemIPCServer;
-class ThreadProvider;
-
-// TargetProcess models a target instance (child process). Objects of this
-// class are owned by the Policy used to create them.
-class TargetProcess {
- public:
- // The constructor takes ownership of |initial_token| and |lockdown_token|.
- TargetProcess(HANDLE initial_token, HANDLE lockdown_token, HANDLE job,
- ThreadProvider* thread_pool);
- ~TargetProcess();
-
- // TODO(cpu): Currently there does not seem to be a reason to implement
- // reference counting for this class since is internal, but kept the
- // the same interface so the interception framework does not need to be
- // touched at this point.
- void AddRef() {}
- void Release() {}
-
- // Creates the new target process. The process is created suspended.
- DWORD Create(const wchar_t* exe_path,
- const wchar_t* command_line,
- const wchar_t* desktop,
- base::win::ScopedProcessInformation* target_info);
-
- // Destroys the target process.
- void Terminate();
-
- // Creates the IPC objects such as the BrokerDispatcher and the
- // IPC server. The IPC server uses the services of the thread_pool.
- DWORD Init(Dispatcher* ipc_dispatcher, void* policy,
- uint32 shared_IPC_size, uint32 shared_policy_size);
-
- // Returns the handle to the target process.
- HANDLE Process() const {
- return sandbox_process_info_.process_handle();
- }
-
- // Returns the handle to the job object that the target process belongs to.
- HANDLE Job() const {
- return job_;
- }
-
- // Returns the address of the target main exe. This is used by the
- // interceptions framework.
- HMODULE MainModule() const {
- return reinterpret_cast<HMODULE>(base_address_);
- }
-
- // Returns the name of the executable.
- const wchar_t* Name() const {
- return exe_name_.get();
- }
-
- // Returns the process id.
- DWORD ProcessId() const {
- return sandbox_process_info_.process_id();
- }
-
- // Returns the handle to the main thread.
- HANDLE MainThread() const {
- return sandbox_process_info_.thread_handle();
- }
-
- // Transfers a 32-bit variable between the broker and the target.
- ResultCode TransferVariable(const char* name, void* address, size_t size);
-
- private:
- // Details of the target process.
- base::win::ScopedProcessInformation sandbox_process_info_;
- // The token associated with the process. It provides the core of the
- // sbox security.
- base::win::ScopedHandle lockdown_token_;
- // The token given to the initial thread so that the target process can
- // start. It has more powers than the lockdown_token.
- base::win::ScopedHandle initial_token_;
- // Kernel handle to the shared memory used by the IPC server.
- base::win::ScopedHandle shared_section_;
- // Job object containing the target process.
- HANDLE job_;
- // Reference to the IPC subsystem.
- scoped_ptr<SharedMemIPCServer> ipc_server_;
- // Provides the threads used by the IPC. This class does not own this pointer.
- ThreadProvider* thread_pool_;
- // Base address of the main executable
- void* base_address_;
- // Full name of the target executable.
- scoped_ptr_malloc<wchar_t> exe_name_;
-
- // Function used for testing.
- friend TargetProcess* MakeTestTargetProcess(HANDLE process,
- HMODULE base_address);
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(TargetProcess);
-};
-
-// Creates a mock TargetProcess used for testing interceptions.
-// TODO(cpu): It seems that this method is not going to be used anymore.
-TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address);
-
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_TARGET_PROCESS_H__
diff --git a/sandbox/win/src/target_services.cc b/sandbox/win/src/target_services.cc
deleted file mode 100644
index 495f108..0000000
--- a/sandbox/win/src/target_services.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/target_services.h"
-
-#include <process.h>
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/crosscall_client.h"
-#include "sandbox/win/src/handle_closer_agent.h"
-#include "sandbox/win/src/handle_interception.h"
-#include "sandbox/win/src/ipc_tags.h"
-#include "sandbox/win/src/restricted_token_utils.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_types.h"
-#include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "sandbox/win/src/sandbox_nt_util.h"
-
-namespace {
-
-// Flushing a cached key is triggered by just opening the key and closing the
-// resulting handle. RegDisablePredefinedCache() is the documented way to flush
-// HKCU so do not use it with this function.
-bool FlushRegKey(HKEY root) {
- HKEY key;
- if (ERROR_SUCCESS == ::RegOpenKeyExW(root, NULL, 0, MAXIMUM_ALLOWED, &key)) {
- if (ERROR_SUCCESS != ::RegCloseKey(key))
- return false;
- }
- return true;
-}
-
-// This function forces advapi32.dll to release some internally cached handles
-// that were made during calls to RegOpenkey and RegOpenKeyEx if it is called
-// with a more restrictive token. Returns true if the flushing is succesful
-// although this behavior is undocumented and there is no guarantee that in
-// fact this will happen in future versions of windows.
-bool FlushCachedRegHandles() {
- return (FlushRegKey(HKEY_LOCAL_MACHINE) &&
- FlushRegKey(HKEY_CLASSES_ROOT) &&
- FlushRegKey(HKEY_USERS));
-}
-
-// Checks if we have handle entries pending and runs the closer.
-bool CloseOpenHandles() {
- if (sandbox::HandleCloserAgent::NeedsHandlesClosed()) {
- sandbox::HandleCloserAgent handle_closer;
-
- handle_closer.InitializeHandlesToClose();
- if (!handle_closer.CloseHandles())
- return false;
- }
-
- return true;
-}
-
-} // namespace
-
-namespace sandbox {
-
-SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level =
- INTEGRITY_LEVEL_LAST;
-
-TargetServicesBase::TargetServicesBase() {
-}
-
-ResultCode TargetServicesBase::Init() {
- process_state_.SetInitCalled();
- return SBOX_ALL_OK;
-}
-
-// Failure here is a breach of security so the process is terminated.
-void TargetServicesBase::LowerToken() {
- if (ERROR_SUCCESS !=
- SetProcessIntegrityLevel(g_shared_delayed_integrity_level))
- ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_INTEGRITY);
- process_state_.SetRevertedToSelf();
- // If the client code as called RegOpenKey, advapi32.dll has cached some
- // handles. The following code gets rid of them.
- if (!::RevertToSelf())
- ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_DROPTOKEN);
- if (!FlushCachedRegHandles())
- ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_FLUSHANDLES);
- if (ERROR_SUCCESS != ::RegDisablePredefinedCache())
- ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CACHEDISABLE);
- if (!CloseOpenHandles())
- ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CLOSEHANDLES);
-}
-
-ProcessState* TargetServicesBase::GetState() {
- return &process_state_;
-}
-
-TargetServicesBase* TargetServicesBase::GetInstance() {
- static TargetServicesBase instance;
- return &instance;
-}
-
-// The broker services a 'test' IPC service with the IPC_PING_TAG tag.
-bool TargetServicesBase::TestIPCPing(int version) {
- void* memory = GetGlobalIPCMemory();
- if (NULL == memory) {
- return false;
- }
- SharedMemIPCClient ipc(memory);
- CrossCallReturn answer = {0};
-
- if (1 == version) {
- uint32 tick1 = ::GetTickCount();
- uint32 cookie = 717115;
- ResultCode code = CrossCall(ipc, IPC_PING1_TAG, cookie, &answer);
-
- if (SBOX_ALL_OK != code) {
- return false;
- }
- // We should get two extended returns values from the IPC, one is the
- // tick count on the broker and the other is the cookie times two.
- if ((answer.extended_count != 2)) {
- return false;
- }
- // We test the first extended answer to be within the bounds of the tick
- // count only if there was no tick count wraparound.
- uint32 tick2 = ::GetTickCount();
- if (tick2 >= tick1) {
- if ((answer.extended[0].unsigned_int < tick1) ||
- (answer.extended[0].unsigned_int > tick2)) {
- return false;
- }
- }
-
- if (answer.extended[1].unsigned_int != cookie * 2) {
- return false;
- }
- } else if (2 == version) {
- uint32 cookie = 717111;
- InOutCountedBuffer counted_buffer(&cookie, sizeof(cookie));
- ResultCode code = CrossCall(ipc, IPC_PING2_TAG, counted_buffer, &answer);
-
- if (SBOX_ALL_OK != code) {
- return false;
- }
- if (cookie != 717111 * 3) {
- return false;
- }
- } else {
- return false;
- }
- return true;
-}
-
-bool ProcessState::IsKernel32Loaded() {
- return process_state_ != 0;
-}
-
-bool ProcessState::InitCalled() {
- return process_state_ > 1;
-}
-
-bool ProcessState::RevertedToSelf() {
- return process_state_ > 2;
-}
-
-void ProcessState::SetKernel32Loaded() {
- if (!process_state_)
- process_state_ = 1;
-}
-
-void ProcessState::SetInitCalled() {
- if (process_state_ < 2)
- process_state_ = 2;
-}
-
-void ProcessState::SetRevertedToSelf() {
- if (process_state_ < 3)
- process_state_ = 3;
-}
-
-ResultCode TargetServicesBase::DuplicateHandle(HANDLE source_handle,
- DWORD target_process_id,
- HANDLE* target_handle,
- DWORD desired_access,
- DWORD options) {
- return sandbox::DuplicateHandleProxy(source_handle, target_process_id,
- target_handle, desired_access, options);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/target_services.h b/sandbox/win/src/target_services.h
deleted file mode 100644
index 70f173b..0000000
--- a/sandbox/win/src/target_services.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_TARGET_SERVICES_H__
-#define SANDBOX_SRC_TARGET_SERVICES_H__
-
-#include "base/basictypes.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/win_utils.h"
-
-namespace sandbox {
-
-class ProcessState {
- public:
- ProcessState() : process_state_(0) {}
-
- // Returns true if kernel32.dll has been loaded.
- bool IsKernel32Loaded();
-
- // Returns true if main has been called.
- bool InitCalled();
-
- // Returns true if LowerToken has been called.
- bool RevertedToSelf();
-
- // Set the current state.
- void SetKernel32Loaded();
- void SetInitCalled();
- void SetRevertedToSelf();
-
- public:
- int process_state_;
- DISALLOW_COPY_AND_ASSIGN(ProcessState);
-};
-
-// This class is an implementation of the TargetServices.
-// Look in the documentation of sandbox::TargetServices for more info.
-// Do NOT add a destructor to this class without changing the implementation of
-// the factory method.
-class TargetServicesBase : public TargetServices {
- public:
- TargetServicesBase();
-
- // Public interface of TargetServices.
- virtual ResultCode Init();
- virtual void LowerToken();
- virtual ProcessState* GetState();
- virtual ResultCode DuplicateHandle(HANDLE source_handle,
- DWORD target_process_id,
- HANDLE* target_handle,
- DWORD desired_access,
- DWORD options);
-
- // Factory method.
- static TargetServicesBase* GetInstance();
-
- // Sends a simple IPC Message that has a well-known answer. Returns true
- // if the IPC was successful and false otherwise. There are 2 versions of
- // this test: 1 and 2. The first one send a simple message while the
- // second one send a message with an in/out param.
- bool TestIPCPing(int version);
-
- private:
- ProcessState process_state_;
- DISALLOW_COPY_AND_ASSIGN(TargetServicesBase);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_TARGET_SERVICES_H__
diff --git a/sandbox/win/src/threadpool_unittest.cc b/sandbox/win/src/threadpool_unittest.cc
deleted file mode 100644
index f439810..0000000
--- a/sandbox/win/src/threadpool_unittest.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/win2k_threadpool.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-void __stdcall EmptyCallBack(void*, unsigned char) {
-}
-
-void __stdcall TestCallBack(void* context, unsigned char) {
- HANDLE event = reinterpret_cast<HANDLE>(context);
- ::SetEvent(event);
-}
-
-namespace sandbox {
-
-// Test that register and unregister work, part 1.
-TEST(IPCTest, ThreadPoolRegisterTest1) {
- Win2kThreadPool thread_pool;
-
- EXPECT_EQ(0, thread_pool.OutstandingWaits());
-
- HANDLE event1 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
- HANDLE event2 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
-
- uint32 context = 0;
- EXPECT_FALSE(thread_pool.RegisterWait(0, event1, EmptyCallBack, &context));
- EXPECT_EQ(0, thread_pool.OutstandingWaits());
-
- EXPECT_TRUE(thread_pool.RegisterWait(this, event1, EmptyCallBack, &context));
- EXPECT_EQ(1, thread_pool.OutstandingWaits());
- EXPECT_TRUE(thread_pool.RegisterWait(this, event2, EmptyCallBack, &context));
- EXPECT_EQ(2, thread_pool.OutstandingWaits());
-
- EXPECT_TRUE(thread_pool.UnRegisterWaits(this));
- EXPECT_EQ(0, thread_pool.OutstandingWaits());
-
- EXPECT_EQ(TRUE, ::CloseHandle(event1));
- EXPECT_EQ(TRUE, ::CloseHandle(event2));
-}
-
-// Test that register and unregister work, part 2.
-TEST(IPCTest, ThreadPoolRegisterTest2) {
- Win2kThreadPool thread_pool;
-
- HANDLE event1 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
- HANDLE event2 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
-
- uint32 context = 0;
- uint32 c1 = 0;
- uint32 c2 = 0;
-
- EXPECT_TRUE(thread_pool.RegisterWait(&c1, event1, EmptyCallBack, &context));
- EXPECT_EQ(1, thread_pool.OutstandingWaits());
- EXPECT_TRUE(thread_pool.RegisterWait(&c2, event2, EmptyCallBack, &context));
- EXPECT_EQ(2, thread_pool.OutstandingWaits());
-
- EXPECT_TRUE(thread_pool.UnRegisterWaits(&c2));
- EXPECT_EQ(1, thread_pool.OutstandingWaits());
- EXPECT_TRUE(thread_pool.UnRegisterWaits(&c2));
- EXPECT_EQ(1, thread_pool.OutstandingWaits());
-
- EXPECT_TRUE(thread_pool.UnRegisterWaits(&c1));
- EXPECT_EQ(0, thread_pool.OutstandingWaits());
-
- EXPECT_EQ(TRUE, ::CloseHandle(event1));
- EXPECT_EQ(TRUE, ::CloseHandle(event2));
-}
-
-// Test that the thread pool has at least a thread that services an event.
-// Test that when the event is un-registered is no longer serviced.
-TEST(IPCTest, ThreadPoolSignalAndWaitTest) {
- Win2kThreadPool thread_pool;
-
- // The events are auto reset and start not signaled.
- HANDLE event1 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
- HANDLE event2 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
-
- EXPECT_TRUE(thread_pool.RegisterWait(this, event1, TestCallBack, event2));
-
- EXPECT_EQ(WAIT_OBJECT_0, ::SignalObjectAndWait(event1, event2, 5000, FALSE));
- EXPECT_EQ(WAIT_OBJECT_0, ::SignalObjectAndWait(event1, event2, 5000, FALSE));
-
- EXPECT_TRUE(thread_pool.UnRegisterWaits(this));
- EXPECT_EQ(0, thread_pool.OutstandingWaits());
-
- EXPECT_EQ(WAIT_TIMEOUT, ::SignalObjectAndWait(event1, event2, 1000, FALSE));
-
- EXPECT_EQ(TRUE, ::CloseHandle(event1));
- EXPECT_EQ(TRUE, ::CloseHandle(event2));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/unload_dll_test.cc b/sandbox/win/src/unload_dll_test.cc
deleted file mode 100644
index 620016c..0000000
--- a/sandbox/win/src/unload_dll_test.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/win/scoped_handle.h"
-#include "sandbox/win/src/sandbox.h"
-#include "sandbox/win/src/sandbox_factory.h"
-#include "sandbox/win/src/target_services.h"
-#include "sandbox/win/tests/common/controller.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace sandbox {
-
-// Loads and or unloads a DLL passed in the second parameter of argv.
-// The first parameter of argv is 'L' = load, 'U' = unload or 'B' for both.
-SBOX_TESTS_COMMAND int UseOneDLL(int argc, wchar_t **argv) {
- if (argc != 2)
- return SBOX_TEST_FAILED_TO_RUN_TEST;
- int rv = SBOX_TEST_FAILED_TO_RUN_TEST;
-
- wchar_t option = (argv[0])[0];
- if ((option == L'L') || (option == L'B')) {
- HMODULE module1 = ::LoadLibraryW(argv[1]);
- rv = (module1 == NULL) ? SBOX_TEST_FAILED : SBOX_TEST_SUCCEEDED;
- }
-
- if ((option == L'U') || (option == L'B')) {
- HMODULE module2 = ::GetModuleHandleW(argv[1]);
- rv = ::FreeLibrary(module2) ? SBOX_TEST_SUCCEEDED : SBOX_TEST_FAILED;
- }
- return rv;
-}
-
-// Opens an event passed as the first parameter of argv.
-SBOX_TESTS_COMMAND int SimpleOpenEvent(int argc, wchar_t **argv) {
- if (argc != 1)
- return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
-
- base::win::ScopedHandle event_open(::OpenEvent(SYNCHRONIZE, FALSE, argv[0]));
- return event_open.Get() ? SBOX_TEST_SUCCEEDED : SBOX_TEST_FAILED;
-}
-
-// Flaky on windows, see http://crbug.com/80569.
-TEST(UnloadDllTest, DISABLED_BaselineAvicapDll) {
- TestRunner runner;
- runner.SetTestState(BEFORE_REVERT);
- runner.SetTimeout(2000);
- // Add a sync rule, because that ensures that the interception agent has
- // more than one item in its internal table.
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_SYNC,
- TargetPolicy::EVENTS_ALLOW_ANY, L"t0001"));
-
- // Note for the puzzled: avicap32.dll is a 64-bit dll in 64-bit versions of
- // windows so this test and the others just work.
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"UseOneDLL L avicap32.dll"));
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"UseOneDLL B avicap32.dll"));
-}
-
-// Flaky on windows, see http://crbug.com/80569.
-TEST(UnloadDllTest, DISABLED_UnloadAviCapDllNoPatching) {
- TestRunner runner;
- runner.SetTestState(BEFORE_REVERT);
- runner.SetTimeout(2000);
- sandbox::TargetPolicy* policy = runner.GetPolicy();
- policy->AddDllToUnload(L"avicap32.dll");
- EXPECT_EQ(SBOX_TEST_FAILED, runner.RunTest(L"UseOneDLL L avicap32.dll"));
- EXPECT_EQ(SBOX_TEST_FAILED, runner.RunTest(L"UseOneDLL B avicap32.dll"));
-}
-
-// Flaky: http://crbug.com/38404
-TEST(UnloadDllTest, DISABLED_UnloadAviCapDllWithPatching) {
- TestRunner runner;
- runner.SetTimeout(2000);
- runner.SetTestState(BEFORE_REVERT);
- sandbox::TargetPolicy* policy = runner.GetPolicy();
- policy->AddDllToUnload(L"avicap32.dll");
-
- base::win::ScopedHandle handle1(::CreateEvent(
- NULL, FALSE, FALSE, L"tst0001"));
-
- // Add a couple of rules that ensures that the interception agent add EAT
- // patching on the client which makes sure that the unload dll record does
- // not interact badly with them.
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
- TargetPolicy::REG_ALLOW_ANY,
- L"HKEY_LOCAL_MACHINE\\Software\\Microsoft"));
- EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_SYNC,
- TargetPolicy::EVENTS_ALLOW_ANY, L"tst0001"));
-
- EXPECT_EQ(SBOX_TEST_FAILED, runner.RunTest(L"UseOneDLL L avicap32.dll"));
-
- runner.SetTestState(AFTER_REVERT);
- EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"SimpleOpenEvent tst0001"));
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/win2k_threadpool.cc b/sandbox/win/src/win2k_threadpool.cc
deleted file mode 100644
index 24cbacf..0000000
--- a/sandbox/win/src/win2k_threadpool.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/win2k_threadpool.h"
-
-#include "sandbox/win/src/win_utils.h"
-
-namespace sandbox {
-
-bool Win2kThreadPool::RegisterWait(const void* cookie, HANDLE waitable_object,
- CrossCallIPCCallback callback,
- void* context) {
- if (0 == cookie) {
- return false;
- }
- HANDLE pool_object = NULL;
- // create a wait for a kernel object, with no timeout
- if (!::RegisterWaitForSingleObject(&pool_object, waitable_object, callback,
- context, INFINITE, WT_EXECUTEDEFAULT)) {
- return false;
- }
- PoolObject pool_obj = {cookie, pool_object};
- AutoLock lock(&lock_);
- pool_objects_.push_back(pool_obj);
- return true;
-}
-
-bool Win2kThreadPool::UnRegisterWaits(void* cookie) {
- if (0 == cookie) {
- return false;
- }
- AutoLock lock(&lock_);
- bool success = true;
- PoolObjects::iterator it = pool_objects_.begin();
- while (it != pool_objects_.end()) {
- if (it->cookie == cookie) {
- HANDLE wait = it->wait;
- it = pool_objects_.erase(it);
- success &= (::UnregisterWaitEx(wait, INVALID_HANDLE_VALUE) != 0);
- } else {
- ++it;
- }
- }
- return success;
-}
-
-size_t Win2kThreadPool::OutstandingWaits() {
- AutoLock lock(&lock_);
- return pool_objects_.size();
-}
-
-Win2kThreadPool::~Win2kThreadPool() {
- // Here we used to unregister all the pool wait handles. Now, following the
- // rest of the code we avoid lengthy or blocking calls given that the process
- // is being torn down.
- ::DeleteCriticalSection(&lock_);
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/win2k_threadpool.h b/sandbox/win/src/win2k_threadpool.h
deleted file mode 100644
index 0abb358..0000000
--- a/sandbox/win/src/win2k_threadpool.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_WIN2K_THREADPOOL_H_
-#define SANDBOX_SRC_WIN2K_THREADPOOL_H_
-
-#include <list>
-#include <algorithm>
-#include "sandbox/win/src/crosscall_server.h"
-
-namespace sandbox {
-
-// Win2kThreadPool a simple implementation of a thread provider as required
-// for the sandbox IPC subsystem. See sandbox\crosscall_server.h for the details
-// and requirements of this interface.
-//
-// Implementing the thread provider as a thread pool is desirable in the case
-// of shared memory IPC because it can generate a large number of waitable
-// events: as many as channels. A thread pool does not create a thread per
-// event, instead maintains a few idle threads but can create more if the need
-// arises.
-//
-// This implementation simply thunks to the nice thread pool API of win2k.
-class Win2kThreadPool : public ThreadProvider {
- public:
- Win2kThreadPool() {
- ::InitializeCriticalSection(&lock_);
- }
- virtual ~Win2kThreadPool();
-
- virtual bool RegisterWait(const void* cookie, HANDLE waitable_object,
- CrossCallIPCCallback callback,
- void* context);
-
- virtual bool UnRegisterWaits(void* cookie);
-
- // Returns the total number of wait objects associated with
- // the thread pool.
- size_t OutstandingWaits();
-
- private:
- // record to keep track of a wait and its associated cookie.
- struct PoolObject {
- const void* cookie;
- HANDLE wait;
- };
- // The list of pool wait objects.
- typedef std::list<PoolObject> PoolObjects;
- PoolObjects pool_objects_;
- // This lock protects the list of pool wait objects.
- CRITICAL_SECTION lock_;
- DISALLOW_COPY_AND_ASSIGN(Win2kThreadPool);
-};
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_WIN2K_THREADPOOL_H_
diff --git a/sandbox/win/src/win_utils.cc b/sandbox/win/src/win_utils.cc
deleted file mode 100644
index 8e63ac7..0000000
--- a/sandbox/win/src/win_utils.cc
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/win_utils.h"
-
-#include <map>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "sandbox/win/src/internal_types.h"
-#include "sandbox/win/src/nt_internals.h"
-
-namespace {
-
-// Holds the information about a known registry key.
-struct KnownReservedKey {
- const wchar_t* name;
- HKEY key;
-};
-
-// Contains all the known registry key by name and by handle.
-const KnownReservedKey kKnownKey[] = {
- { L"HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT },
- { L"HKEY_CURRENT_USER", HKEY_CURRENT_USER },
- { L"HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE},
- { L"HKEY_USERS", HKEY_USERS},
- { L"HKEY_PERFORMANCE_DATA", HKEY_PERFORMANCE_DATA},
- { L"HKEY_PERFORMANCE_TEXT", HKEY_PERFORMANCE_TEXT},
- { L"HKEY_PERFORMANCE_NLSTEXT", HKEY_PERFORMANCE_NLSTEXT},
- { L"HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG},
- { L"HKEY_DYN_DATA", HKEY_DYN_DATA}
-};
-
-// Returns true if the provided path points to a pipe.
-bool IsPipe(const std::wstring& path) {
- size_t start = 0;
- if (0 == path.compare(0, sandbox::kNTPrefixLen, sandbox::kNTPrefix))
- start = sandbox::kNTPrefixLen;
-
- const wchar_t kPipe[] = L"pipe\\";
- return (0 == path.compare(start, arraysize(kPipe) - 1, kPipe));
-}
-
-} // namespace
-
-namespace sandbox {
-
-HKEY GetReservedKeyFromName(const std::wstring& name) {
- for (size_t i = 0; i < arraysize(kKnownKey); ++i) {
- if (name == kKnownKey[i].name)
- return kKnownKey[i].key;
- }
-
- return NULL;
-}
-
-bool ResolveRegistryName(std::wstring name, std::wstring* resolved_name) {
- for (size_t i = 0; i < arraysize(kKnownKey); ++i) {
- if (name.find(kKnownKey[i].name) == 0) {
- HKEY key;
- DWORD disposition;
- if (ERROR_SUCCESS != ::RegCreateKeyEx(kKnownKey[i].key, L"", 0, NULL, 0,
- MAXIMUM_ALLOWED, NULL, &key,
- &disposition))
- return false;
-
- bool result = GetPathFromHandle(key, resolved_name);
- ::RegCloseKey(key);
-
- if (!result)
- return false;
-
- *resolved_name += name.substr(wcslen(kKnownKey[i].name));
- return true;
- }
- }
-
- return false;
-}
-
-DWORD IsReparsePoint(const std::wstring& full_path, bool* result) {
- std::wstring path = full_path;
-
- // Remove the nt prefix.
- if (0 == path.compare(0, kNTPrefixLen, kNTPrefix))
- path = path.substr(kNTPrefixLen);
-
- // Check if it's a pipe. We can't query the attributes of a pipe.
- if (IsPipe(path)) {
- *result = FALSE;
- return ERROR_SUCCESS;
- }
-
- std::wstring::size_type last_pos = std::wstring::npos;
-
- do {
- path = path.substr(0, last_pos);
-
- DWORD attributes = ::GetFileAttributes(path.c_str());
- if (INVALID_FILE_ATTRIBUTES == attributes) {
- DWORD error = ::GetLastError();
- if (error != ERROR_FILE_NOT_FOUND &&
- error != ERROR_PATH_NOT_FOUND &&
- error != ERROR_INVALID_NAME) {
- // Unexpected error.
- NOTREACHED();
- return error;
- }
- } else if (FILE_ATTRIBUTE_REPARSE_POINT & attributes) {
- // This is a reparse point.
- *result = true;
- return ERROR_SUCCESS;
- }
-
- last_pos = path.rfind(L'\\');
- } while (last_pos != std::wstring::npos);
-
- *result = false;
- return ERROR_SUCCESS;
-}
-
-// We get a |full_path| of the form \??\c:\some\foo\bar, and the name that
-// we'll get from |handle| will be \device\harddiskvolume1\some\foo\bar.
-bool SameObject(HANDLE handle, const wchar_t* full_path) {
- std::wstring path(full_path);
- DCHECK(!path.empty());
-
- // Check if it's a pipe.
- if (IsPipe(path))
- return true;
-
- std::wstring actual_path;
- if (!GetPathFromHandle(handle, &actual_path))
- return false;
-
- // This may end with a backslash.
- const wchar_t kBackslash = '\\';
- if (path[path.length() - 1] == kBackslash)
- path = path.substr(0, path.length() - 1);
-
- // Perfect match (case-insesitive check).
- if (0 == _wcsicmp(actual_path.c_str(), path.c_str()))
- return true;
-
- // Look for the drive letter.
- size_t colon_pos = path.find(L':');
- if (colon_pos == 0 || colon_pos == std::wstring::npos)
- return false;
-
- // Only one character for the drive.
- if (colon_pos > 1 && path[colon_pos - 2] != kBackslash)
- return false;
-
- // We only need 3 chars, but let's alloc a buffer for four.
- wchar_t drive[4] = {0};
- wchar_t vol_name[MAX_PATH];
- memcpy(drive, &path[colon_pos - 1], 2 * sizeof(*drive));
-
- // We'll get a double null terminated string.
- DWORD vol_length = ::QueryDosDeviceW(drive, vol_name, MAX_PATH);
- if (vol_length < 2 || vol_length == MAX_PATH)
- return false;
-
- // Ignore the nulls at the end.
- vol_length = static_cast<DWORD>(wcslen(vol_name));
-
- // The two paths should be the same length.
- if (vol_length + path.size() - (colon_pos + 1) != actual_path.size())
- return false;
-
- // Check up to the drive letter.
- if (0 != _wcsnicmp(actual_path.c_str(), vol_name, vol_length))
- return false;
-
- // Check the path after the drive letter.
- if (0 != _wcsicmp(&actual_path[vol_length], &path[colon_pos + 1]))
- return false;
-
- return true;
-}
-
-bool ConvertToLongPath(const std::wstring& short_path,
- std::wstring* long_path) {
- // Check if the path is a NT path.
- bool is_nt_path = false;
- std::wstring path = short_path;
- if (0 == path.compare(0, kNTPrefixLen, kNTPrefix)) {
- path = path.substr(kNTPrefixLen);
- is_nt_path = true;
- }
-
- DWORD size = MAX_PATH;
- scoped_array<wchar_t> long_path_buf(new wchar_t[size]);
-
- DWORD return_value = ::GetLongPathName(path.c_str(), long_path_buf.get(),
- size);
- while (return_value >= size) {
- size *= 2;
- long_path_buf.reset(new wchar_t[size]);
- return_value = ::GetLongPathName(path.c_str(), long_path_buf.get(), size);
- }
-
- DWORD last_error = ::GetLastError();
- if (0 == return_value && (ERROR_FILE_NOT_FOUND == last_error ||
- ERROR_PATH_NOT_FOUND == last_error ||
- ERROR_INVALID_NAME == last_error)) {
- // The file does not exist, but maybe a sub path needs to be expanded.
- std::wstring::size_type last_slash = path.rfind(L'\\');
- if (std::wstring::npos == last_slash)
- return false;
-
- std::wstring begin = path.substr(0, last_slash);
- std::wstring end = path.substr(last_slash);
- if (!ConvertToLongPath(begin, &begin))
- return false;
-
- // Ok, it worked. Let's reset the return value.
- path = begin + end;
- return_value = 1;
- } else if (0 != return_value) {
- path = long_path_buf.get();
- }
-
- if (return_value != 0) {
- if (is_nt_path) {
- *long_path = kNTPrefix;
- *long_path += path;
- } else {
- *long_path = path;
- }
-
- return true;
- }
-
- return false;
-}
-
-bool GetPathFromHandle(HANDLE handle, std::wstring* path) {
- NtQueryObjectFunction NtQueryObject = NULL;
- ResolveNTFunctionPtr("NtQueryObject", &NtQueryObject);
-
- OBJECT_NAME_INFORMATION initial_buffer;
- OBJECT_NAME_INFORMATION* name = &initial_buffer;
- ULONG size = sizeof(initial_buffer);
- // Query the name information a first time to get the size of the name.
- NTSTATUS status = NtQueryObject(handle, ObjectNameInformation, name, size,
- &size);
-
- scoped_ptr<OBJECT_NAME_INFORMATION> name_ptr;
- if (size) {
- name = reinterpret_cast<OBJECT_NAME_INFORMATION*>(new BYTE[size]);
- name_ptr.reset(name);
-
- // Query the name information a second time to get the name of the
- // object referenced by the handle.
- status = NtQueryObject(handle, ObjectNameInformation, name, size, &size);
- }
-
- if (STATUS_SUCCESS != status)
- return false;
-
- path->assign(name->ObjectName.Buffer, name->ObjectName.Length /
- sizeof(name->ObjectName.Buffer[0]));
- return true;
-}
-
-bool GetNtPathFromWin32Path(const std::wstring& path, std::wstring* nt_path) {
- HANDLE file = ::CreateFileW(path.c_str(), 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
- OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (file == INVALID_HANDLE_VALUE)
- return false;
- bool rv = GetPathFromHandle(file, nt_path);
- ::CloseHandle(file);
- return rv;
-}
-
-bool WriteProtectedChildMemory(HANDLE child_process, void* address,
- const void* buffer, size_t length) {
- // First, remove the protections.
- DWORD old_protection;
- if (!::VirtualProtectEx(child_process, address, length,
- PAGE_WRITECOPY, &old_protection))
- return false;
-
- SIZE_T written;
- bool ok = ::WriteProcessMemory(child_process, address, buffer, length,
- &written) && (length == written);
-
- // Always attempt to restore the original protection.
- if (!::VirtualProtectEx(child_process, address, length,
- old_protection, &old_protection))
- return false;
-
- return ok;
-}
-
-}; // namespace sandbox
-
-// TODO(jschuh): http://crbug.com/11789
-// I'm guessing we have a race where some "security" software is messing
-// with ntdll/imports underneath us. So, we retry a few times, and in the
-// worst case we sleep briefly before a few more attempts. (Normally sleeping
-// would be very bad, but it's better than crashing in this case.)
-void ResolveNTFunctionPtr(const char* name, void* ptr) {
- const int max_tries = 5;
- const int sleep_threshold = 2;
-
- static HMODULE ntdll = ::GetModuleHandle(sandbox::kNtdllName);
-
- FARPROC* function_ptr = reinterpret_cast<FARPROC*>(ptr);
- *function_ptr = ::GetProcAddress(ntdll, name);
-
- for (int tries = 1; !(*function_ptr) && tries < max_tries; ++tries) {
- if (tries >= sleep_threshold)
- ::Sleep(1);
- ntdll = ::GetModuleHandle(sandbox::kNtdllName);
- *function_ptr = ::GetProcAddress(ntdll, name);
- }
-
- CHECK(*function_ptr);
-}
diff --git a/sandbox/win/src/win_utils.h b/sandbox/win/src/win_utils.h
deleted file mode 100644
index a80bb81..0000000
--- a/sandbox/win/src/win_utils.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_WIN_UTILS_H_
-#define SANDBOX_SRC_WIN_UTILS_H_
-
-#include <windows.h>
-#include <string>
-#include "base/basictypes.h"
-
-namespace sandbox {
-
-// Prefix for path used by NT calls.
-const wchar_t kNTPrefix[] = L"\\??\\";
-const size_t kNTPrefixLen = arraysize(kNTPrefix) - 1;
-
-const wchar_t kNTObjManPrefix[] = L"\\Device\\";
-const size_t kNTObjManPrefixLen = arraysize(kNTObjManPrefix) - 1;
-
-// Automatically acquires and releases a lock when the object is
-// is destroyed.
-class AutoLock {
- public:
- // Acquires the lock.
- explicit AutoLock(CRITICAL_SECTION *lock) : lock_(lock) {
- ::EnterCriticalSection(lock);
- };
-
- // Releases the lock;
- ~AutoLock() {
- ::LeaveCriticalSection(lock_);
- };
-
- private:
- CRITICAL_SECTION *lock_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(AutoLock);
-};
-
-// Basic implementation of a singleton which calls the destructor
-// when the exe is shutting down or the DLL is being unloaded.
-template <typename Derived>
-class SingletonBase {
- public:
- static Derived* GetInstance() {
- static Derived* instance = NULL;
- if (NULL == instance) {
- instance = new Derived();
- // Microsoft CRT extension. In an exe this this called after
- // winmain returns, in a dll is called in DLL_PROCESS_DETACH
- _onexit(OnExit);
- }
- return instance;
- }
-
- private:
- // this is the function that gets called by the CRT when the
- // process is shutting down.
- static int __cdecl OnExit() {
- delete GetInstance();
- return 0;
- }
-};
-
-// Convert a short path (C:\path~1 or \\??\\c:\path~1) to the long version of
-// the path. If the path is not a valid filesystem path, the function returns
-// false and the output parameter is not modified.
-bool ConvertToLongPath(const std::wstring& short_path, std::wstring* long_path);
-
-// Sets result to true if the path contains a reparse point. The return value
-// is ERROR_SUCCESS when the function succeeds or the appropriate error code
-// when the function fails.
-// This function is not smart. It looks for each element in the path and
-// returns true if any of them is a reparse point.
-DWORD IsReparsePoint(const std::wstring& full_path, bool* result);
-
-// Returns true if the handle corresponds to the object pointed by this path.
-bool SameObject(HANDLE handle, const wchar_t* full_path);
-
-// Resolves a handle to an nt path. Returns true if the handle can be resolved.
-bool GetPathFromHandle(HANDLE handle, std::wstring* path);
-
-// Resolves a win32 path to an nt path using GetPathFromHandle. The path must
-// exist. Returs true if the translation was succesful.
-bool GetNtPathFromWin32Path(const std::wstring& path, std::wstring* nt_path);
-
-// Translates a reserved key name to its handle.
-// For example "HKEY_LOCAL_MACHINE" returns HKEY_LOCAL_MACHINE.
-// Returns NULL if the name does not represent any reserved key name.
-HKEY GetReservedKeyFromName(const std::wstring& name);
-
-// Resolves a user-readable registry path to a system-readable registry path.
-// For example, HKEY_LOCAL_MACHINE\\Software\\microsoft is translated to
-// \\registry\\machine\\software\\microsoft. Returns false if the path
-// cannot be resolved.
-bool ResolveRegistryName(std::wstring name, std::wstring* resolved_name);
-
-// Writes |length| bytes from the provided |buffer| into the address space of
-// |child_process|, at the specified |address|, preserving the original write
-// protection attributes. Returns true on success.
-bool WriteProtectedChildMemory(HANDLE child_process, void* address,
- const void* buffer, size_t length);
-
-} // namespace sandbox
-
-// Resolves a function name in NTDLL to a function pointer. The second parameter
-// is a pointer to the function pointer.
-void ResolveNTFunctionPtr(const char* name, void* ptr);
-
-#endif // SANDBOX_SRC_WIN_UTILS_H_
diff --git a/sandbox/win/src/win_utils_unittest.cc b/sandbox/win/src/win_utils_unittest.cc
deleted file mode 100644
index 7265316..0000000
--- a/sandbox/win/src/win_utils_unittest.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <windows.h>
-
-#include "base/win/scoped_handle.h"
-#include "sandbox/win/src/win_utils.h"
-#include "sandbox/win/tests/common/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-TEST(WinUtils, IsReparsePoint) {
- using sandbox::IsReparsePoint;
-
- // Create a temp file because we need write access to it.
- wchar_t temp_directory[MAX_PATH];
- wchar_t my_folder[MAX_PATH];
- ASSERT_NE(::GetTempPath(MAX_PATH, temp_directory), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, my_folder), 0u);
-
- // Delete the file and create a directory instead.
- ASSERT_TRUE(::DeleteFile(my_folder));
- ASSERT_TRUE(::CreateDirectory(my_folder, NULL));
-
- bool result = true;
- EXPECT_EQ(ERROR_SUCCESS, IsReparsePoint(my_folder, &result));
- EXPECT_FALSE(result);
-
- // We have to fix Bug 32224 to pass this test.
- std::wstring not_found = std::wstring(my_folder) + L"\\foo\\bar";
- // EXPECT_EQ(ERROR_PATH_NOT_FOUND, IsReparsePoint(not_found, &result));
-
- std::wstring new_file = std::wstring(my_folder) + L"\\foo";
- EXPECT_EQ(ERROR_SUCCESS, IsReparsePoint(new_file, &result));
- EXPECT_FALSE(result);
-
- // Replace the directory with a reparse point to %temp%.
- HANDLE dir = ::CreateFile(my_folder, FILE_ALL_ACCESS,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
- EXPECT_NE(INVALID_HANDLE_VALUE, dir);
-
- std::wstring temp_dir_nt = std::wstring(L"\\??\\") + temp_directory;
- EXPECT_TRUE(SetReparsePoint(dir, temp_dir_nt.c_str()));
-
- EXPECT_EQ(ERROR_SUCCESS, IsReparsePoint(new_file, &result));
- EXPECT_TRUE(result);
-
- EXPECT_TRUE(DeleteReparsePoint(dir));
- EXPECT_TRUE(::CloseHandle(dir));
- EXPECT_TRUE(::RemoveDirectory(my_folder));
-}
-
-TEST(WinUtils, SameObject) {
- using sandbox::SameObject;
-
- // Create a temp file because we need write access to it.
- wchar_t temp_directory[MAX_PATH];
- wchar_t my_folder[MAX_PATH];
- ASSERT_NE(::GetTempPath(MAX_PATH, temp_directory), 0u);
- ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, my_folder), 0u);
-
- // Delete the file and create a directory instead.
- ASSERT_TRUE(::DeleteFile(my_folder));
- ASSERT_TRUE(::CreateDirectory(my_folder, NULL));
-
- std::wstring folder(my_folder);
- std::wstring file_name = folder + L"\\foo.txt";
- const ULONG kSharing = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;
- base::win::ScopedHandle file(CreateFile(
- file_name.c_str(), GENERIC_WRITE, kSharing, NULL, CREATE_ALWAYS,
- FILE_FLAG_DELETE_ON_CLOSE, NULL));
-
- EXPECT_TRUE(file.IsValid());
- std::wstring file_name_nt1 = std::wstring(L"\\??\\") + file_name;
- std::wstring file_name_nt2 = std::wstring(L"\\??\\") + folder + L"\\FOO.txT";
- EXPECT_TRUE(SameObject(file.Get(), file_name_nt1.c_str()));
- EXPECT_TRUE(SameObject(file.Get(), file_name_nt2.c_str()));
-
- file.Close();
- EXPECT_TRUE(::RemoveDirectory(my_folder));
-}
diff --git a/sandbox/win/src/window.cc b/sandbox/win/src/window.cc
deleted file mode 100644
index 445cb17..0000000
--- a/sandbox/win/src/window.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sandbox/win/src/window.h"
-
-#include <aclapi.h>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace {
-
-// Gets the security attributes of a window object referenced by |handle|. The
-// lpSecurityDescriptor member of the SECURITY_ATTRIBUTES parameter returned
-// must be freed using LocalFree by the caller.
-bool GetSecurityAttributes(HANDLE handle, SECURITY_ATTRIBUTES* attributes) {
- attributes->bInheritHandle = FALSE;
- attributes->nLength = sizeof(SECURITY_ATTRIBUTES);
-
- PACL dacl = NULL;
- DWORD result = ::GetSecurityInfo(handle, SE_WINDOW_OBJECT,
- DACL_SECURITY_INFORMATION, NULL, NULL, &dacl,
- NULL, &attributes->lpSecurityDescriptor);
- if (ERROR_SUCCESS == result)
- return true;
-
- return false;
-}
-
-}
-
-namespace sandbox {
-
-ResultCode CreateAltWindowStation(HWINSTA* winsta) {
- // Get the security attributes from the current window station; we will
- // use this as the base security attributes for the new window station.
- SECURITY_ATTRIBUTES attributes = {0};
- if (!GetSecurityAttributes(::GetProcessWindowStation(), &attributes)) {
- return SBOX_ERROR_CANNOT_CREATE_WINSTATION;
- }
-
- // Create the window station using NULL for the name to ask the os to
- // generate it.
- // TODO(nsylvain): don't ask for WINSTA_ALL_ACCESS if we don't need to.
- *winsta = ::CreateWindowStationW(NULL, 0, WINSTA_ALL_ACCESS, &attributes);
- LocalFree(attributes.lpSecurityDescriptor);
-
- if (*winsta)
- return SBOX_ALL_OK;
-
- return SBOX_ERROR_CANNOT_CREATE_WINSTATION;
-}
-
-ResultCode CreateAltDesktop(HWINSTA winsta, HDESK* desktop) {
- std::wstring desktop_name = L"sbox_alternate_desktop_";
-
- // Append the current PID to the desktop name.
- wchar_t buffer[16];
- _snwprintf_s(buffer, sizeof(buffer) / sizeof(wchar_t), L"0x%X",
- ::GetCurrentProcessId());
- desktop_name += buffer;
-
- // Get the security attributes from the current desktop, we will use this as
- // the base security attributes for the new desktop.
- SECURITY_ATTRIBUTES attributes = {0};
- if (!GetSecurityAttributes(GetThreadDesktop(GetCurrentThreadId()),
- &attributes)) {
- return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
- }
-
- // Back up the current window station, in case we need to switch it.
- HWINSTA current_winsta = ::GetProcessWindowStation();
-
- if (winsta) {
- // We need to switch to the alternate window station before creating the
- // desktop.
- if (!::SetProcessWindowStation(winsta)) {
- ::LocalFree(attributes.lpSecurityDescriptor);
- return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
- }
- }
-
- // Create the destkop.
- // TODO(nsylvain): don't ask for GENERIC_ALL if we don't need to.
- *desktop = ::CreateDesktop(desktop_name.c_str(), NULL, NULL, 0, GENERIC_ALL,
- &attributes);
- ::LocalFree(attributes.lpSecurityDescriptor);
-
- if (winsta) {
- // Revert to the right window station.
- if (!::SetProcessWindowStation(current_winsta)) {
- return SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION;
- }
- }
-
- if (*desktop)
- return SBOX_ALL_OK;
-
- return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
-}
-
-std::wstring GetWindowObjectName(HANDLE handle) {
- // Get the size of the name.
- DWORD size = 0;
- ::GetUserObjectInformation(handle, UOI_NAME, NULL, 0, &size);
-
- if (!size) {
- NOTREACHED();
- return std::wstring();
- }
-
- // Create the buffer that will hold the name.
- scoped_array<wchar_t> name_buffer(new wchar_t[size]);
-
- // Query the name of the object.
- if (!::GetUserObjectInformation(handle, UOI_NAME, name_buffer.get(), size,
- &size)) {
- NOTREACHED();
- return std::wstring();
- }
-
- return std::wstring(name_buffer.get());
-}
-
-std::wstring GetFullDesktopName(HWINSTA winsta, HDESK desktop) {
- if (!desktop) {
- NOTREACHED();
- return std::wstring();
- }
-
- std::wstring name;
- if (winsta) {
- name = GetWindowObjectName(winsta);
- name += L'\\';
- }
-
- name += GetWindowObjectName(desktop);
- return name;
-}
-
-} // namespace sandbox
diff --git a/sandbox/win/src/window.h b/sandbox/win/src/window.h
deleted file mode 100644
index e8233e7..0000000
--- a/sandbox/win/src/window.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SANDBOX_SRC_WINDOW_H_
-#define SANDBOX_SRC_WINDOW_H_
-
-#include <windows.h>
-#include <string>
-
-#include "sandbox/win/src/sandbox_types.h"
-
-namespace sandbox {
-
- // Creates a window station. The name is generated by the OS. The security
- // descriptor is based on the security descriptor of the current window
- // station.
- ResultCode CreateAltWindowStation(HWINSTA* winsta);
-
- // Creates a desktop. The name is a static string followed by the pid of the
- // current process. The security descriptor on the new desktop is based on the
- // security descriptor of the desktop associated with the current thread.
- // If a winsta is specified, the function will switch to it before creating
- // the desktop. If the functions fails the switch back to the current winsta,
- // the function will return SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION.
- ResultCode CreateAltDesktop(HWINSTA winsta, HDESK* desktop);
-
- // Returns the name of a desktop or a window station.
- std::wstring GetWindowObjectName(HANDLE handle);
-
- // Returns the name of the desktop referenced by |desktop|. If a window
- // station is specified, the name is prepended with the window station name,
- // followed by a backslash. This name can be used as the lpDesktop parameter
- // to CreateProcess.
- std::wstring GetFullDesktopName(HWINSTA winsta, HDESK desktop);
-
-} // namespace sandbox
-
-#endif // SANDBOX_SRC_WINDOW_H_