ROSE  0.9.11.56
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 {
98  };
99 
109  struct Relocation {
110  size_t offset;
112  rose_addr_t value;
120  Relocation(size_t offset, RelocType type, rose_addr_t value)
121  : offset(offset), type(type), value(value) {}
122  };
123 
126  rose_addr_t originalVa;
129  explicit InstructionInfo(SgAsmInstruction *insn)
130  : originalVa(insn->get_address()) {}
131  };
132 
140 
141 protected:
143  AddressInterval chunkAllocationRegion_; // where chunks can be allocated
144  size_t minChunkAllocationSize_; // size of each chunk in bytes (also the alignment)
145  size_t chunkAllocationAlignment_; // alignment for allocating large chunks
146  std::string chunkAllocationName_; // name to give new areas of the memory map
147  AddressIntervalSet allocatedChunks_; // large allocated chunks that populate freeSpace_
148  AddressIntervalSet freeSpace_; // parts of mapped memory serving as free space for allocations
149  unsigned aggregationDirection_; // AggregationDirection bits
150  NopPadding nopPadding_; // where to add no-op padding
151 
152 public:
155 
156 public:
158  : partitioner_(partitioner), minChunkAllocationSize_(8192), chunkAllocationAlignment_(4096),
159  chunkAllocationName_("new code"), aggregationDirection_(AGGREGATE_PREDECESSORS | AGGREGATE_SUCCESSORS),
160  nopPadding_(PAD_NOP_BACK) {
161  ASSERT_not_null(partitioner.memoryMap());
162  if (!partitioner.memoryMap()->isEmpty() &&
163  partitioner.memoryMap()->hull().greatest() < AddressInterval::whole().greatest()) {
164  chunkAllocationRegion_ = AddressInterval::hull(partitioner.memoryMap()->hull().greatest() + 1,
166  } else {
167  chunkAllocationRegion_ = AddressInterval::whole();
168  }
169  }
170 
174  static void initDiagnostics();
175 
183  const AddressInterval& chunkAllocationRegion() const { return chunkAllocationRegion_; }
184  void chunkAllocationRegion(const AddressInterval& i) { chunkAllocationRegion_ = i; }
190  const AddressIntervalSet& allocatedChunks() const { return allocatedChunks_; }
191 
198  size_t minChunkAllocationSize() const { return minChunkAllocationSize_; }
199  void minChunkAllocationSize(size_t n) { minChunkAllocationSize_ = n; }
205  size_t chunkAllocationAlignment() const { return chunkAllocationAlignment_; }
206  void chunkAllocationAlignment(size_t n);
212  const std::string& chunkAllocationName() const { return chunkAllocationName_; }
213  void chunkAllocationName(const std::string &s) { chunkAllocationName_ = s; }
224  unsigned aggregationDirection() const { return aggregationDirection_; }
225  void aggregationDirection(unsigned d) { aggregationDirection_ = d; }
234  NopPadding nopPadding() const { return nopPadding_; }
235  void nopPadding(NopPadding p) { nopPadding_ = p; }
264  size_t startIdx, size_t nInsns, std::vector<uint8_t> replacement,
265  const std::vector<Relocation> &relocations = std::vector<Relocation>());
266 
273  const std::vector<uint8_t> &replacement,
274  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
275  return replaceBlockInsns(bb, 0, nInsns, replacement, relocations);
276  }
277 
284  const std::vector<uint8_t> &replacement,
285  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
286  ASSERT_require(nInsns <= bb->nInstructions());
287  return replaceBlockInsns(bb, bb->nInstructions()-nInsns, nInsns, replacement, relocations);
288  }
289 
297  const std::vector<uint8_t> &replacement,
298  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
299  return replaceInsnsAtFront(bb, 0, replacement, relocations);
300  }
301 
309  const std::vector<uint8_t> &replacement,
310  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
311  return replaceInsnsAtBack(bb, 0, replacement, relocations);
312  }
313 
330  virtual bool replaceInsns(const std::vector<SgAsmInstruction*> &toReplace, const std::vector<uint8_t> &replacement,
331  const std::vector<Relocation> &relocations = std::vector<Relocation>());
332 
334  virtual void fillWithNops(const AddressIntervalSet &where);
335 
337  virtual void fillWithRandom(const AddressIntervalSet &where);
338 
344  virtual std::vector<uint8_t> encodeJump(rose_addr_t srcVa, rose_addr_t tgtVa);
345 
351  virtual std::vector<uint8_t> applyRelocations(rose_addr_t startVa, std::vector<uint8_t> replacement,
352  const std::vector<Relocation> &relocations, size_t relocStart,
353  const InstructionInfoMap &insnInfoMap);
354 
364  virtual AddressInterval allocateMemory(size_t nBytes, rose_addr_t jmpTargetVa, Commit::Boolean commit = Commit::YES);
365 
373  void commitAllocation(const AddressInterval &where, Commit::Boolean commit = Commit::YES);
374 
376  AddressIntervalSet instructionLocations(const std::vector<SgAsmInstruction*>&);
377 
386  virtual bool replaceByOverwrite(const AddressIntervalSet &toReplaceVas, const AddressInterval &entryInterval,
387  const std::vector<uint8_t> &replacement, const std::vector<Relocation> &relocations,
388  size_t relocStart, const InstructionInfoMap &insnInfoMap);
389 
399  virtual bool replaceByTransfer(const AddressIntervalSet &toReplaceVas, const AddressInterval &entryInterval,
400  const std::vector<SgAsmInstruction*> &toReplace, const std::vector<uint8_t> &replacement,
401  const std::vector<Relocation> &relocations, size_t relocStart,
402  const InstructionInfoMap &insnInfoMap);
403 
410  size_t startIdx, size_t nDeleted);
411 };
412 
413 } // namespace
414 } // namespace
415 
416 #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: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.
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:517
NopPadding
How to pad with no-ops.
Partitions instructions into basic blocks and functions.
Definition: Partitioner.h:317
Container associating values with keys.
Definition: Sawyer/Map.h:66
const AddressInterval & chunkAllocationRegion() const
Property: Where chunks are allocated.