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