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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%28280.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    :  // Declaration of the entry thunk instrumentation transform. This instruments
  16    :  // module entry points (DLL and EXE) and individual functions with different
  17    :  // hook functions (provided to the transform). The details as to which
  18    :  // entry points and functions are hooked (and how) can be individually
  19    :  // controlled.
  20    :  //
  21    :  // A generic hook (without a parameter) redirects a call to a thunk of the
  22    :  // form:
  23    :  //
  24    :  //   0x68 0x44 0x33 0x22 0x11       push 0x11223344
  25    :  //   0xff 0x25 0x88 0x77 0x66 0x55  jmp [0x55667788]
  26    :  //
  27    :  // Where 0x11223344 is the address of the original function to be invoked,
  28    :  // and 0x55667788 is the address of the import pointing at the hook to be
  29    :  // invoked. The hook is responsible for cleaning up the stack with a 'ret' so
  30    :  // that 0x11223344 is popped, and control is transferred to the original
  31    :  // function.
  32    :  //
  33    :  // A parameterized hook redirects a call to a thunk of the form:
  34    :  //
  35    :  //   0x68 0xdd 0xcc 0xbb 0xaa       push 0xaabbccdd  ; must be a 32 bit value.
  36    :  //   0x68 0x44 0x33 0x22 0x11       push 0x11223344
  37    :  //   0xff 0x25 0x88 0x77 0x66 0x55  jmp [0x55667788]
  38    :  //
  39    :  // Where 0xaabbccdd is an additional immediate value, the semantics of which
  40    :  // are known to the hook function. The hook is responsible for cleaning up
  41    :  // the stack with a 'ret 4' so that both 0xaabbccdd and 0x11223344 are popped
  42    :  // and control is returned to the original function.
  43    :  //
  44    :  // Prior to executing the thunk the stack is set up as if the call was going to
  45    :  // be directly to the original function.
  46    :  
  47    :  #ifndef SYZYGY_INSTRUMENT_TRANSFORMS_ENTRY_THUNK_TRANSFORM_H_
  48    :  #define SYZYGY_INSTRUMENT_TRANSFORMS_ENTRY_THUNK_TRANSFORM_H_
  49    :  
  50    :  #include <set>
  51    :  #include <string>
  52    :  
  53    :  #include "base/string_piece.h"
  54    :  #include "syzygy/block_graph/basic_block_assembler.h"
  55    :  #include "syzygy/block_graph/iterate.h"
  56    :  #include "syzygy/block_graph/transforms/iterative_transform.h"
  57    :  #include "syzygy/pe/pe_utils.h"
  58    :  
  59    :  namespace instrument {
  60    :  namespace transforms {
  61    :  
  62    :  class EntryThunkTransform
  63    :      : public block_graph::transforms::IterativeTransformImpl<
  64    :          EntryThunkTransform> {
  65    :   public:
  66    :    typedef block_graph::Immediate Immediate;
  67    :    typedef block_graph::BlockGraph BlockGraph;
  68    :  
  69    :    EntryThunkTransform();
  70    :  
  71    :    // @name Accessors.
  72    :    // @{
  73  E :    void set_instrument_unsafe_references(bool instrument) {
  74  E :      instrument_unsafe_references_ = instrument;
  75  E :    }
  76  E :    bool instrument_unsafe_references() const {
  77  E :      return instrument_unsafe_references_;
  78  E :    }
  79    :  
  80  E :    void set_src_ranges_for_thunks(bool src_ranges_for_thunks) {
  81  E :      src_ranges_for_thunks_ = src_ranges_for_thunks;
  82  E :    }
  83  E :    bool src_ranges_for_thunks() const {
  84  E :      return src_ranges_for_thunks_;
  85  E :    }
  86    :  
  87  E :    void set_only_instrument_module_entry(bool only_instrument_module_entry) {
  88  E :      only_instrument_module_entry_ = only_instrument_module_entry;
  89  E :    }
  90    :  
  91  E :    bool only_instrument_module_entry() const {
  92  E :      return only_instrument_module_entry_;
  93  E :    }
  94    :  
  95  E :    void set_instrument_dll_name(const base::StringPiece& instrument_dll_name) {
  96  E :      instrument_dll_name.CopyToString(&instrument_dll_name_);
  97  E :    }
  98    :    const char* instrument_dll_name() const {
  99    :      return instrument_dll_name_.c_str();
 100    :    }
 101    :  
 102  E :    const Immediate& entry_thunk_parameter() const {
 103  E :      return entry_thunk_parameter_;
 104  E :    }
 105  E :    const Immediate& function_thunk_parameter() const {
 106  E :      return function_thunk_parameter_;
 107  E :    }
 108    :  
 109  E :    BlockGraph::Section* thunk_section() const { return thunk_section_; }
 110    :    // @}
 111    :  
 112    :    // @{
 113    :    // Sets the parameter to be used by entry/function thunks. Only 32-bit
 114    :    // parameters may be used. Set to an invalid parameter (default constructed)
 115    :    // with a size of core::kSizeNone in order to disable parameterized thunks.
 116    :    // @param immediate the parameter to be used.
 117    :    // @returns true if the parameter was accepted, false otherwise.
 118    :    bool SetEntryThunkParameter(const Immediate& immediate);
 119    :    bool SetFunctionThunkParameter(const Immediate& immediate);
 120    :    // @}
 121    :  
 122    :    // @{
 123    :    // @returns true if the thunk type will be parameterized.
 124    :    bool EntryThunkIsParameterized() const;
 125    :    bool FunctionThunkIsParameterized() const;
 126    :    // @}
 127    :  
 128    :    // The name of the import for general entry hooks.
 129    :    static const char kEntryHookName[];
 130    :    // The name of the import for DllMain-like function entry hooks.
 131    :    static const char kDllMainEntryHookName[];
 132    :    // The name of the import for EXE entry point hook.
 133    :    static const char kExeMainEntryHookName[];
 134    :  
 135    :    // The name of the DLL imported default.
 136    :    static const char kDefaultInstrumentDll[];
 137    :  
 138    :   protected:
 139    :    typedef std::map<BlockGraph::Offset, BlockGraph::Block*> ThunkBlockMap;
 140    :  
 141    :    // @name IterativeTransformImpl implementation.
 142    :    // @{
 143    :    bool PreBlockGraphIteration(
 144    :        BlockGraph* block_graph, BlockGraph::Block* header_block);
 145    :    bool OnBlock(BlockGraph* block_graph, BlockGraph::Block* block);
 146    :    // @}
 147    :  
 148    :    // Instrument a single block.
 149    :    bool InstrumentCodeBlock(BlockGraph* block_graph, BlockGraph::Block* block);
 150    :  
 151    :    // Instruments a single referrer to a code block.
 152    :    bool InstrumentCodeBlockReferrer(const BlockGraph::Block::Referrer& referrer,
 153    :                                     BlockGraph* block_graph,
 154    :                                     BlockGraph::Block* block,
 155    :                                     ThunkBlockMap* thunk_block_map);
 156    :  
 157    :    // Create a single thunk to destination.
 158    :    // @param block_graph the block-graph being instrumented.
 159    :    // @param destination the destination reference.
 160    :    // @param hook a reference to the hook to use.
 161    :    // @param parameter the parameter to be passed to the thunk. If this is NULL
 162    :    //     then an unparameterized thunk will be created.
 163    :    BlockGraph::Block* CreateOneThunk(BlockGraph* block_graph,
 164    :                                      const BlockGraph::Reference& destination,
 165    :                                      const BlockGraph::Reference& hook,
 166    :                                      const Immediate* parameter);
 167    :  
 168    :   private:
 169    :    friend IterativeTransformImpl<EntryThunkTransform>;
 170    :    friend NamedBlockGraphTransformImpl<EntryThunkTransform>;
 171    :  
 172    :    bool GetEntryPoints(BlockGraph::Block* header_block);
 173    :  
 174    :    // For NamedBlockGraphTransformImpl.
 175    :    static const char kTransformName[];
 176    :  
 177    :    // The section we put our thunks in. Valid after successful
 178    :    // PreBlockGraphIteration.
 179    :    BlockGraph::Section* thunk_section_;
 180    :  
 181    :    // References to _indirect_penter and _indirect_penter_dllmain import
 182    :    // entries. Valid after successful PreBlockGraphIteration.
 183    :    BlockGraph::Reference hook_ref_;
 184    :    BlockGraph::Reference hook_dllmain_ref_;
 185    :    BlockGraph::Reference hook_exe_entry_ref_;
 186    :  
 187    :    // Iff true, instrument references with a non-zero offset into the
 188    :    // destination block.
 189    :    bool instrument_unsafe_references_;
 190    :  
 191    :    // Iff true, thunks will be adorned with a source range identifying them
 192    :    // with the function they address. This makes the output more debugging
 193    :    // friendly, at the cost of the uniqueness of address->name resolution.
 194    :    bool src_ranges_for_thunks_;
 195    :  
 196    :    // If true, only instrument DLL entry points.
 197    :    bool only_instrument_module_entry_;
 198    :  
 199    :    // If has a size of 32 bits, then entry thunks will be set up with an extra
 200    :    // parameter on the stack prior to the address of the original function.
 201    :    Immediate entry_thunk_parameter_;
 202    :  
 203    :    // If has a size of 32 bits, then function hook thunks will be set up with an
 204    :    // extra parameter on the stack prior to the address of the original function.
 205    :    Immediate function_thunk_parameter_;
 206    :  
 207    :    // Name of the instrumentation DLL we import.
 208    :    // Defaults to "call_trace_client.dll".
 209    :    std::string instrument_dll_name_;
 210    :  
 211    :    // This contains the set of entrypoints that have DllMain calling conventions.
 212    :    // These are thunked to the dllmain hook import, instead of the generic
 213    :    // hook import. Valid after successful call to GetEntryPoints.
 214    :    pe::EntryPointSet dllmain_entrypoints_;
 215    :    // If the module being instrumented is an executable, this will hold the
 216    :    // EXE main entry point. Valid after successful call to GetEntryPoints.
 217    :    pe::EntryPoint exe_entry_point_;
 218    :  
 219    :    DISALLOW_COPY_AND_ASSIGN(EntryThunkTransform);
 220    :  };
 221    :  
 222    :  }  // namespace transforms
 223    :  }  // namespace instrument
 224    :  
 225    :  #endif  // SYZYGY_INSTRUMENT_TRANSFORMS_ENTRY_THUNK_TRANSFORM_H_

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