Coverage for /Syzygy/instrument/transforms/entry_thunk_transform.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%12120.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    :  // Implementation of the entry thunk instrumentation transform.
  16    :  
  17    :  #ifndef SYZYGY_INSTRUMENT_TRANSFORMS_ENTRY_THUNK_TRANSFORM_H_
  18    :  #define SYZYGY_INSTRUMENT_TRANSFORMS_ENTRY_THUNK_TRANSFORM_H_
  19    :  
  20    :  #include <set>
  21    :  #include <string>
  22    :  
  23    :  #include "base/string_piece.h"
  24    :  #include "syzygy/block_graph/iterate.h"
  25    :  #include "syzygy/block_graph/transforms/iterative_transform.h"
  26    :  #include "syzygy/pe/pe_utils.h"
  27    :  
  28    :  namespace instrument {
  29    :  namespace transforms {
  30    :  
  31    :  class EntryThunkTransform
  32    :      : public block_graph::transforms::IterativeTransformImpl<
  33    :          EntryThunkTransform> {
  34    :   public:
  35    :    EntryThunkTransform();
  36    :  
  37    :    // @name Accessors.
  38    :    // @{
  39  E :    void set_instrument_unsafe_references(bool instrument) {
  40  E :      instrument_unsafe_references_ = instrument;
  41  E :    }
  42    :    bool instrument_unsafe_references() const {
  43    :      return instrument_unsafe_references_;
  44    :    }
  45    :  
  46  E :    void set_src_ranges_for_thunks(bool src_ranges_for_thunks) {
  47  E :      src_ranges_for_thunks_ = src_ranges_for_thunks;
  48  E :    }
  49    :    bool src_ranges_for_thunks() const {
  50    :      return src_ranges_for_thunks_;
  51    :    }
  52    :  
  53  E :    void set_only_instrument_module_entry(bool only_instrument_module_entry) {
  54  E :      only_instrument_module_entry_ = only_instrument_module_entry;
  55  E :    }
  56    :  
  57    :    bool only_instrument_module_entry() const {
  58    :      return only_instrument_module_entry_;
  59    :    }
  60    :  
  61  E :    void set_instrument_dll_name(const base::StringPiece& instrument_dll_name) {
  62  E :      instrument_dll_name.CopyToString(&instrument_dll_name_);
  63  E :    }
  64    :    const char* instrument_dll_name() const {
  65    :      return instrument_dll_name_.c_str();
  66    :    }
  67    :    // @}
  68    :  
  69    :    // The name of the import for general entry hooks.
  70    :    static const char kEntryHookName[];
  71    :    // The name of the import for DllMain-like function entry hooks.
  72    :    static const char kDllMainEntryHookName[];
  73    :    // The name of the import for EXE entry point hook.
  74    :    static const char kExeEntryHookName[];
  75    :  
  76    :    // The name of the DLL imported default.
  77    :    static const char kDefaultInstrumentDll[];
  78    :  
  79    :   protected:
  80    :    typedef block_graph::BlockGraph BlockGraph;
  81    :    typedef std::map<BlockGraph::Offset, BlockGraph::Block*> ThunkBlockMap;
  82    :    struct Thunk;
  83    :  
  84    :    // @name IterativeTransformImpl implementation.
  85    :    // @{
  86    :    bool PreBlockGraphIteration(
  87    :        BlockGraph* block_graph, BlockGraph::Block* header_block);
  88    :    bool OnBlock(BlockGraph* block_graph, BlockGraph::Block* block);
  89    :    // @}
  90    :  
  91    :    // Accessor.
  92    :    BlockGraph::Section* thunk_section() const { return thunk_section_; }
  93    :  
  94    :    // Instrument a single block.
  95    :    bool InstrumentCodeBlock(BlockGraph* block_graph, BlockGraph::Block* block);
  96    :  
  97    :    // Instruments a single referrer to a code block.
  98    :    bool InstrumentCodeBlockReferrer(const BlockGraph::Block::Referrer& referrer,
  99    :                                     BlockGraph* block_graph,
 100    :                                     BlockGraph::Block* block,
 101    :                                     ThunkBlockMap* thunk_block_map);
 102    :  
 103    :    // Create a single thunk to destination.
 104    :    // @param block_graph the block-graph being instrumented.
 105    :    // @param destination the destination reference.
 106    :    // @param hook a reference to the hook to use.
 107    :    BlockGraph::Block* CreateOneThunk(BlockGraph* block_graph,
 108    :                                      const BlockGraph::Reference& destination,
 109    :                                      const BlockGraph::Reference& hook);
 110    :  
 111    :    // Initializes the references in thunk_block, which must be an allocated
 112    :    // thunk of size sizeof(Thunk), containing data of the same size.
 113    :    static bool InitializeThunk(BlockGraph::Block* thunk_block,
 114    :                               const BlockGraph::Reference& destination,
 115    :                               const BlockGraph::Reference& import_entry);
 116    :  
 117    :   private:
 118    :    friend IterativeTransformImpl<EntryThunkTransform>;
 119    :    friend NamedBlockGraphTransformImpl<EntryThunkTransform>;
 120    :  
 121    :    bool GetEntryPoints(BlockGraph::Block* header_block);
 122    :  
 123    :    // For NamedBlockGraphTransformImpl.
 124    :    static const char kTransformName[];
 125    :  
 126    :    // The section we put our thunks in. Valid after successful
 127    :    // PreBlockGraphIteration.
 128    :    BlockGraph::Section* thunk_section_;
 129    :  
 130    :    // References to _indirect_penter and _indirect_penter_dllmain import
 131    :    // entries. Valid after successful PreBlockGraphIteration.
 132    :    BlockGraph::Reference hook_ref_;
 133    :    BlockGraph::Reference hook_dllmain_ref_;
 134    :    BlockGraph::Reference hook_exe_entry_ref_;
 135    :  
 136    :    // Iff true, instrument references with a non-zero offset into the
 137    :    // destination block.
 138    :    bool instrument_unsafe_references_;
 139    :  
 140    :    // Iff true, thunks will be adorned with a source range identifying them
 141    :    // with the function they address. This makes the output more debugging
 142    :    // friendly, at the cost of the uniqueness of address->name resolution.
 143    :    bool src_ranges_for_thunks_;
 144    :  
 145    :    // If true, only instrument DLL entry points.
 146    :    bool only_instrument_module_entry_;
 147    :  
 148    :    // Name of the instrumentation DLL we import.
 149    :    // Defaults to "call_trace_client.dll".
 150    :    std::string instrument_dll_name_;
 151    :  
 152    :    // This contains the set of entrypoints that have DllMain calling conventions.
 153    :    // These are thunked to the dllmain hook import, instead of the generic
 154    :    // hook import. Valid after successful call to GetEntryPoints.
 155    :    pe::EntryPointSet dllmain_entrypoints_;
 156    :    // If the module being instrumented is an executable, this will hold the
 157    :    // EXE main entry point. Valid after successful call to GetEntryPoints.
 158    :    pe::EntryPoint exe_entry_point_;
 159    :  
 160    :    static const Thunk kThunkTemplate;
 161    :  
 162    :    DISALLOW_COPY_AND_ASSIGN(EntryThunkTransform);
 163    :  };
 164    :  
 165    :  // This defines the memory layout for the thunks we create.
 166    :  #pragma pack(push)
 167    :  #pragma pack(1)
 168    :  struct EntryThunkTransform::Thunk {
 169    :    BYTE push;
 170    :    DWORD func_addr;  // The real function to invoke.
 171    :    WORD jmp;
 172    :    DWORD hook_addr;  // The instrumentation hook that gets called beforehand.
 173    :  };
 174    :  #pragma pack(pop)
 175    :  
 176    :  }  // namespace transforms
 177    :  }  // namespace instrument
 178    :  
 179    :  #endif  // SYZYGY_INSTRUMENT_TRANSFORMS_ENTRY_THUNK_TRANSFORM_H_

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