Index: sandbox/win/src/interception.h |
diff --git a/sandbox/win/src/interception.h b/sandbox/win/src/interception.h |
deleted file mode 100644 |
index 4d1ee82ba39948df8dafa0b26749b4cfafcfcc9b..0000000000000000000000000000000000000000 |
--- a/sandbox/win/src/interception.h |
+++ /dev/null |
@@ -1,286 +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 <stddef.h> |
- |
-#include <list> |
-#include <string> |
- |
-#include "base/gtest_prod_util.h" |
-#include "base/macros.h" |
-#include "base/strings/string16.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 { |
- InterceptionData(); |
- ~InterceptionData(); |
- |
- InterceptionType type; // Interception type. |
- InterceptorId id; // Interceptor id. |
- base::string16 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) |
- |
-// When intercepting the EAT it is important that the patched version of the |
-// function not call any functions imported from system libraries unless |
-// |TargetServices::InitCalled()| returns true, because it is only then that |
-// we are guaranteed that our IAT has been initialized. |
-#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) |
- |
-// When intercepting the EAT it is important that the patched version of the |
-// function not call any functions imported from system libraries unless |
-// |TargetServices::InitCalled()| returns true, because it is only then that |
-// we are guaranteed that our IAT has been initialized. |
-#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_ |