sandbox_nt_util.h revision 868fa2fe829687343ffae624259930155e16dbd8
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/win/src/nt_internals.h" 10#include "sandbox/win/src/sandbox_nt_types.h" 11 12// Placement new and delete to be used from ntdll interception code. 13void* __cdecl operator new(size_t size, sandbox::AllocationType type, 14 void* near_to = NULL); 15void __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 20void __cdecl operator delete(void* memory, sandbox::AllocationType type, 21 void* near_to); 22 23// Regular placement new and delete 24void* __cdecl operator new(size_t size, void* buffer, 25 sandbox::AllocationType type); 26void __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) ? (void)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 48namespace sandbox { 49 50extern "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. 68void* GetGlobalIPCMemory(); 69 70// Returns a pointer to the Policy shared memory. 71void* GetGlobalPolicyMemory(); 72 73enum 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) 83bool ValidParameter(void* buffer, size_t size, RequiredAccess intent); 84 85 86// Copies data from a user buffer to our buffer. Returns the operation status. 87NTSTATUS CopyData(void* destination, const void* source, size_t bytes); 88 89// Copies the name from an object attributes. 90NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object, 91 wchar_t** out_name, uint32* attributes, HANDLE* root); 92 93// Initializes our ntdll level heap 94bool InitHeap(); 95 96// Returns true if the provided handle refers to the current process. 97bool IsSameProcess(HANDLE process); 98 99enum 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); 119UNICODE_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). 125UNICODE_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). 131UNICODE_STRING* ExtractModuleName(const UNICODE_STRING* module_path); 132 133// Returns true if the parameters correspond to a dll mapped as code. 134bool IsValidImageSection(HANDLE section, PVOID *base, PLARGE_INTEGER offset, 135 PSIZE_T view_size); 136 137// Converts an ansi string to an UNICODE_STRING. 138UNICODE_STRING* AnsiToUnicode(const char* string); 139 140// Provides a simple way to temporarily change the protection of a memory page. 141class 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. 167bool 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__ 174