security/sandbox/chromium/base/win/pe_image.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
michael@0 2 // Use of this source code is governed by a BSD-style license that can be
michael@0 3 // found in the LICENSE file.
michael@0 4
michael@0 5 // This file was adapted from GreenBorder's Code.
michael@0 6 // To understand what this class is about (for other than well known functions
michael@0 7 // as GetProcAddress), a good starting point is "An In-Depth Look into the
michael@0 8 // Win32 Portable Executable File Format" by Matt Pietrek:
michael@0 9 // http://msdn.microsoft.com/msdnmag/issues/02/02/PE/default.aspx
michael@0 10
michael@0 11 #ifndef BASE_WIN_PE_IMAGE_H_
michael@0 12 #define BASE_WIN_PE_IMAGE_H_
michael@0 13
michael@0 14 #include <windows.h>
michael@0 15
michael@0 16 #if defined(_WIN32_WINNT_WIN8)
michael@0 17 // The Windows 8 SDK defines FACILITY_VISUALCPP in winerror.h.
michael@0 18 #undef FACILITY_VISUALCPP
michael@0 19 #endif
michael@0 20 #include <DelayIMP.h>
michael@0 21
michael@0 22 namespace base {
michael@0 23 namespace win {
michael@0 24
michael@0 25 // This class is a wrapper for the Portable Executable File Format (PE).
michael@0 26 // It's main purpose is to provide an easy way to work with imports and exports
michael@0 27 // from a file, mapped in memory as image.
michael@0 28 class PEImage {
michael@0 29 public:
michael@0 30 // Callback to enumerate sections.
michael@0 31 // cookie is the value passed to the enumerate method.
michael@0 32 // Returns true to continue the enumeration.
michael@0 33 typedef bool (*EnumSectionsFunction)(const PEImage &image,
michael@0 34 PIMAGE_SECTION_HEADER header,
michael@0 35 PVOID section_start, DWORD section_size,
michael@0 36 PVOID cookie);
michael@0 37
michael@0 38 // Callback to enumerate exports.
michael@0 39 // function is the actual address of the symbol. If forward is not null, it
michael@0 40 // contains the dll and symbol to forward this export to. cookie is the value
michael@0 41 // passed to the enumerate method.
michael@0 42 // Returns true to continue the enumeration.
michael@0 43 typedef bool (*EnumExportsFunction)(const PEImage &image, DWORD ordinal,
michael@0 44 DWORD hint, LPCSTR name, PVOID function,
michael@0 45 LPCSTR forward, PVOID cookie);
michael@0 46
michael@0 47 // Callback to enumerate import blocks.
michael@0 48 // name_table and iat point to the imports name table and address table for
michael@0 49 // this block. cookie is the value passed to the enumerate method.
michael@0 50 // Returns true to continue the enumeration.
michael@0 51 typedef bool (*EnumImportChunksFunction)(const PEImage &image, LPCSTR module,
michael@0 52 PIMAGE_THUNK_DATA name_table,
michael@0 53 PIMAGE_THUNK_DATA iat, PVOID cookie);
michael@0 54
michael@0 55 // Callback to enumerate imports.
michael@0 56 // module is the dll that exports this symbol. cookie is the value passed to
michael@0 57 // the enumerate method.
michael@0 58 // Returns true to continue the enumeration.
michael@0 59 typedef bool (*EnumImportsFunction)(const PEImage &image, LPCSTR module,
michael@0 60 DWORD ordinal, LPCSTR name, DWORD hint,
michael@0 61 PIMAGE_THUNK_DATA iat, PVOID cookie);
michael@0 62
michael@0 63 // Callback to enumerate dalayed import blocks.
michael@0 64 // module is the dll that exports this block of symbols. cookie is the value
michael@0 65 // passed to the enumerate method.
michael@0 66 // Returns true to continue the enumeration.
michael@0 67 typedef bool (*EnumDelayImportChunksFunction)(const PEImage &image,
michael@0 68 PImgDelayDescr delay_descriptor,
michael@0 69 LPCSTR module,
michael@0 70 PIMAGE_THUNK_DATA name_table,
michael@0 71 PIMAGE_THUNK_DATA iat,
michael@0 72 PIMAGE_THUNK_DATA bound_iat,
michael@0 73 PIMAGE_THUNK_DATA unload_iat,
michael@0 74 PVOID cookie);
michael@0 75
michael@0 76 // Callback to enumerate relocations.
michael@0 77 // cookie is the value passed to the enumerate method.
michael@0 78 // Returns true to continue the enumeration.
michael@0 79 typedef bool (*EnumRelocsFunction)(const PEImage &image, WORD type,
michael@0 80 PVOID address, PVOID cookie);
michael@0 81
michael@0 82 explicit PEImage(HMODULE module) : module_(module) {}
michael@0 83 explicit PEImage(const void* module) {
michael@0 84 module_ = reinterpret_cast<HMODULE>(const_cast<void*>(module));
michael@0 85 }
michael@0 86
michael@0 87 // Gets the HMODULE for this object.
michael@0 88 HMODULE module() const;
michael@0 89
michael@0 90 // Sets this object's HMODULE.
michael@0 91 void set_module(HMODULE module);
michael@0 92
michael@0 93 // Checks if this symbol is actually an ordinal.
michael@0 94 static bool IsOrdinal(LPCSTR name);
michael@0 95
michael@0 96 // Converts a named symbol to the corresponding ordinal.
michael@0 97 static WORD ToOrdinal(LPCSTR name);
michael@0 98
michael@0 99 // Returns the DOS_HEADER for this PE.
michael@0 100 PIMAGE_DOS_HEADER GetDosHeader() const;
michael@0 101
michael@0 102 // Returns the NT_HEADER for this PE.
michael@0 103 PIMAGE_NT_HEADERS GetNTHeaders() const;
michael@0 104
michael@0 105 // Returns number of sections of this PE.
michael@0 106 WORD GetNumSections() const;
michael@0 107
michael@0 108 // Returns the header for a given section.
michael@0 109 // returns NULL if there is no such section.
michael@0 110 PIMAGE_SECTION_HEADER GetSectionHeader(UINT section) const;
michael@0 111
michael@0 112 // Returns the size of a given directory entry.
michael@0 113 DWORD GetImageDirectoryEntrySize(UINT directory) const;
michael@0 114
michael@0 115 // Returns the address of a given directory entry.
michael@0 116 PVOID GetImageDirectoryEntryAddr(UINT directory) const;
michael@0 117
michael@0 118 // Returns the section header for a given address.
michael@0 119 // Use: s = image.GetImageSectionFromAddr(a);
michael@0 120 // Post: 's' is the section header of the section that contains 'a'
michael@0 121 // or NULL if there is no such section.
michael@0 122 PIMAGE_SECTION_HEADER GetImageSectionFromAddr(PVOID address) const;
michael@0 123
michael@0 124 // Returns the section header for a given section.
michael@0 125 PIMAGE_SECTION_HEADER GetImageSectionHeaderByName(LPCSTR section_name) const;
michael@0 126
michael@0 127 // Returns the first block of imports.
michael@0 128 PIMAGE_IMPORT_DESCRIPTOR GetFirstImportChunk() const;
michael@0 129
michael@0 130 // Returns the exports directory.
michael@0 131 PIMAGE_EXPORT_DIRECTORY GetExportDirectory() const;
michael@0 132
michael@0 133 // Returns a given export entry.
michael@0 134 // Use: e = image.GetExportEntry(f);
michael@0 135 // Pre: 'f' is either a zero terminated string or ordinal
michael@0 136 // Post: 'e' is a pointer to the export directory entry
michael@0 137 // that contains 'f's export RVA, or NULL if 'f'
michael@0 138 // is not exported from this image
michael@0 139 PDWORD GetExportEntry(LPCSTR name) const;
michael@0 140
michael@0 141 // Returns the address for a given exported symbol.
michael@0 142 // Use: p = image.GetProcAddress(f);
michael@0 143 // Pre: 'f' is either a zero terminated string or ordinal.
michael@0 144 // Post: if 'f' is a non-forwarded export from image, 'p' is
michael@0 145 // the exported function. If 'f' is a forwarded export
michael@0 146 // then p is the special value 0xFFFFFFFF. In this case
michael@0 147 // RVAToAddr(*GetExportEntry) can be used to resolve
michael@0 148 // the string that describes the forward.
michael@0 149 FARPROC GetProcAddress(LPCSTR function_name) const;
michael@0 150
michael@0 151 // Retrieves the ordinal for a given exported symbol.
michael@0 152 // Returns true if the symbol was found.
michael@0 153 bool GetProcOrdinal(LPCSTR function_name, WORD *ordinal) const;
michael@0 154
michael@0 155 // Enumerates PE sections.
michael@0 156 // cookie is a generic cookie to pass to the callback.
michael@0 157 // Returns true on success.
michael@0 158 bool EnumSections(EnumSectionsFunction callback, PVOID cookie) const;
michael@0 159
michael@0 160 // Enumerates PE exports.
michael@0 161 // cookie is a generic cookie to pass to the callback.
michael@0 162 // Returns true on success.
michael@0 163 bool EnumExports(EnumExportsFunction callback, PVOID cookie) const;
michael@0 164
michael@0 165 // Enumerates PE imports.
michael@0 166 // cookie is a generic cookie to pass to the callback.
michael@0 167 // Returns true on success.
michael@0 168 bool EnumAllImports(EnumImportsFunction callback, PVOID cookie) const;
michael@0 169
michael@0 170 // Enumerates PE import blocks.
michael@0 171 // cookie is a generic cookie to pass to the callback.
michael@0 172 // Returns true on success.
michael@0 173 bool EnumImportChunks(EnumImportChunksFunction callback, PVOID cookie) const;
michael@0 174
michael@0 175 // Enumerates the imports from a single PE import block.
michael@0 176 // cookie is a generic cookie to pass to the callback.
michael@0 177 // Returns true on success.
michael@0 178 bool EnumOneImportChunk(EnumImportsFunction callback, LPCSTR module_name,
michael@0 179 PIMAGE_THUNK_DATA name_table, PIMAGE_THUNK_DATA iat,
michael@0 180 PVOID cookie) const;
michael@0 181
michael@0 182
michael@0 183 // Enumerates PE delay imports.
michael@0 184 // cookie is a generic cookie to pass to the callback.
michael@0 185 // Returns true on success.
michael@0 186 bool EnumAllDelayImports(EnumImportsFunction callback, PVOID cookie) const;
michael@0 187
michael@0 188 // Enumerates PE delay import blocks.
michael@0 189 // cookie is a generic cookie to pass to the callback.
michael@0 190 // Returns true on success.
michael@0 191 bool EnumDelayImportChunks(EnumDelayImportChunksFunction callback,
michael@0 192 PVOID cookie) const;
michael@0 193
michael@0 194 // Enumerates imports from a single PE delay import block.
michael@0 195 // cookie is a generic cookie to pass to the callback.
michael@0 196 // Returns true on success.
michael@0 197 bool EnumOneDelayImportChunk(EnumImportsFunction callback,
michael@0 198 PImgDelayDescr delay_descriptor,
michael@0 199 LPCSTR module_name,
michael@0 200 PIMAGE_THUNK_DATA name_table,
michael@0 201 PIMAGE_THUNK_DATA iat,
michael@0 202 PIMAGE_THUNK_DATA bound_iat,
michael@0 203 PIMAGE_THUNK_DATA unload_iat,
michael@0 204 PVOID cookie) const;
michael@0 205
michael@0 206 // Enumerates PE relocation entries.
michael@0 207 // cookie is a generic cookie to pass to the callback.
michael@0 208 // Returns true on success.
michael@0 209 bool EnumRelocs(EnumRelocsFunction callback, PVOID cookie) const;
michael@0 210
michael@0 211 // Verifies the magic values on the PE file.
michael@0 212 // Returns true if all values are correct.
michael@0 213 bool VerifyMagic() const;
michael@0 214
michael@0 215 // Converts an rva value to the appropriate address.
michael@0 216 virtual PVOID RVAToAddr(DWORD rva) const;
michael@0 217
michael@0 218 // Converts an rva value to an offset on disk.
michael@0 219 // Returns true on success.
michael@0 220 bool ImageRVAToOnDiskOffset(DWORD rva, DWORD *on_disk_offset) const;
michael@0 221
michael@0 222 // Converts an address to an offset on disk.
michael@0 223 // Returns true on success.
michael@0 224 bool ImageAddrToOnDiskOffset(LPVOID address, DWORD *on_disk_offset) const;
michael@0 225
michael@0 226 private:
michael@0 227 HMODULE module_;
michael@0 228 };
michael@0 229
michael@0 230 // This class is an extension to the PEImage class that allows working with PE
michael@0 231 // files mapped as data instead of as image file.
michael@0 232 class PEImageAsData : public PEImage {
michael@0 233 public:
michael@0 234 explicit PEImageAsData(HMODULE hModule) : PEImage(hModule) {}
michael@0 235
michael@0 236 virtual PVOID RVAToAddr(DWORD rva) const;
michael@0 237 };
michael@0 238
michael@0 239 inline bool PEImage::IsOrdinal(LPCSTR name) {
michael@0 240 #pragma warning(push)
michael@0 241 #pragma warning(disable: 4311)
michael@0 242 // This cast generates a warning because it is 32 bit specific.
michael@0 243 return reinterpret_cast<DWORD>(name) <= 0xFFFF;
michael@0 244 #pragma warning(pop)
michael@0 245 }
michael@0 246
michael@0 247 inline WORD PEImage::ToOrdinal(LPCSTR name) {
michael@0 248 return reinterpret_cast<WORD>(name);
michael@0 249 }
michael@0 250
michael@0 251 inline HMODULE PEImage::module() const {
michael@0 252 return module_;
michael@0 253 }
michael@0 254
michael@0 255 inline PIMAGE_IMPORT_DESCRIPTOR PEImage::GetFirstImportChunk() const {
michael@0 256 return reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
michael@0 257 GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_IMPORT));
michael@0 258 }
michael@0 259
michael@0 260 inline PIMAGE_EXPORT_DIRECTORY PEImage::GetExportDirectory() const {
michael@0 261 return reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(
michael@0 262 GetImageDirectoryEntryAddr(IMAGE_DIRECTORY_ENTRY_EXPORT));
michael@0 263 }
michael@0 264
michael@0 265 } // namespace win
michael@0 266 } // namespace base
michael@0 267
michael@0 268 #endif // BASE_WIN_PE_IMAGE_H_

mercurial