Coverage for /Syzygy/pe/pe_file.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%38380.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. 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 SYZYGY_PE_PE_FILE_H_
  16    :  #define SYZYGY_PE_PE_FILE_H_
  17    :  
  18    :  #include <windows.h>
  19    :  #include <winnt.h>
  20    :  #include <map>
  21    :  #include <set>
  22    :  #include <string>
  23    :  #include <vector>
  24    :  
  25    :  #include "base/files/file_path.h"
  26    :  #include "sawbuck/sym_util/types.h"
  27    :  #include "syzygy/core/address.h"
  28    :  #include "syzygy/core/address_space.h"
  29    :  #include "syzygy/core/serialization.h"
  30    :  
  31    :  namespace pe {
  32    :  
  33    :  // This duplicates a similar constant in the core namespace, declared by
  34    :  // block_graph.h. We duplicate it here so as not to add an uneccessary
  35    :  // dependency.
  36    :  // Header data and other data not from a regular section is considered as
  37    :  // being from an invalid section.
  38    :  extern const size_t kInvalidSection;
  39    :  
  40    :  class PEFile {
  41    :   public:
  42    :    // Used for storing the signature of a PE file.
  43    :    struct Signature;
  44    :  
  45    :    typedef core::AbsoluteAddress AbsoluteAddress;
  46    :    typedef core::FileOffsetAddress FileOffsetAddress;
  47    :    typedef core::RelativeAddress RelativeAddress;
  48    :  
  49    :    // Contains relocation addresses.
  50    :    typedef std::set<RelativeAddress> RelocSet;
  51    :  
  52    :    // Contains the decoded relocation information, where each item
  53    :    // in the map is the address and value of a relocatable entry.
  54    :    typedef std::map<RelativeAddress, AbsoluteAddress> RelocMap;
  55    :  
  56    :    // Information about a single export.
  57    :    struct ExportInfo;
  58    :    typedef std::vector<ExportInfo> ExportInfoVector;
  59    :  
  60    :    // Information about a single import.
  61    :    struct ImportInfo;
  62    :    typedef std::vector<ImportInfo> ImportInfoVector;
  63    :  
  64    :    // Information about all imports for a given DLL.
  65    :    struct ImportDll;
  66    :    typedef std::vector<ImportDll> ImportDllVector;
  67    :  
  68    :    PEFile();
  69    :    ~PEFile();
  70    :  
  71  E :    const base::FilePath& path() const { return path_; }
  72    :  
  73    :    // Read in the image file at path.
  74    :    bool Init(const base::FilePath& path);
  75    :  
  76    :    // Populates a signature object with the signature of this PE file. This
  77    :    // is only valid if called after Init.
  78    :    void GetSignature(Signature* signature) const;
  79    :  
  80    :    // Decodes the relocation information from the image to relocs.
  81    :    // TODO(siggi): Consider folding this member into ReadRelocs.
  82    :    bool DecodeRelocs(RelocSet* relocs) const;
  83    :    // Reads all reloc values from the image.
  84    :    bool ReadRelocs(const RelocSet& relocs, RelocMap* reloc_values) const;
  85    :  
  86    :    // Decodes the import information in the image.
  87    :    bool DecodeImports(ImportDllVector* imports) const;
  88    :  
  89    :    // Decodes the export information in the image.
  90    :    bool DecodeExports(ExportInfoVector* exports) const;
  91    :  
  92    :    // @{
  93    :    // Translate between relative and absolute addresses.
  94    :    bool Translate(RelativeAddress rel, AbsoluteAddress* abs) const;
  95    :    bool Translate(AbsoluteAddress abs, RelativeAddress* rel) const;
  96    :    bool Translate(FileOffsetAddress offs, RelativeAddress* rel) const;
  97    :    bool Translate(RelativeAddress rel, FileOffsetAddress* offs) const;
  98    :    // @}
  99    :  
 100    :    // Read len bytes from image at offset offs to data.
 101    :    bool ReadImage(RelativeAddress rel, void* data, size_t len) const;
 102    :    bool ReadImage(AbsoluteAddress abs, void* data, size_t len) const;
 103    :  
 104    :    // Read a zero-terminated string from offs into str.
 105    :    bool ReadImageString(RelativeAddress rel, std::string* str) const;
 106    :    bool ReadImageString(AbsoluteAddress abs, std::string* str) const;
 107    :  
 108    :    // Get a pointer to the image at addr, provided the image contains data
 109    :    // for [addr, addr + len)
 110    :    const uint8* GetImageData(RelativeAddress rel, size_t len) const;
 111    :    const uint8* GetImageData(AbsoluteAddress abs, size_t len) const;
 112    :    uint8* GetImageData(RelativeAddress rel, size_t len);
 113    :    uint8* GetImageData(AbsoluteAddress abs, size_t len);
 114    :  
 115    :    // Check whether or not a given address range is inside the
 116    :    // address space of the PE image.
 117    :    bool Contains(RelativeAddress rel, size_t len) const;
 118    :    bool Contains(AbsoluteAddress abs, size_t len) const;
 119    :  
 120    :    // Returns the section index associated with a given address. Returns
 121    :    // kInvalidSection if the address does not lie within a section.
 122    :    size_t GetSectionIndex(RelativeAddress rel, size_t len) const;
 123    :    size_t GetSectionIndex(AbsoluteAddress abs, size_t len) const;
 124    :  
 125    :    // Returns a pointer to the section header associated with a given address.
 126    :    // Returns NULL if the address does not lie within a section.
 127    :    const IMAGE_SECTION_HEADER* GetSectionHeader(RelativeAddress rel,
 128    :                                                 size_t len) const;
 129    :    const IMAGE_SECTION_HEADER* GetSectionHeader(AbsoluteAddress rel,
 130    :                                                 size_t len) const;
 131    :  
 132    :    // Returns the section index associated with the given name. Returns
 133    :    // kInvalidSection if no section with that name is found.
 134    :    size_t GetSectionIndex(const char* name) const;
 135    :  
 136    :    // Returns the section header associated with the given name. Returns
 137    :    // kInvalidSection if no section with the name is found.
 138    :    const IMAGE_SECTION_HEADER* GetSectionHeader(const char* name) const;
 139    :  
 140    :    // Helper to stringify the name of a section.
 141    :    std::string GetSectionName(size_t section_index) const;
 142    :    static std::string GetSectionName(const IMAGE_SECTION_HEADER& section);
 143    :  
 144    :    // Accessors.
 145  E :    const IMAGE_DOS_HEADER* dos_header() const {
 146  E :      return dos_header_;
 147  E :    }
 148    :  
 149  E :    const IMAGE_NT_HEADERS* nt_headers() const {
 150  E :      return nt_headers_;
 151  E :    }
 152    :  
 153  E :    const IMAGE_SECTION_HEADER* section_headers() const {
 154  E :      return section_headers_;
 155  E :    }
 156    :  
 157  E :    const IMAGE_SECTION_HEADER* section_header(size_t num_section) const {
 158    :      if (nt_headers_ != NULL &&
 159  E :          num_section < nt_headers_->FileHeader.NumberOfSections)
 160  E :        return section_headers_ + num_section;
 161    :  
 162  E :      return NULL;
 163  E :    }
 164    :  
 165  E :    uint32 PEFile::AbsToRelDisplacement(uint32 abs_disp) const {
 166  E :      return abs_disp - nt_headers_->OptionalHeader.ImageBase;
 167  E :    }
 168    :  
 169    :   private:
 170    :    bool ReadHeaders(FILE* file);
 171    :    bool ReadSections(FILE* file);
 172    :  
 173    :    base::FilePath path_;
 174    :    const IMAGE_DOS_HEADER* dos_header_;
 175    :    const IMAGE_NT_HEADERS* nt_headers_;
 176    :    const IMAGE_SECTION_HEADER* section_headers_;
 177    :  
 178    :    typedef std::vector<uint8> SectionBuffer;
 179    :    struct SectionInfo {
 180  E :      SectionInfo() : id(kInvalidSection) {
 181  E :      }
 182    :      size_t id;
 183    :      SectionBuffer buffer;
 184    :    };
 185    :    typedef core::AddressSpace<RelativeAddress, size_t, SectionInfo>
 186    :        ImageAddressSpace;
 187    :  
 188    :    // Contains all data in the image. The address space has a range defined
 189    :    // for the header and each section in the image, with its associated
 190    :    // SectionBuffer as the data.
 191    :    ImageAddressSpace image_data_;
 192    :  
 193    :    DISALLOW_COPY_AND_ASSIGN(PEFile);
 194    :  };
 195    :  
 196    :  // This structure holds a PE file signature.
 197    :  struct PEFile::Signature {
 198  E :    Signature() : module_size(0), module_time_date_stamp(0), module_checksum(0) {
 199  E :    }
 200    :  
 201    :    explicit Signature(const sym_util::ModuleInformation& module_info)
 202    :        : path(module_info.image_file_name),
 203    :          base_address(module_info.base_address),
 204    :          module_size(module_info.module_size),
 205    :          module_time_date_stamp(module_info.time_date_stamp),
 206  E :          module_checksum(module_info.image_checksum) {
 207  E :    }
 208    :  
 209    :    // The original path is kept for convenience. This should always be an
 210    :    // absolute path.
 211    :    // TODO(chrisha): Check that the path is absolute at all sites where this
 212    :    //     path is used.
 213    :    std::wstring path;
 214    :  
 215    :    // The signature consists of the following 4 fields.
 216    :    AbsoluteAddress base_address;
 217    :    size_t module_size;
 218    :    uint32 module_time_date_stamp;
 219    :    uint32 module_checksum;
 220    :  
 221    :    // Compares this signature to another one. The paths do not have to match.
 222    :    bool IsConsistent(const Signature& signature) const;
 223    :  
 224    :    // Compares this signature to another one.
 225    :    // The paths and the checksum do not have to match.
 226    :    bool IsConsistentExceptForChecksum(const Signature& signature) const;
 227    :  
 228    :    // We need an equality operator for serialization unittests.
 229  E :    bool operator==(const Signature& signature) const {
 230  E :      return path == signature.path && IsConsistent(signature);
 231  E :    }
 232    :  
 233    :    // For serialization.
 234    :    bool Save(core::OutArchive* out_archive) const;
 235    :    bool Load(core::InArchive* in_archive);
 236    :  };
 237    :  
 238    :  // Information about a single export.
 239    :  struct PEFile::ExportInfo {
 240    :    // Address of the exported function.
 241    :    RelativeAddress function;
 242    :  
 243    :    // Name of the export, if any.
 244    :    std::string name;
 245    :  
 246    :    // Export forward string, if any.
 247    :    std::string forward;
 248    :  
 249    :    // Export ordinal.
 250    :    uint16 ordinal;
 251    :  };
 252    :  
 253    :  // Information about a single import.
 254    :  struct PEFile::ImportInfo {
 255    :    ImportInfo(uint16 h, uint16 o, const char* n)
 256    :        : hint(h),
 257    :          ordinal(o),
 258  E :          function(n) {
 259  E :    }
 260    :  
 261    :    explicit ImportInfo(const char* function_name)
 262    :        : hint(0),
 263    :          ordinal(0),
 264    :          function(function_name) {
 265    :    }
 266    :    explicit ImportInfo(uint16 function_ordinal)
 267    :        : hint(0),
 268    :          ordinal(function_ordinal) {
 269    :    }
 270  E :    ImportInfo() : hint(0), ordinal(0) {
 271  E :    }
 272    :  
 273  E :    bool operator==(const ImportInfo& o) const {
 274  E :      return hint == o.hint && ordinal == o.ordinal && function == o.function;
 275  E :    }
 276    :  
 277    :    // The loader ordinal hint for this import.
 278    :    uint16 hint;
 279    :  
 280    :    // The ordinal of the function if function.empty().
 281    :    uint16 ordinal;
 282    :  
 283    :    // If non-empty, the name of the function.
 284    :    std::string function;
 285    :  };
 286    :  
 287    :  // Information about all imports for a given DLL.
 288    :  struct PEFile::ImportDll {
 289  E :    ImportDll() {
 290  E :      memset(&desc, 0, sizeof(desc));
 291  E :      desc.ForwarderChain = -1;
 292  E :    }
 293    :  
 294    :    // The import descriptor.
 295    :    IMAGE_IMPORT_DESCRIPTOR desc;
 296    :  
 297    :    // Name of the DLL imported.
 298    :    std::string name;
 299    :  
 300    :    // One entry for each imported function.
 301    :    ImportInfoVector functions;
 302    :  };
 303    :  
 304    :  }  // namespace pe
 305    :  
 306    :  #endif  // SYZYGY_PE_PE_FILE_H_

Coverage information generated Thu Jul 04 09:34:53 2013.