michael@0: // Copyright (c) 2010 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: // Defines ResolverThunk, the interface for classes that perform interceptions. michael@0: // For more details see michael@0: // http://dev.chromium.org/developers/design-documents/sandbox . michael@0: michael@0: #include "base/basictypes.h" michael@0: #include "sandbox/win/src/nt_internals.h" michael@0: michael@0: #ifndef SANDBOX_SRC_RESOLVER_H__ michael@0: #define SANDBOX_SRC_RESOLVER_H__ michael@0: michael@0: namespace sandbox { michael@0: michael@0: // A resolver is the object in charge of performing the actual interception of michael@0: // a function. There should be a concrete implementation of a resolver roughly michael@0: // per type of interception. michael@0: class ResolverThunk { michael@0: public: michael@0: ResolverThunk() {} michael@0: virtual ~ResolverThunk() {} michael@0: michael@0: // Performs the actual interception of a function. michael@0: // target_name is an exported function from the module loaded at michael@0: // target_module, and must be replaced by interceptor_name, exported from michael@0: // interceptor_module. interceptor_entry_point can be provided instead of michael@0: // interceptor_name / interceptor_module. michael@0: // thunk_storage must point to a buffer on the child's address space, to hold michael@0: // the patch thunk, and related data. If provided, storage_used will receive michael@0: // the number of bytes used from thunk_storage. michael@0: // michael@0: // Example: (without error checking) michael@0: // michael@0: // size_t size = resolver.GetThunkSize(); michael@0: // char* buffer = ::VirtualAllocEx(child_process, NULL, size, michael@0: // MEM_COMMIT, PAGE_READWRITE); michael@0: // resolver.Setup(ntdll_module, NULL, L"NtCreateFile", NULL, michael@0: // &MyReplacementFunction, buffer, size, NULL); michael@0: // michael@0: // In general, the idea is to allocate a single big buffer for all michael@0: // interceptions on the same dll, and call Setup n times. michael@0: // WARNING: This means that any data member that is specific to a single michael@0: // interception must be reset within this method. michael@0: virtual NTSTATUS Setup(const void* target_module, michael@0: const void* interceptor_module, michael@0: const char* target_name, michael@0: const char* interceptor_name, michael@0: const void* interceptor_entry_point, michael@0: void* thunk_storage, michael@0: size_t storage_bytes, michael@0: size_t* storage_used) = 0; michael@0: michael@0: // Gets the address of function_name inside module (main exe). michael@0: virtual NTSTATUS ResolveInterceptor(const void* module, michael@0: const char* function_name, michael@0: const void** address); michael@0: michael@0: // Gets the address of an exported function_name inside module. michael@0: virtual NTSTATUS ResolveTarget(const void* module, michael@0: const char* function_name, michael@0: void** address); michael@0: michael@0: // Gets the required buffer size for this type of thunk. michael@0: virtual size_t GetThunkSize() const = 0; michael@0: michael@0: protected: michael@0: // Performs basic initialization on behalf of a concrete instance of a michael@0: // resolver. That is, parameter validation and resolution of the target michael@0: // and the interceptor into the member variables. michael@0: // michael@0: // target_name is an exported function from the module loaded at michael@0: // target_module, and must be replaced by interceptor_name, exported from michael@0: // interceptor_module. interceptor_entry_point can be provided instead of michael@0: // interceptor_name / interceptor_module. michael@0: // thunk_storage must point to a buffer on the child's address space, to hold michael@0: // the patch thunk, and related data. michael@0: virtual NTSTATUS Init(const void* target_module, michael@0: const void* interceptor_module, michael@0: const char* target_name, michael@0: const char* interceptor_name, michael@0: const void* interceptor_entry_point, michael@0: void* thunk_storage, michael@0: size_t storage_bytes); michael@0: michael@0: // Gets the required buffer size for the internal part of the thunk. michael@0: size_t GetInternalThunkSize() const; michael@0: michael@0: // Initializes the internal part of the thunk. michael@0: // interceptor is the function to be called instead of original_function. michael@0: bool SetInternalThunk(void* storage, size_t storage_bytes, michael@0: const void* original_function, const void* interceptor); michael@0: michael@0: // Holds the resolved interception target. michael@0: void* target_; michael@0: // Holds the resolved interception interceptor. michael@0: const void* interceptor_; michael@0: michael@0: DISALLOW_COPY_AND_ASSIGN(ResolverThunk); michael@0: }; michael@0: michael@0: } // namespace sandbox michael@0: michael@0: #endif // SANDBOX_SRC_RESOLVER_H__