interception.h revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defines InterceptionManager, the class in charge of setting up interceptions 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the sandboxed process. For more details see 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://dev.chromium.org/developers/design-documents/sandbox . 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SANDBOX_SRC_INTERCEPTION_H_ 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SANDBOX_SRC_INTERCEPTION_H_ 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_types.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TargetProcess; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum InterceptorId; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Internal structures used for communication between the broker and the target. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct DllPatchInfo; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct DllInterceptionData; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The InterceptionManager executes on the parent application, and it is in 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// charge of setting up the desired interceptions, and placing the Interception 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Agent into the child application. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The exposed API consists of two methods: AddToPatchedFunctions to set up a 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// particular interception, and InitializeInterceptions to actually go ahead and 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// perform all interceptions and transfer data to the child application. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The typical usage is something like this: 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InterceptionManager interception_manager(child); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if (!interception_manager.AddToPatchedFunctions( 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// L"ntdll.dll", "NtCreateFile", 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sandbox::INTERCEPTION_SERVICE_CALL, &MyNtCreateFile, MY_ID_1)) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return false; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if (!interception_manager.AddToPatchedFunctions( 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// L"kernel32.dll", "CreateDirectoryW", 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sandbox::INTERCEPTION_EAT, L"MyCreateDirectoryW@12", MY_ID_2)) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return false; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if (!interception_manager.InitializeInterceptions()) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DWORD error = ::GetLastError(); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return false; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Any required syncronization must be performed outside this class. Also, it is 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not possible to perform further interceptions after InitializeInterceptions 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is called. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class InterceptionManager { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The unit test will access private members. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow tests to be marked DISABLED_. Note that FLAKY_ and FAILS_ prefixes 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // do not work with sandbox tests. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(InterceptionManagerTest, BufferLayout1); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(InterceptionManagerTest, BufferLayout2); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An interception manager performs interceptions on a given child process. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are allowed to intercept functions that have been patched by somebody 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // else, relaxed should be set to true. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: We increase the child's reference count internally. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterceptionManager(TargetProcess* child_process, bool relaxed); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~InterceptionManager(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Patches function_name inside dll_name to point to replacement_code_address. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function_name has to be an exported symbol of dll_name. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true on success. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The new function should match the prototype and calling convention of the 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function to intercept except for one extra argument (the first one) that 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contains a pointer to the original function, to simplify the development 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of interceptors (for IA32). In x64, there is no extra argument to the 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interceptor, so the provided InterceptorId is used to keep a table of 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // intercepted functions so that the interceptor can index that table to get 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the pointer that would have been the first argument (g_originals[id]). 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For example, to intercept NtClose, the following code could be used: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // typedef NTSTATUS (WINAPI *NtCloseFunction) (IN HANDLE Handle); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NTSTATUS WINAPI MyNtCose(IN NtCloseFunction OriginalClose, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IN HANDLE Handle) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // // do something 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // // call the original function 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return OriginalClose(Handle); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And in x64: 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // typedef NTSTATUS (WINAPI *NtCloseFunction) (IN HANDLE Handle); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NTSTATUS WINAPI MyNtCose64(IN HANDLE Handle) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // // do something 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // // call the original function 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NtCloseFunction OriginalClose = g_originals[NT_CLOSE_ID]; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return OriginalClose(Handle); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddToPatchedFunctions(const wchar_t* dll_name, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* function_name, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterceptionType interception_type, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* replacement_code_address, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterceptorId id); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Patches function_name inside dll_name to point to 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // replacement_function_name. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddToPatchedFunctions(const wchar_t* dll_name, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* function_name, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterceptionType interception_type, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* replacement_function_name, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterceptorId id); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The interception agent will unload the dll with dll_name. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddToUnloadModules(const wchar_t* dll_name); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes all interceptions on the client. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true on success. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The child process must be created suspended, and cannot be resumed until 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // after this method returns. In addition, no action should be performed on 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the child that may cause it to resume momentarily, such as injecting 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // threads or APCs. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function must be called only once, after all interceptions have been 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // set up using AddToPatchedFunctions. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool InitializeInterceptions(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to store the interception information until the actual set-up. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct InterceptionData { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterceptionType type; // Interception type. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterceptorId id; // Interceptor id. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring dll; // Name of dll to intercept. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string function; // Name of function to intercept. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string interceptor; // Name of interceptor function. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* interceptor_address; // Interceptor's entry point. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calculates the size of the required configuration buffer. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t GetBufferSize() const; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Rounds up the size of a given buffer, considering alignment (padding). 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value is the current size of the buffer, and alignment is specified in 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bytes. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline size_t RoundUpToMultiple(size_t value, size_t alignment) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ((value + alignment -1) / alignment) * alignment; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets up a given buffer with all the information that has to be transfered 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the child. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true on success. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The buffer size should be at least the value returned by GetBufferSize 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SetupConfigBuffer(void* buffer, size_t buffer_bytes); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fills up the part of the transfer buffer that corresponds to information 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // about one dll to patch. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data is the first recorded interception for this dll. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true on success. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On successful return, buffer will be advanced from it's current position 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the point where the next block of configuration data should be written 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (the actual interception info), and the current size of the buffer will 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // decrease to account the space used by this method. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SetupDllInfo(const InterceptionData& data, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void** buffer, size_t* buffer_bytes) const; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fills up the part of the transfer buffer that corresponds to a single 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function to patch. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dll_info points to the dll being updated with the interception stored on 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data. The buffer pointer and remaining size are updated by this call. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true on success. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SetupInterceptionInfo(const InterceptionData& data, void** buffer, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* buffer_bytes, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DllPatchInfo* dll_info) const; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this interception is to be performed by the child 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as opposed to from the parent. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsInterceptionPerformedByChild(const InterceptionData& data) const; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocates a buffer on the child's address space (returned on 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // remote_buffer), and fills it with the contents of a local buffer. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true on success. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CopyDataToChild(const void* local_buffer, size_t buffer_bytes, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void** remote_buffer) const; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs the cold patch (from the parent) of ntdll. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true on success. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method will insert additional interceptions to launch the interceptor 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // agent on the child process, if there are additional interceptions to do. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool PatchNtdll(bool hot_patch_needed); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Peforms the actual interceptions on ntdll. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thunks is the memory to store all the thunks for this dll (on the child), 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and dll_data is a local buffer to hold global dll interception info. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true on success. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool PatchClientFunctions(DllInterceptionData* thunks, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t thunk_bytes, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DllInterceptionData* dll_data); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The process to intercept. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TargetProcess* child_; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Holds all interception info until the call to initialize (perform the 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actual patch). 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<InterceptionData> interceptions_; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keep track of patches added by name. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool names_used_; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // true if we are allowed to patch already-patched functions. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool relaxed_; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(InterceptionManager); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This macro simply calls interception_manager.AddToPatchedFunctions with 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the given service to intercept (INTERCEPTION_SERVICE_CALL), and assumes that 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the interceptor is called "TargetXXX", where XXX is the name of the service. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that num_params is the number of bytes to pop out of the stack for 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the exported interceptor, following the calling convention of a service call 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (WINAPI = with the "C" underscore). 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if SANDBOX_EXPORTS 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_WIN64) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAKE_SERVICE_NAME(service, params) "Target" # service "64" 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAKE_SERVICE_NAME(service, params) "_Target" # service "@" # params 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ADD_NT_INTERCEPTION(service, id, num_params) \ 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddToPatchedFunctions(kNtdllName, #service, \ 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sandbox::INTERCEPTION_SERVICE_CALL, \ 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAKE_SERVICE_NAME(service, num_params), id) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INTERCEPT_NT(manager, service, id, num_params) \ 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((&Target##service) ? \ 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->ADD_NT_INTERCEPTION(service, id, num_params) : false) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// When intercepting the EAT it is important that the patched version of the 2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// function not call any functions imported from system libraries unless 2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// |TargetServices::InitCalled()| returns true, because it is only then that 2478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// we are guaranteed that our IAT has been initialized. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INTERCEPT_EAT(manager, dll, function, id, num_params) \ 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((&Target##function) ? \ 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->AddToPatchedFunctions(dll, #function, sandbox::INTERCEPTION_EAT, \ 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAKE_SERVICE_NAME(function, num_params), \ 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id) : \ 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else // SANDBOX_EXPORTS 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_WIN64) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAKE_SERVICE_NAME(service) &Target##service##64 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAKE_SERVICE_NAME(service) &Target##service 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ADD_NT_INTERCEPTION(service, id, num_params) \ 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddToPatchedFunctions(kNtdllName, #service, \ 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sandbox::INTERCEPTION_SERVICE_CALL, \ 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAKE_SERVICE_NAME(service), id) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INTERCEPT_NT(manager, service, id, num_params) \ 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->ADD_NT_INTERCEPTION(service, id, num_params) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// When intercepting the EAT it is important that the patched version of the 2708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// function not call any functions imported from system libraries unless 2718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// |TargetServices::InitCalled()| returns true, because it is only then that 2728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// we are guaranteed that our IAT has been initialized. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INTERCEPT_EAT(manager, dll, function, id, num_params) \ 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->AddToPatchedFunctions(dll, #function, sandbox::INTERCEPTION_EAT, \ 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAKE_SERVICE_NAME(function), id) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // SANDBOX_EXPORTS 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // SANDBOX_SRC_INTERCEPTION_H_ 281