ROSE  0.11.50.0
CodeInserter.h
1 #ifndef Rose_BinaryAnalysis_CodeInserter_H
2 #define Rose_BinaryAnalysis_CodeInserter_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include <Rose/BinaryAnalysis/Partitioner2/Partitioner.h>
7 #include <Sawyer/Map.h>
8 
9 namespace Rose {
10 namespace BinaryAnalysis {
11 
13 namespace Commit {
14 enum Boolean {
15  NO,
16  YES
17 };
18 } // namespace
19 
21 class CodeInserter {
22 public:
25  AGGREGATE_PREDECESSORS = 0x00000001,
26  AGGREGATE_SUCCESSORS = 0x00000002
27  };
28 
30  enum NopPadding {
34  };
35 
54  enum RelocType {
100  };
101 
111  struct Relocation {
112  size_t offset;
114  rose_addr_t value;
122  Relocation(size_t offset, RelocType type, rose_addr_t value)
123  : offset(offset), type(type), value(value) {}
124  };
125 
128  rose_addr_t originalVa;
131  explicit InstructionInfo(SgAsmInstruction *insn)
132  : originalVa(insn->get_address()) {}
133  };
134 
142 
143 protected:
144  const Rose::BinaryAnalysis::Partitioner2::Partitioner &partitioner_;
145  AddressInterval chunkAllocationRegion_; // where chunks can be allocated
146  size_t minChunkAllocationSize_; // size of each chunk in bytes (also the alignment)
147  size_t chunkAllocationAlignment_; // alignment for allocating large chunks
148  std::string chunkAllocationName_; // name to give new areas of the memory map
149  AddressIntervalSet allocatedChunks_; // large allocated chunks that populate freeSpace_
150  AddressIntervalSet freeSpace_; // parts of mapped memory serving as free space for allocations
151  unsigned aggregationDirection_; // AggregationDirection bits
152  NopPadding nopPadding_; // where to add no-op padding
153 
154 public:
157 
158 public:
159  explicit CodeInserter(const Rose::BinaryAnalysis::Partitioner2::Partitioner &partitioner)
160  : partitioner_(partitioner), minChunkAllocationSize_(8192), chunkAllocationAlignment_(4096),
161  chunkAllocationName_("new code"), aggregationDirection_(AGGREGATE_PREDECESSORS | AGGREGATE_SUCCESSORS),
162  nopPadding_(PAD_NOP_BACK) {
163  ASSERT_not_null(partitioner.memoryMap());
164  if (!partitioner.memoryMap()->isEmpty() &&
165  partitioner.memoryMap()->hull().greatest() < AddressInterval::whole().greatest()) {
166  chunkAllocationRegion_ = AddressInterval::hull(partitioner.memoryMap()->hull().greatest() + 1,
168  } else {
169  chunkAllocationRegion_ = AddressInterval::whole();
170  }
171  }
172 
176  static void initDiagnostics();
177 
185  const AddressInterval& chunkAllocationRegion() const { return chunkAllocationRegion_; }
186  void chunkAllocationRegion(const AddressInterval& i) { chunkAllocationRegion_ = i; }
192  const AddressIntervalSet& allocatedChunks() const { return allocatedChunks_; }
193 
200  size_t minChunkAllocationSize() const { return minChunkAllocationSize_; }
201  void minChunkAllocationSize(size_t n) { minChunkAllocationSize_ = n; }
207  size_t chunkAllocationAlignment() const { return chunkAllocationAlignment_; }
208  void chunkAllocationAlignment(size_t n);
214  const std::string& chunkAllocationName() const { return chunkAllocationName_; }
215  void chunkAllocationName(const std::string &s) { chunkAllocationName_ = s; }
226  unsigned aggregationDirection() const { return aggregationDirection_; }
227  void aggregationDirection(unsigned d) { aggregationDirection_ = d; }
236  NopPadding nopPadding() const { return nopPadding_; }
237  void nopPadding(NopPadding p) { nopPadding_ = p; }
265  virtual bool replaceBlockInsns(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr&,
266  size_t startIdx, size_t nInsns, std::vector<uint8_t> replacement,
267  const std::vector<Relocation> &relocations = std::vector<Relocation>());
268 
274  bool replaceInsnsAtFront(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr &bb, size_t nInsns,
275  const std::vector<uint8_t> &replacement,
276  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
277  return replaceBlockInsns(bb, 0, nInsns, replacement, relocations);
278  }
279 
285  virtual bool replaceInsnsAtBack(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr &bb, size_t nInsns,
286  const std::vector<uint8_t> &replacement,
287  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
288  ASSERT_require(nInsns <= bb->nInstructions());
289  return replaceBlockInsns(bb, bb->nInstructions()-nInsns, nInsns, replacement, relocations);
290  }
291 
298  virtual bool prependInsns(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr &bb,
299  const std::vector<uint8_t> &replacement,
300  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
301  return replaceInsnsAtFront(bb, 0, replacement, relocations);
302  }
303 
310  virtual bool appendInsns(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr &bb,
311  const std::vector<uint8_t> &replacement,
312  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
313  return replaceInsnsAtBack(bb, 0, replacement, relocations);
314  }
315 
332  virtual bool replaceInsns(const std::vector<SgAsmInstruction*> &toReplace, const std::vector<uint8_t> &replacement,
333  const std::vector<Relocation> &relocations = std::vector<Relocation>());
334 
336  virtual void fillWithNops(const AddressIntervalSet &where);
337 
339  virtual void fillWithRandom(const AddressIntervalSet &where);
340 
346  virtual std::vector<uint8_t> encodeJump(rose_addr_t srcVa, rose_addr_t tgtVa);
347 
353  virtual std::vector<uint8_t> applyRelocations(rose_addr_t startVa, std::vector<uint8_t> replacement,
354  const std::vector<Relocation> &relocations, size_t relocStart,
355  const InstructionInfoMap &insnInfoMap);
356 
366  virtual AddressInterval allocateMemory(size_t nBytes, rose_addr_t jmpTargetVa, Commit::Boolean commit = Commit::YES);
367 
375  void commitAllocation(const AddressInterval &where, Commit::Boolean commit = Commit::YES);
376 
378  AddressIntervalSet instructionLocations(const std::vector<SgAsmInstruction*>&);
379 
388  virtual bool replaceByOverwrite(const AddressIntervalSet &toReplaceVas, const AddressInterval &entryInterval,
389  const std::vector<uint8_t> &replacement, const std::vector<Relocation> &relocations,
390  size_t relocStart, const InstructionInfoMap &insnInfoMap);
391 
401  virtual bool replaceByTransfer(const AddressIntervalSet &toReplaceVas, const AddressInterval &entryInterval,
402  const std::vector<SgAsmInstruction*> &toReplace, const std::vector<uint8_t> &replacement,
403  const std::vector<Relocation> &relocations, size_t relocStart,
404  const InstructionInfoMap &insnInfoMap);
405 
411  InstructionInfoMap computeInstructionInfoMap(const Rose::BinaryAnalysis::Partitioner2::BasicBlock::Ptr&,
412  size_t startIdx, size_t nDeleted);
413 };
414 
415 } // namespace
416 } // namespace
417 
418 #endif
419 #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.
Interprets the reloc_value as an index of some byte in the input, and computes that byte's virtual ad...
Definition: CodeInserter.h:61
RelocType type
Relocation algorithm.
Definition: CodeInserter.h:113
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.
Definition: CodeInserter.h:114
void minChunkAllocationSize(size_t n)
Property: Minimum size of allocated chunks.
Definition: CodeInserter.h:201
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:1606
virtual void fillWithRandom(const AddressIntervalSet &where)
Fill the specified memory with random data.
Only query an allocation.
Definition: CodeInserter.h:15
Interprets the reloc_value as an instruction relative index for some instruction of the original basi...
Definition: CodeInserter.h:81
virtual void fillWithNops(const AddressIntervalSet &where)
Fill the specified memory with no-op instructions.
size_t offset
Location of relocation in replacement code.
Definition: CodeInserter.h:112
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.
Definition: CodeInserter.h:128
unsigned aggregationDirection() const
Property: Whether additional instructions can be moved.
Definition: CodeInserter.h:226
AggregationDirection
What other instructions can be moved to make room.
Definition: CodeInserter.h:24
void chunkAllocationRegion(const AddressInterval &i)
Property: Where chunks are allocated.
Definition: CodeInserter.h:186
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.
Definition: CodeInserter.h:33
const std::string & chunkAllocationName() const
Property: Name for newly allocated regions of memory.
Definition: CodeInserter.h:214
Main namespace for the ROSE library.
Sawyer::Container::Map< int, InstructionInfo > InstructionInfoMap
Information about instructions within the basic block being modified.
Definition: CodeInserter.h:141
Relocation(size_t offset, RelocType type, rose_addr_t value)
Constructor.
Definition: CodeInserter.h:122
Add no-ops to the end of replacements.
Definition: CodeInserter.h:31
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.
Definition: CodeInserter.h:200
void commitAllocation(const AddressInterval &where, Commit::Boolean commit=Commit::YES)
Commit previous allocation.
Interprets the reloc_value as an instruction relative index for some instruction of the original basi...
Definition: CodeInserter.h:91
Interprets the reloc_value as an index of some byte in the input, and computes that byte's virtual ad...
Definition: CodeInserter.h:58
virtual std::vector< uint8_t > encodeJump(rose_addr_t srcVa, rose_addr_t tgtVa)
Encode an unconditional branch.
Move succeeding instructions in CFG.
Definition: CodeInserter.h:26
const AddressIntervalSet & allocatedChunks() const
Returns the parts of the virtual address space that were allocated for new instructions.
Definition: CodeInserter.h:192
Interprets the reloc_value as an instruction relative index for some instruction of the original basi...
Definition: CodeInserter.h:72
size_t chunkAllocationAlignment() const
Property: Alignment for large allocated chunks.
Definition: CodeInserter.h:207
Interprets the reloc_value as a virtual address and computes the offset from the output virtual addre...
Definition: CodeInserter.h:68
void chunkAllocationName(const std::string &s)
Property: Name for newly allocated regions of memory.
Definition: CodeInserter.h:215
Insert new code in place of existing instructions.
Definition: CodeInserter.h:21
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.
Definition: CodeInserter.h:310
Interprets the reloc_value as an index of some byte in the input, and computes that byte's virtual ad...
Definition: CodeInserter.h:55
Allocate memory for real.
Definition: CodeInserter.h:16
static Interval whole()
Construct an interval that covers the entire domain.
Definition: Interval.h:180
static Interval hull(T v1, T v2)
Construct an interval from two endpoints.
Definition: Interval.h:151
void nopPadding(NopPadding p)
Property: Where to add no-ops when padding.
Definition: CodeInserter.h:237
RelocType
Type of relocation to perform.
Definition: CodeInserter.h:54
Information about an instruction within the basic block being modified.
Definition: CodeInserter.h:127
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.
Definition: CodeInserter.h:274
Add no-ops to the front of replacements.
Definition: CodeInserter.h:32
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.
Definition: CodeInserter.h:298
NopPadding nopPadding() const
Property: Where to add no-ops when padding.
Definition: CodeInserter.h:236
static Diagnostics::Facility mlog
Facility for emitting diagnostics.
Definition: CodeInserter.h:156
Sawyer::Optional< rose_addr_t > newVaOffset
Offset of instruction from front of encoded insn vector.
Definition: CodeInserter.h:129
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.
Definition: CodeInserter.h:285
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.
Definition: CodeInserter.h:227
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.
Interprets the reloc_value as a virtual address and computes the offset from the output virtual addre...
Definition: CodeInserter.h:64
T greatest() const
Returns upper limit.
Definition: Interval.h:213
NopPadding
How to pad with no-ops.
Definition: CodeInserter.h:30
Container associating values with keys.
Definition: Sawyer/Map.h:66
const AddressInterval & chunkAllocationRegion() const
Property: Where chunks are allocated.
Definition: CodeInserter.h:185