ROSE  0.9.10.89
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 
153 public:
156 
157 public:
159  : partitioner_(partitioner), minChunkAllocationSize_(8192), chunkAllocationAlignment_(4096),
160  chunkAllocationName_("new code"), aggregationDirection_(AGGREGATE_PREDECESSORS | AGGREGATE_SUCCESSORS),
161  nopPadding_(PAD_NOP_BACK) {
162  ASSERT_not_null(partitioner.memoryMap());
163  if (!partitioner.memoryMap()->isEmpty() &&
164  partitioner.memoryMap()->hull().greatest() < AddressInterval::whole().greatest()) {
165  chunkAllocationRegion_ = AddressInterval::hull(partitioner.memoryMap()->hull().greatest() + 1,
167  } else {
168  chunkAllocationRegion_ = AddressInterval::whole();
169  }
170  }
171 
175  static void initDiagnostics();
176 
184  const AddressInterval& chunkAllocationRegion() const { return chunkAllocationRegion_; }
185  void chunkAllocationRegion(const AddressInterval& i) { chunkAllocationRegion_ = i; }
191  const AddressIntervalSet& allocatedChunks() const { return allocatedChunks_; }
192 
199  size_t minChunkAllocationSize() const { return minChunkAllocationSize_; }
200  void minChunkAllocationSize(size_t n) { minChunkAllocationSize_ = n; }
206  size_t chunkAllocationAlignment() const { return chunkAllocationAlignment_; }
207  void chunkAllocationAlignment(size_t n);
213  const std::string& chunkAllocationName() const { return chunkAllocationName_; }
214  void chunkAllocationName(const std::string &s) { chunkAllocationName_ = s; }
225  unsigned aggregationDirection() const { return aggregationDirection_; }
226  void aggregationDirection(unsigned d) { aggregationDirection_ = d; }
235  NopPadding nopPadding() const { return nopPadding_; }
236  void nopPadding(NopPadding p) { nopPadding_ = p; }
265  size_t startIdx, size_t nInsns, std::vector<uint8_t> replacement,
266  const std::vector<Relocation> &relocations = std::vector<Relocation>());
267 
274  const std::vector<uint8_t> &replacement,
275  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
276  return replaceBlockInsns(bb, 0, nInsns, replacement, relocations);
277  }
278 
285  const std::vector<uint8_t> &replacement,
286  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
287  ASSERT_require(nInsns <= bb->nInstructions());
288  return replaceBlockInsns(bb, bb->nInstructions()-nInsns, nInsns, replacement, relocations);
289  }
290 
298  const std::vector<uint8_t> &replacement,
299  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
300  return replaceInsnsAtFront(bb, 0, replacement, relocations);
301  }
302 
310  const std::vector<uint8_t> &replacement,
311  const std::vector<Relocation> &relocations = std::vector<Relocation>()) {
312  return replaceInsnsAtBack(bb, 0, replacement, relocations);
313  }
314 
331  virtual bool replaceInsns(const std::vector<SgAsmInstruction*> &toReplace, const std::vector<uint8_t> &replacement,
332  const std::vector<Relocation> &relocations = std::vector<Relocation>());
333 
335  virtual void fillWithNops(const AddressIntervalSet &where);
336 
338  virtual void fillWithRandom(const AddressIntervalSet &where);
339 
345  virtual std::vector<uint8_t> encodeJump(rose_addr_t srcVa, rose_addr_t tgtVa);
346 
352  virtual std::vector<uint8_t> applyRelocations(rose_addr_t startVa, std::vector<uint8_t> replacement,
353  const std::vector<Relocation> &relocations, size_t relocStart,
354  const InstructionInfoMap &insnInfoMap);
355 
365  virtual AddressInterval allocateMemory(size_t nBytes, rose_addr_t jmpTargetVa, Commit::Boolean commit = Commit::YES);
366 
374  void commitAllocation(const AddressInterval &where, Commit::Boolean commit = Commit::YES);
375 
377  AddressIntervalSet instructionLocations(const std::vector<SgAsmInstruction*>&);
378 
387  virtual bool replaceByOverwrite(const AddressIntervalSet &toReplaceVas, const AddressInterval &entryInterval,
388  const std::vector<uint8_t> &replacement, const std::vector<Relocation> &relocations,
389  size_t relocStart, const InstructionInfoMap &insnInfoMap);
390 
400  virtual bool replaceByTransfer(const AddressIntervalSet &toReplaceVas, const AddressInterval &entryInterval,
401  const std::vector<SgAsmInstruction*> &toReplace, const std::vector<uint8_t> &replacement,
402  const std::vector<Relocation> &relocations, size_t relocStart,
403  const InstructionInfoMap &insnInfoMap);
404 
411  size_t startIdx, size_t nDeleted);
412 };
413 
414 } // namespace
415 } // namespace
416 
417 #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:486
NopPadding
How to pad with no-ops.
Partitions instructions into basic blocks and functions.
Definition: Partitioner.h:293
Container associating values with keys.
Definition: Sawyer/Map.h:66
const AddressInterval & chunkAllocationRegion() const
Property: Where chunks are allocated.