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