OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
| 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at |
| 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. |
| 14 |
| 15 #ifndef CRASHPAD_SNAPSHOT_WIN_PE_IMAGE_RESOURCE_READER_H_ |
| 16 #define CRASHPAD_SNAPSHOT_WIN_PE_IMAGE_RESOURCE_READER_H_ |
| 17 |
| 18 #include <stdint.h> |
| 19 #include <windows.h> |
| 20 |
| 21 #include <string> |
| 22 #include <vector> |
| 23 |
| 24 #include "base/basictypes.h" |
| 25 #include "snapshot/win/process_reader_win.h" |
| 26 #include "util/misc/initialization_state_dcheck.h" |
| 27 #include "util/win/address_types.h" |
| 28 #include "util/win/checked_win_address_range.h" |
| 29 |
| 30 namespace crashpad { |
| 31 |
| 32 //! \brief A reader for resources stored in PE images mapped into another |
| 33 //! process. |
| 34 //! |
| 35 //! \sa PEImageReader |
| 36 class PEImageResourceReader { |
| 37 public: |
| 38 PEImageResourceReader(); |
| 39 ~PEImageResourceReader(); |
| 40 |
| 41 //! \brief Initializes the resource reader. |
| 42 //! |
| 43 //! \param[in] process_reader The reader for the remote process. |
| 44 //! \param[in] resources_directory_entry The module’s `IMAGE_DATA_DIRECTORY` |
| 45 //! for its resources area. This is taken from the module’s |
| 46 //! `IMAGE_OPTIONAL_HEADER::DataDirectory` at index |
| 47 //! `IMAGE_DIRECTORY_ENTRY_RESOURCE`. |
| 48 //! \param[in] module_range The location (base address and size) of the module |
| 49 //! in the remote process. |
| 50 //! \param[in] module_name The module’s name, a string to be used in logged |
| 51 //! messages. This string is for diagnostic purposes. |
| 52 //! |
| 53 //! \return `true` on success, `false` on failure with a message logged. |
| 54 bool Initialize(ProcessReaderWin* process_reader, |
| 55 const IMAGE_DATA_DIRECTORY& resources_directory_entry, |
| 56 const CheckedWinAddressRange& module_range, |
| 57 std::string module_name); |
| 58 |
| 59 //! \brief Locates a resource in a module by its ID. |
| 60 //! |
| 61 //! This method is similar to `FindResourceEx()`, but it operates on modules |
| 62 //! loaded in a remote process’ address space. It is not necessary to |
| 63 //! `LoadLibrary()` a module into a process in order to use this method. |
| 64 //! |
| 65 //! No support is provided at present for locating resources by \a type or \a |
| 66 //! name using strings as opposed to integer identifiers. |
| 67 //! |
| 68 //! Languages are scanned in the order determined by |
| 69 //! GetEntryFromResourceDirectoryByLanguage(). |
| 70 //! |
| 71 //! \param[in] type The integer identifier of the resource type, as in the |
| 72 //! `lpType` parameter of `FindResourceEx()`. |
| 73 //! \param[in] name The integer identifier of the resource, as in the `lpName` |
| 74 //! parameter of `FindResourceEx()`. |
| 75 //! \param[in] language The language of the resource, as in the `wLanguage` |
| 76 //! parameter of `FindResourceEx()`. |
| 77 //! \param[out] address The address, in the remote process’ address space, of |
| 78 //! the resource data. |
| 79 //! \param[out] size The size of the resource data. |
| 80 //! \param[out] code_page The code page used to encode textual resource data. |
| 81 //! This parameter is optional. |
| 82 //! |
| 83 //! \return `true` on success, with the out parameters set appropriately. |
| 84 //! `false` if the resource was not found, without logging any messages. |
| 85 //! `false` on failure, with a message logged. |
| 86 bool FindResourceByID(uint16_t type, |
| 87 uint16_t name, |
| 88 uint16_t language, |
| 89 WinVMAddress* address, |
| 90 WinVMSize* size, |
| 91 uint32_t* code_page) const; |
| 92 |
| 93 private: |
| 94 //! \brief Locates a resource directory entry within a resource directory by |
| 95 //! integer ID. |
| 96 //! |
| 97 //! \param[in] resource_directory_offset The offset, in the module’s resources |
| 98 //! area, of the resource directory to search. |
| 99 //! \param[in] id The integer identifier of the resource to search for. |
| 100 //! \param[in] want_subdirectory `true` if the resource directory entry is |
| 101 //! expected to be a resource directory itself, `false` otherwise. |
| 102 //! |
| 103 //! \return The offset, in the module’s resources area, of the entry that was |
| 104 //! found. On failure, `0`. `0` is technically a valid offset, but it |
| 105 //! corresponds to the root resource directory, which should never be the |
| 106 //! offset of another resource directory entry. If \a id was not found, |
| 107 //! `0` will be returned without logging anything. For other failures, a |
| 108 //! message will be logged. |
| 109 uint32_t GetEntryFromResourceDirectoryByID(uint32_t resource_directory_offset, |
| 110 uint16_t id, |
| 111 bool want_subdirectory) const; |
| 112 |
| 113 //! \brief Locates a resource directory entry within a resource directory by |
| 114 //! language. |
| 115 //! |
| 116 //! This method is similar to GetEntryFromResourceDirectoryByID() with \a |
| 117 //! want_subdirectory set to `false`. Attempts are made to locate the resource |
| 118 //! by using these languages: |
| 119 //! <ul> |
| 120 //! <li>\a language</li> |
| 121 //! <li>\a language, with `SUBLANG_NEUTRAL`</li> |
| 122 //! <li>`LANG_NEUTRAL` with `SUBLANG_NEUTRAL`</li> |
| 123 //! <li>`LANG_ENGLISH` with `SUBLANG_DEFAULT`</li> |
| 124 //! <li>If none of the above match, the first language found</li> |
| 125 //! </ul> |
| 126 //! |
| 127 //! If only a specific language is desired without any fallbacks, call |
| 128 //! GetEntryFromResourceDirectoryByID() with the language directory’s offset |
| 129 //! instead, passing the desired language in the \a id parameter, and `false` |
| 130 //! for \a want_subdirectory. |
| 131 //! |
| 132 //! \param[in] language_directory_offset The offset, in the module’s resources |
| 133 //! area, of the resource directory to search. |
| 134 //! \param[in] language The language of the resource to search for. |
| 135 //! |
| 136 //! \return The return value is as in GetEntryFromResourceDirectoryByID(). |
| 137 uint32_t GetEntryFromResourceDirectoryByLanguage( |
| 138 uint32_t language_directory_offset, |
| 139 uint16_t language) const; |
| 140 |
| 141 //! \brief Reads a resource directory. |
| 142 //! |
| 143 //! \param[in] resource_directory_offset The offset, in the module’s resources |
| 144 //! area, of the resource directory to read. |
| 145 //! \param[out] resource_directory The `IMAGE_RESOURCE_DIRECTORY` structure. |
| 146 //! This parameter is optional. |
| 147 //! \param[out] named_entries A vector of \a |
| 148 //! resource_directory->NumberOfNamedEntries |
| 149 //! `IMAGE_RESOURCE_DIRECTORY_ENTRY` items that follow the resource |
| 150 //! directory. This parameter is optional. |
| 151 //! \param[out] id_entries A vector of \a |
| 152 //! resource_directory->NumberOfIdEntries `IMAGE_RESOURCE_DIRECTORY_ENTRY` |
| 153 //! items that follow the named entries. This parameter is optional. |
| 154 //! |
| 155 //! \return `true` on success, with the out parameters set appropriately. |
| 156 //! `false` on failure with a message logged. |
| 157 bool ReadResourceDirectory( |
| 158 uint32_t resource_directory_offset, |
| 159 IMAGE_RESOURCE_DIRECTORY* resource_directory, |
| 160 std::vector<IMAGE_RESOURCE_DIRECTORY_ENTRY>* named_entries, |
| 161 std::vector<IMAGE_RESOURCE_DIRECTORY_ENTRY>* id_entries) const; |
| 162 |
| 163 //! \brief Reads memory from the target process, first checking whether the |
| 164 //! range requested falls inside resources_range_. |
| 165 //! |
| 166 //! \return `true` on success, with \a into filled out, otherwise `false` with |
| 167 //! a message logged. |
| 168 bool CheckedReadMemory(WinVMAddress address, |
| 169 WinVMSize size, |
| 170 void* into) const; |
| 171 |
| 172 ProcessReaderWin* process_reader_; // weak |
| 173 CheckedWinAddressRange resources_range_; |
| 174 WinVMAddress module_base_; |
| 175 std::string module_name_; |
| 176 InitializationStateDcheck initialized_; |
| 177 |
| 178 DISALLOW_COPY_AND_ASSIGN(PEImageResourceReader); |
| 179 }; |
| 180 |
| 181 } // namespace crashpad |
| 182 |
| 183 #endif // CRASHPAD_SNAPSHOT_WIN_PE_IMAGE_RESOURCE_READER_H_ |
OLD | NEW |