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