15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2010 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 ResolverThunk, the interface for classes that perform interceptions. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For more details see 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://dev.chromium.org/developers/design-documents/sandbox . 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/nt_internals.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SANDBOX_SRC_RESOLVER_H__ 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SANDBOX_SRC_RESOLVER_H__ 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A resolver is the object in charge of performing the actual interception of 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a function. There should be a concrete implementation of a resolver roughly 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// per type of interception. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ResolverThunk { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolverThunk() {} 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ResolverThunk() {} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs the actual interception of a function. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target_name is an exported function from the module loaded at 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target_module, and must be replaced by interceptor_name, exported from 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interceptor_module. interceptor_entry_point can be provided instead of 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interceptor_name / interceptor_module. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thunk_storage must point to a buffer on the child's address space, to hold 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the patch thunk, and related data. If provided, storage_used will receive 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the number of bytes used from thunk_storage. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Example: (without error checking) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size_t size = resolver.GetThunkSize(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // char* buffer = ::VirtualAllocEx(child_process, NULL, size, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MEM_COMMIT, PAGE_READWRITE); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // resolver.Setup(ntdll_module, NULL, L"NtCreateFile", NULL, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // &MyReplacementFunction, buffer, size, NULL); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In general, the idea is to allocate a single big buffer for all 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interceptions on the same dll, and call Setup n times. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WARNING: This means that any data member that is specific to a single 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interception must be reset within this method. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual NTSTATUS Setup(const void* target_module, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* interceptor_module, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* target_name, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* interceptor_name, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* interceptor_entry_point, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* thunk_storage, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t storage_bytes, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* storage_used) = 0; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets the address of function_name inside module (main exe). 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual NTSTATUS ResolveInterceptor(const void* module, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* function_name, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void** address); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets the address of an exported function_name inside module. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual NTSTATUS ResolveTarget(const void* module, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* function_name, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void** address); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets the required buffer size for this type of thunk. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual size_t GetThunkSize() const = 0; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs basic initialization on behalf of a concrete instance of a 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // resolver. That is, parameter validation and resolution of the target 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and the interceptor into the member variables. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target_name is an exported function from the module loaded at 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target_module, and must be replaced by interceptor_name, exported from 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interceptor_module. interceptor_entry_point can be provided instead of 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interceptor_name / interceptor_module. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thunk_storage must point to a buffer on the child's address space, to hold 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the patch thunk, and related data. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual NTSTATUS Init(const void* target_module, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* interceptor_module, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* target_name, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* interceptor_name, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* interceptor_entry_point, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* thunk_storage, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t storage_bytes); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets the required buffer size for the internal part of the thunk. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t GetInternalThunkSize() const; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes the internal part of the thunk. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interceptor is the function to be called instead of original_function. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SetInternalThunk(void* storage, size_t storage_bytes, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* original_function, const void* interceptor); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Holds the resolved interception target. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* target_; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Holds the resolved interception interceptor. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* interceptor_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ResolverThunk); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // SANDBOX_SRC_RESOLVER_H__ 106