ROSE  0.9.10.54
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.
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 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.
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(T v1, 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.
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.