OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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_SANDBOX_NT_UTIL_H_ | |
6 #define SANDBOX_SRC_SANDBOX_NT_UTIL_H_ | |
7 | |
8 #include "base/basictypes.h" | |
9 #include "sandbox/src/nt_internals.h" | |
10 #include "sandbox/src/sandbox_nt_types.h" | |
11 | |
12 // Placement new and delete to be used from ntdll interception code. | |
13 void* __cdecl operator new(size_t size, sandbox::AllocationType type, | |
14 void* near_to = NULL); | |
15 void __cdecl operator delete(void* memory, sandbox::AllocationType type); | |
16 // Add operator delete that matches the placement form of the operator new | |
17 // above. This is required by compiler to generate code to call operator delete | |
18 // in case the object's constructor throws an exception. | |
19 // See http://msdn.microsoft.com/en-us/library/cxdxz3x6.aspx | |
20 void __cdecl operator delete(void* memory, sandbox::AllocationType type, | |
21 void* near_to); | |
22 | |
23 // Regular placement new and delete | |
24 void* __cdecl operator new(size_t size, void* buffer, | |
25 sandbox::AllocationType type); | |
26 void __cdecl operator delete(void* memory, void* buffer, | |
27 sandbox::AllocationType type); | |
28 | |
29 // DCHECK_NT is defined to be pretty much an assert at this time because we | |
30 // don't have logging from the ntdll layer on the child. | |
31 // | |
32 // VERIFY_NT and VERIFY_SUCCESS_NT are the standard asserts on debug, but | |
33 // execute the actual argument on release builds. VERIFY_NT expects an action | |
34 // returning a bool, while VERIFY_SUCCESS_NT expects an action returning | |
35 // NTSTATUS. | |
36 #ifndef NDEBUG | |
37 #define DCHECK_NT(condition) { (condition) ? 0 : __debugbreak(); } | |
38 #define VERIFY(action) DCHECK_NT(action) | |
39 #define VERIFY_SUCCESS(action) DCHECK_NT(NT_SUCCESS(action)) | |
40 #else | |
41 #define DCHECK_NT(condition) | |
42 #define VERIFY(action) (action) | |
43 #define VERIFY_SUCCESS(action) (action) | |
44 #endif | |
45 | |
46 #define NOTREACHED_NT() DCHECK_NT(false) | |
47 | |
48 namespace sandbox { | |
49 | |
50 extern "C" long _InterlockedCompareExchange(long volatile* destination, | |
51 long exchange, long comperand); | |
52 | |
53 #pragma intrinsic(_InterlockedCompareExchange) | |
54 | |
55 // We want to make sure that we use an intrinsic version of the function, not | |
56 // the one provided by kernel32. | |
57 __forceinline void* _InterlockedCompareExchangePointer( | |
58 void* volatile* destination, void* exchange, void* comperand) { | |
59 size_t ret = _InterlockedCompareExchange( | |
60 reinterpret_cast<long volatile*>(destination), | |
61 static_cast<long>(reinterpret_cast<size_t>(exchange)), | |
62 static_cast<long>(reinterpret_cast<size_t>(comperand))); | |
63 | |
64 return reinterpret_cast<void*>(static_cast<size_t>(ret)); | |
65 } | |
66 | |
67 // Returns a pointer to the IPC shared memory. | |
68 void* GetGlobalIPCMemory(); | |
69 | |
70 // Returns a pointer to the Policy shared memory. | |
71 void* GetGlobalPolicyMemory(); | |
72 | |
73 enum RequiredAccess { | |
74 READ, | |
75 WRITE | |
76 }; | |
77 | |
78 // Performs basic user mode buffer validation. In any case, buffers access must | |
79 // be protected by SEH. intent specifies if the buffer should be tested for read | |
80 // or write. | |
81 // Note that write intent implies destruction of the buffer content (we actually | |
82 // write) | |
83 bool ValidParameter(void* buffer, size_t size, RequiredAccess intent); | |
84 | |
85 | |
86 // Copies data from a user buffer to our buffer. Returns the operation status. | |
87 NTSTATUS CopyData(void* destination, const void* source, size_t bytes); | |
88 | |
89 // Copies the name from an object attributes. | |
90 NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object, | |
91 wchar_t** out_name, uint32* attributes, HANDLE* root); | |
92 | |
93 // Initializes our ntdll level heap | |
94 bool InitHeap(); | |
95 | |
96 // Returns true if the provided handle refers to the current process. | |
97 bool IsSameProcess(HANDLE process); | |
98 | |
99 enum MappedModuleFlags { | |
100 MODULE_IS_PE_IMAGE = 1, // Module is an executable. | |
101 MODULE_HAS_ENTRY_POINT = 2, // Execution entry point found. | |
102 MODULE_HAS_CODE = 4 // Non zero size of executable sections. | |
103 }; | |
104 | |
105 // Returns the name and characteristics for a given PE module. The return | |
106 // value is the name as defined by the export table and the flags is any | |
107 // combination of the MappedModuleFlags enumeration. | |
108 // | |
109 // The returned buffer must be freed with a placement delete from the ntdll | |
110 // level allocator: | |
111 // | |
112 // UNICODE_STRING* name = GetPEImageInfoFromModule(HMODULE module, &flags); | |
113 // if (!name) { | |
114 // // probably not a valid dll | |
115 // return; | |
116 // } | |
117 // InsertYourLogicHere(name); | |
118 // operator delete(name, NT_ALLOC); | |
119 UNICODE_STRING* GetImageInfoFromModule(HMODULE module, uint32* flags); | |
120 | |
121 // Returns the full path and filename for a given dll. | |
122 // May return NULL if the provided address is not backed by a named section, or | |
123 // if the current OS version doesn't support the call. The returned buffer must | |
124 // be freed with a placement delete (see GetImageNameFromModule example). | |
125 UNICODE_STRING* GetBackingFilePath(PVOID address); | |
126 | |
127 // Returns the last component of a path that contains the module name. | |
128 // It will return NULL if the path ends with the path separator. The returned | |
129 // buffer must be freed with a placement delete (see GetImageNameFromModule | |
130 // example). | |
131 UNICODE_STRING* ExtractModuleName(const UNICODE_STRING* module_path); | |
132 | |
133 // Returns true if the parameters correspond to a dll mapped as code. | |
134 bool IsValidImageSection(HANDLE section, PVOID *base, PLARGE_INTEGER offset, | |
135 PSIZE_T view_size); | |
136 | |
137 // Converts an ansi string to an UNICODE_STRING. | |
138 UNICODE_STRING* AnsiToUnicode(const char* string); | |
139 | |
140 // Provides a simple way to temporarily change the protection of a memory page. | |
141 class AutoProtectMemory { | |
142 public: | |
143 AutoProtectMemory() | |
144 : changed_(false), address_(NULL), bytes_(0), old_protect_(0) {} | |
145 | |
146 ~AutoProtectMemory() { | |
147 RevertProtection(); | |
148 } | |
149 | |
150 // Sets the desired protection of a given memory range. | |
151 NTSTATUS ChangeProtection(void* address, size_t bytes, ULONG protect); | |
152 | |
153 // Restores the original page protection. | |
154 NTSTATUS RevertProtection(); | |
155 | |
156 private: | |
157 bool changed_; | |
158 void* address_; | |
159 size_t bytes_; | |
160 ULONG old_protect_; | |
161 | |
162 DISALLOW_COPY_AND_ASSIGN(AutoProtectMemory); | |
163 }; | |
164 | |
165 // Returns true if the file_rename_information structure is supported by our | |
166 // rename handler. | |
167 bool IsSupportedRenameCall(FILE_RENAME_INFORMATION* file_info, DWORD length, | |
168 uint32 file_info_class); | |
169 | |
170 } // namespace sandbox | |
171 | |
172 | |
173 #endif // SANDBOX_SRC_SANDBOX_NT_UTIL_H__ | |
OLD | NEW |