ROSE  0.11.31.0
BinaryCodeInserter.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 <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:
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:
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; }
266  size_t startIdx, size_t nInsns, std::vector<uint8_t> replacement,
267  const std::vector<Relocation> &relocations = std::vector<Relocation>());
268 
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 
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 
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 
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 
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...
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:1606
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.
Main namespace for the ROSE library.
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 instruction relative index for some instruction of the original basi...
Interprets the reloc_value as an index of some byte in the input, and computes that byte'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.
Interprets the reloc_value as a virtual address and computes the offset from the output virtual addre...
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'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_t v1, rose_addr_t v2)
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.
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.
Interprets the reloc_value as a virtual address and computes the offset from the output virtual addre...
T greatest() const
Returns upper limit.
Definition: Interval.h:191
MemoryMap::Ptr memoryMap() const
Returns the memory map.
Definition: Partitioner.h:540
NopPadding
How to pad with no-ops.
Partitions instructions into basic blocks and functions.
Definition: Partitioner.h:323
Container associating values with keys.
Definition: Sawyer/Map.h:66
const AddressInterval & chunkAllocationRegion() const
Property: Where chunks are allocated.