Coverage for /Syzygy/pe/pe_file.h

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

Line-by-line coverage:

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

Coverage information generated Thu Sep 06 11:30:46 2012.