Home | History | Annotate | Download | only in src
      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.
     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) ? (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 
     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__
    174