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