ROSE  0.9.10.47
BinaryCodeInserter.h
1 #ifndef Rose_BinaryAnalysis_CodeInserter_H
2 #define Rose_BinaryAnalysis__CodeInserter_H
3 
4 #include <Partitioner2/Partitioner.h>
5 #include <Sawyer/Map.h>
6 
7 namespace Rose {
8 namespace BinaryAnalysis {
9 
11 namespace Commit {
12 enum Boolean {
13  NO,
14  YES
15 };
16 } // namespace
17 
19 class CodeInserter {
20 public:
23  AGGREGATE_PREDECESSORS = 0x00000001,
24  AGGREGATE_SUCCESSORS = 0x00000002
25  };
26 
28  enum NopPadding {
32  };
33 
52  enum RelocType {
81  };
82 
92  struct Relocation {
93  size_t offset;
95  rose_addr_t value;
103  Relocation(size_t offset, RelocType type, rose_addr_t value)
104  : offset(offset), type(type), value(value) {}
105  };
106 
109  rose_addr_t originalVa;
112  explicit InstructionInfo(SgAsmInstruction *insn)
113  : originalVa(insn->get_address()) {}
114  };
115 
123 
124 protected:
126  AddressInterval chunkAllocationRegion_; // where chunks can be allocated
127  size_t minChunkAllocationSize_; // size of each chunk in bytes (also the alignment)
128  size_t chunkAllocationAlignment_; // alignment for allocating large chunks
129  std::string chunkAllocationName_; // name to give new areas of the memory map
130  AddressIntervalSet allocatedChunks_; // large allocated chunks that populate freeSpace_
131  AddressIntervalSet freeSpace_; // parts of mapped memory serving as free space for allocations
132  unsigned aggregationDirection_; // AggregationDirection bits
133  NopPadding nopPadding_; // where to add no-op padding
134 
135 
136 public:
139 
140 public:
142  : partitioner_(partitioner), minChunkAllocationSize_(8192), chunkAllocationAlignment_(4096),
143  chunkAllocationName_("new code"), aggregationDirection_(AGGREGATE_PREDECESSORS | AGGREGATE_SUCCESSORS),
144  nopPadding_(PAD_NOP_BACK) {
145  ASSERT_not_null(partitioner.memoryMap());
146  if (!partitioner.memoryMap()->isEmpty() &&
147  partitioner.memoryMap()->hull().greatest() < AddressInterval::whole().greatest()) {
148  chunkAllocationRegion_ = AddressInterval::hull(partitioner.memoryMap()->hull().greatest() + 1,
150  } else {
151  chunkAllocationRegion_ = AddressInterval::whole();
152  }
153  }
154 
158  static void initDiagnostics();
159 
167  const AddressInterval& chunkAllocationRegion() const { return chunkAllocationRegion_; }
168  void chunkAllocationRegion(const AddressInterval& i) { chunkAllocationRegion_ = i; }
174  const AddressIntervalSet& allocatedChunks() const { return allocatedChunks_; }
175 
182  size_t minChunkAllocationSize() const { return minChunkAllocationSize_; }
183  void minChunkAllocationSize(size_t n) { minChunkAllocationSize_ = n; }
189  size_t chunkAllocationAlignment() const { return chunkAllocationAlignment_; }
190  void chunkAllocationAlignment(size_t n);
196  const std::string& chunkAllocationName() const { return chunkAllocationName_; }
197  void chunkAllocationName(const std::string &s) { chunkAllocationName_ = s; }
208  unsigned aggregationDirection() const { return aggregationDirection_; }
209  void aggregationDirection(unsigned d) { aggregationDirection_ = d; }
218  NopPadding nopPadding() const { return nopPadding_; }
219  void nopPadding(NopPadding p) { nopPadding_ = p; }
248  size_t startIdx, size_t nInsns, std::vector<uint8_t> replacement,
249  const std::vector<Relocation> &relocations = std::vector<Relocation>());
250 
257  const std::vector<uint8_t> &replacement,
258  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
259  return replaceBlockInsns(bb, 0, nInsns, replacement, relocations);
260  }
261 
268  const std::vector<uint8_t> &replacement,
269  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
270  return replaceBlockInsns(bb, bb->nInstructions()-nInsns, nInsns, replacement, relocations);
271  }
272 
280  const std::vector<uint8_t> &replacement,
281  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
282  return replaceInsnsAtFront(bb, 0, replacement, relocations);
283  }
284 
292  const std::vector<uint8_t> &replacement,
293  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
294  return replaceInsnsAtBack(bb, 0, replacement, relocations);
295  }
296 
313  virtual bool replaceInsns(const std::vector<SgAsmInstruction*> &toReplace, const std::vector<uint8_t> &replacement,
314  const std::vector<Relocation> &relocations = std::vector<Relocation>());
315 
317  virtual void fillWithNops(const AddressIntervalSet &where);
318 
320  virtual void fillWithRandom(const AddressIntervalSet &where);
321 
327  virtual std::vector<uint8_t> encodeJump(rose_addr_t srcVa, rose_addr_t tgtVa);
328 
334  virtual std::vector<uint8_t> applyRelocations(rose_addr_t startVa, std::vector<uint8_t> replacement,
335  const std::vector<Relocation> &relocations, size_t relocStart,
336  const InstructionInfoMap &insnInfoMap);
337 
347  virtual AddressInterval allocateMemory(size_t nBytes, rose_addr_t jmpTargetVa, Commit::Boolean commit = Commit::YES);
348 
356  void commitAllocation(const AddressInterval &where, Commit::Boolean commit = Commit::YES);
357 
359  AddressIntervalSet instructionLocations(const std::vector<SgAsmInstruction*>&);
360 
369  virtual bool replaceByOverwrite(const AddressIntervalSet &toReplaceVas, const AddressInterval &entryInterval,
370  const std::vector<uint8_t> &replacement, const std::vector<Relocation> &relocations,
371  size_t relocStart, const InstructionInfoMap &insnInfoMap);
372 
382  virtual bool replaceByTransfer(const AddressIntervalSet &toReplaceVas, const AddressInterval &entryInterval,
383  const std::vector<SgAsmInstruction*> &toReplace, const std::vector<uint8_t> &replacement,
384  const std::vector<Relocation> &relocations, size_t relocStart,
385  const InstructionInfoMap &insnInfoMap);
386 
393  size_t startIdx, size_t nDeleted);
394 };
395 
396 } // namespace
397 } // namespace
398 
399 #endif
virtual bool replaceBlockInsns(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr &, size_t startIdx, size_t nInsns, std::vector< uint8_t > replacement, const std::vector< Relocation > &relocations=std::vector< Relocation >())
Replace instructions in basic block.
InstructionInfoMap computeInstructionInfoMap(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr &, size_t startIdx, size_t nDeleted)
Obtain info about instructions for the basic block being modified.
rose_addr_t value
Argument for relocation algorithm.
void minChunkAllocationSize(size_t n)
Property: Minimum size of allocated chunks.
Base class for machine instructions.
AddressIntervalSet instructionLocations(const std::vector< SgAsmInstruction * > &)
Given a list of functions, return all addresses that the instructions occupy.
Collection of streams.
Definition: Message.h:1579
virtual void fillWithRandom(const AddressIntervalSet &where)
Fill the specified memory with random data.
Only query an allocation.
Interprets the reloc_value as an instruction relative index for some instruction of the original basi...
virtual void fillWithNops(const AddressIntervalSet &where)
Fill the specified memory with no-op instructions.
size_t offset
Location of relocation in replacement code.
virtual AddressInterval allocateMemory(size_t nBytes, rose_addr_t jmpTargetVa, Commit::Boolean commit=Commit::YES)
Allocate virtual memory in the partitioner memory map.
rose_addr_t originalVa
Original address of instruction.
unsigned aggregationDirection() const
Property: Whether additional instructions can be moved.
AggregationDirection
What other instructions can be moved to make room.
void chunkAllocationRegion(const AddressInterval &i)
Property: Where chunks are allocated.
virtual bool replaceInsns(const std::vector< SgAsmInstruction * > &toReplace, const std::vector< uint8_t > &replacement, const std::vector< Relocation > &relocations=std::vector< Relocation >())
Replace exactly the specified instructions with some other encoding.
static void initDiagnostics()
Initialize diagnostic streams.
Add random data to the end of replacements.
const std::string & chunkAllocationName() const
Property: Name for newly allocated regions of memory.
Sawyer::Container::Map< int, InstructionInfo > InstructionInfoMap
Information about instructions within the basic block being modified.
Relocation(size_t offset, RelocType type, rose_addr_t value)
Constructor.
Add no-ops to the end of replacements.
virtual bool replaceByTransfer(const AddressIntervalSet &toReplaceVas, const AddressInterval &entryInterval, const std::vector< SgAsmInstruction * > &toReplace, const std::vector< uint8_t > &replacement, const std::vector< Relocation > &relocations, size_t relocStart, const InstructionInfoMap &insnInfoMap)
Insert new code in allocated area.
size_t minChunkAllocationSize() const
Property: Minimum size of allocated chunks.
void commitAllocation(const AddressInterval &where, Commit::Boolean commit=Commit::YES)
Commit previous allocation.
Interprets the reloc_value as an index of some byte in the input, and computes that byte&#39;s virtual ad...
virtual std::vector< uint8_t > encodeJump(rose_addr_t srcVa, rose_addr_t tgtVa)
Encode an unconditional branch.
const AddressIntervalSet & allocatedChunks() const
Returns the parts of the virtual address space that were allocated for new instructions.
Interprets the reloc_value as an instruction relative index for some instruction of the original basi...
size_t chunkAllocationAlignment() const
Property: Alignment for large allocated chunks.
void chunkAllocationName(const std::string &s)
Property: Name for newly allocated regions of memory.
Insert new code in place of existing instructions.
virtual bool appendInsns(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr &bb, const std::vector< uint8_t > &replacement, const std::vector< Relocation > &relocations=std::vector< Relocation >())
Append code to a basic block.
Interprets the reloc_value as an index of some byte in the input, and computes that byte&#39;s virtual ad...
Allocate memory for real.
static Interval whole()
Construct an interval that covers the entire domain.
Definition: Interval.h:167
static Interval hull(rose_addr_tv1, rose_addr_tv2)
Construct an interval from two endpoints.
Definition: Interval.h:150
void nopPadding(NopPadding p)
Property: Where to add no-ops when padding.
RelocType
Type of relocation to perform.
Information about an instruction within the basic block being modified.
bool replaceInsnsAtFront(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr &bb, size_t nInsns, const std::vector< uint8_t > &replacement, const std::vector< Relocation > &relocations=std::vector< Relocation >())
Replace instructions at front of basic block.
Add no-ops to the front of replacements.
virtual bool prependInsns(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr &bb, const std::vector< uint8_t > &replacement, const std::vector< Relocation > &relocations=std::vector< Relocation >())
Prepend code to a basic block.
NopPadding nopPadding() const
Property: Where to add no-ops when padding.
Interprets the reloc_value as an index of some byte in the input and computes the offset from the out...
static Diagnostics::Facility mlog
Facility for emitting diagnostics.
Sawyer::Optional< rose_addr_t > newVaOffset
Offset of instruction from front of encoded insn vector.
virtual bool replaceInsnsAtBack(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr &bb, size_t nInsns, const std::vector< uint8_t > &replacement, const std::vector< Relocation > &relocations=std::vector< Relocation >())
Replace instructions at back of basic block.
virtual std::vector< uint8_t > applyRelocations(rose_addr_t startVa, std::vector< uint8_t > replacement, const std::vector< Relocation > &relocations, size_t relocStart, const InstructionInfoMap &insnInfoMap)
Apply relocations to create a new encoding.
void aggregationDirection(unsigned d)
Property: Whether additional instructions can be moved.
virtual bool replaceByOverwrite(const AddressIntervalSet &toReplaceVas, const AddressInterval &entryInterval, const std::vector< uint8_t > &replacement, const std::vector< Relocation > &relocations, size_t relocStart, const InstructionInfoMap &insnInfoMap)
Insert new code by overwriting existing instructions.
T greatest() const
Returns upper limit.
Definition: Interval.h:191
MemoryMap::Ptr memoryMap() const
Returns the memory map.
Definition: Partitioner.h:484
NopPadding
How to pad with no-ops.
Partitions instructions into basic blocks and functions.
Definition: Partitioner.h:292
Container associating values with keys.
Definition: Sawyer/Map.h:64
const AddressInterval & chunkAllocationRegion() const
Property: Where chunks are allocated.