1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef SANDBOX_SRC_SERVICE_RESOLVER_H__ 6 #define SANDBOX_SRC_SERVICE_RESOLVER_H__ 7 8 #include <stddef.h> 9 10 #include "base/macros.h" 11 #include "sandbox/win/src/nt_internals.h" 12 #include "sandbox/win/src/resolver.h" 13 14 namespace sandbox { 15 16 // This is the concrete resolver used to perform service-call type functions 17 // inside ntdll.dll. 18 class ServiceResolverThunk : public ResolverThunk { 19 public: 20 // The service resolver needs a child process to write to. ServiceResolverThunk(HANDLE process,bool relaxed)21 ServiceResolverThunk(HANDLE process, bool relaxed) 22 : ntdll_base_(NULL), 23 process_(process), 24 relaxed_(relaxed), 25 relative_jump_(0) {} ~ServiceResolverThunk()26 ~ServiceResolverThunk() override {} 27 28 // Implementation of Resolver::Setup. 29 NTSTATUS Setup(const void* target_module, 30 const void* interceptor_module, 31 const char* target_name, 32 const char* interceptor_name, 33 const void* interceptor_entry_point, 34 void* thunk_storage, 35 size_t storage_bytes, 36 size_t* storage_used) override; 37 38 // Implementation of Resolver::ResolveInterceptor. 39 NTSTATUS ResolveInterceptor(const void* module, 40 const char* function_name, 41 const void** address) override; 42 43 // Implementation of Resolver::ResolveTarget. 44 NTSTATUS ResolveTarget(const void* module, 45 const char* function_name, 46 void** address) override; 47 48 // Implementation of Resolver::GetThunkSize. 49 size_t GetThunkSize() const override; 50 51 // Call this to set up ntdll_base_ which will allow for local patches. 52 virtual void AllowLocalPatches(); 53 54 // Verifies that the function specified by |target_name| in |target_module| is 55 // a service and copies the data from that function into |thunk_storage|. If 56 // |storage_bytes| is too small, then the method fails. 57 virtual NTSTATUS CopyThunk(const void* target_module, 58 const char* target_name, 59 BYTE* thunk_storage, 60 size_t storage_bytes, 61 size_t* storage_used); 62 63 protected: 64 // The unit test will use this member to allow local patch on a buffer. 65 HMODULE ntdll_base_; 66 67 // Handle of the child process. 68 HANDLE process_; 69 70 private: 71 // Returns true if the code pointer by target_ corresponds to the expected 72 // type of function. Saves that code on the first part of the thunk pointed 73 // by local_thunk (should be directly accessible from the parent). 74 virtual bool IsFunctionAService(void* local_thunk) const; 75 76 // Performs the actual patch of target_. 77 // local_thunk must be already fully initialized, and the first part must 78 // contain the original code. The real type of this buffer is ServiceFullThunk 79 // (yes, private). remote_thunk (real type ServiceFullThunk), must be 80 // allocated on the child, and will contain the thunk data, after this call. 81 // Returns the apropriate status code. 82 virtual NTSTATUS PerformPatch(void* local_thunk, void* remote_thunk); 83 84 // Provides basically the same functionality as IsFunctionAService but it 85 // continues even if it does not recognize the function code. remote_thunk 86 // is the address of our memory on the child. 87 bool SaveOriginalFunction(void* local_thunk, void* remote_thunk); 88 89 // true if we are allowed to patch already-patched functions. 90 bool relaxed_; 91 ULONG relative_jump_; 92 93 DISALLOW_COPY_AND_ASSIGN(ServiceResolverThunk); 94 }; 95 96 // This is the concrete resolver used to perform service-call type functions 97 // inside ntdll.dll on WOW64 (32 bit ntdll on 64 bit Vista). 98 class Wow64ResolverThunk : public ServiceResolverThunk { 99 public: 100 // The service resolver needs a child process to write to. Wow64ResolverThunk(HANDLE process,bool relaxed)101 Wow64ResolverThunk(HANDLE process, bool relaxed) 102 : ServiceResolverThunk(process, relaxed) {} ~Wow64ResolverThunk()103 ~Wow64ResolverThunk() override {} 104 105 private: 106 bool IsFunctionAService(void* local_thunk) const override; 107 108 DISALLOW_COPY_AND_ASSIGN(Wow64ResolverThunk); 109 }; 110 111 // This is the concrete resolver used to perform service-call type functions 112 // inside ntdll.dll on WOW64 for Windows 8. 113 class Wow64W8ResolverThunk : public ServiceResolverThunk { 114 public: 115 // The service resolver needs a child process to write to. Wow64W8ResolverThunk(HANDLE process,bool relaxed)116 Wow64W8ResolverThunk(HANDLE process, bool relaxed) 117 : ServiceResolverThunk(process, relaxed) {} ~Wow64W8ResolverThunk()118 ~Wow64W8ResolverThunk() override {} 119 120 private: 121 bool IsFunctionAService(void* local_thunk) const override; 122 123 DISALLOW_COPY_AND_ASSIGN(Wow64W8ResolverThunk); 124 }; 125 126 // This is the concrete resolver used to perform service-call type functions 127 // inside ntdll.dll on Windows 8. 128 class Win8ResolverThunk : public ServiceResolverThunk { 129 public: 130 // The service resolver needs a child process to write to. Win8ResolverThunk(HANDLE process,bool relaxed)131 Win8ResolverThunk(HANDLE process, bool relaxed) 132 : ServiceResolverThunk(process, relaxed) {} ~Win8ResolverThunk()133 ~Win8ResolverThunk() override {} 134 135 private: 136 bool IsFunctionAService(void* local_thunk) const override; 137 138 DISALLOW_COPY_AND_ASSIGN(Win8ResolverThunk); 139 }; 140 141 // This is the concrete resolver used to perform service-call type functions 142 // inside ntdll.dll on WOW64 for Windows 10. 143 class Wow64W10ResolverThunk : public ServiceResolverThunk { 144 public: 145 // The service resolver needs a child process to write to. Wow64W10ResolverThunk(HANDLE process,bool relaxed)146 Wow64W10ResolverThunk(HANDLE process, bool relaxed) 147 : ServiceResolverThunk(process, relaxed) {} ~Wow64W10ResolverThunk()148 ~Wow64W10ResolverThunk() override {} 149 150 private: 151 bool IsFunctionAService(void* local_thunk) const override; 152 153 DISALLOW_COPY_AND_ASSIGN(Wow64W10ResolverThunk); 154 }; 155 156 } // namespace sandbox 157 158 159 #endif // SANDBOX_SRC_SERVICE_RESOLVER_H__ 160