ROSE  0.11.109.0
PointerDetection.h
1 #ifndef ROSE_BinaryAnalysis_PointerDetection_H
2 #define ROSE_BinaryAnalysis_PointerDetection_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include <Rose/BinaryAnalysis/Disassembler/BasicTypes.h>
7 #include <Rose/BinaryAnalysis/InstructionSemantics/BaseSemantics.h>
8 #include <Sawyer/Set.h>
9 
10 namespace Rose {
11 namespace BinaryAnalysis {
12 
13 namespace Partitioner2 {
14  class Partitioner;
15  class Function;
16 }
17 
18 
111 namespace PointerDetection {
112 
116 void initDiagnostics();
117 
122 
124 // Settings
126 
128 class Settings {
129 public:
135  bool ignoreConstIp = true;
136 
141  bool ignoreStrangeSizes = true;
142 
144  bool saveDataPointers = true;
145 
147  bool saveCodePointers = true;
148 
150  bool savePointerVas = true;
151 
153  bool savePointerAccesses = true;
154 
157 
160 
163 
165  uint64_t symbolicTrimThreshold = std::numeric_limits<uint64_t>::max();
166 
172 };
173 
175 // PointerDescriptor
177 
180 public:
182  enum Direction {
185  };
186 
188  struct Access {
189  rose_addr_t insnVa;
193  Access(rose_addr_t insnVa, Direction direction, const SymbolicExpression::Ptr &value)
194  : insnVa(insnVa), direction(direction), value(value) {}
195 
196  bool operator<(const Access &other) const {
197  if (insnVa != other.insnVa)
198  return insnVa < other.insnVa;
199  if (direction != other.direction)
200  return direction < other.direction;
201  if (value && other.value) {
202  return value->hash() < other.value->hash();
203  } else {
204  return !value && other.value;
205  }
206  }
207  };
208 
210  size_t nBits;
211  std::set<Access> pointerAccesses;
212  std::set<Access> dereferences;
214  PointerDescriptor(const SymbolicExpression::Ptr &pointerVa, size_t nBits, rose_addr_t insnVa, Direction dir,
215  const SymbolicExpression::Ptr &pointerValue)
216  : pointerVa(pointerVa), nBits(nBits) {
217  pointerAccesses.insert(Access(insnVa, dir, pointerValue));
218  }
219 };
220 
222 using PointerDescriptors = std::list<PointerDescriptor>;
223 
225 // Pointer analysis
227 
232 class Analysis {
233 public:
234 
235 private:
236  Settings settings_;
238  bool hasResults_; // Are the following data members initialized?
239  bool didConverge_; // Are the following data members valid (else only appoximations)?
240  PointerDescriptors codePointers_; // Memory addresses that hold a pointer to code
241  PointerDescriptors dataPointers_; // Memory addresses that hold a pointer to data
242  InstructionSemantics::BaseSemantics::StatePtr initialState_; // Initial state for analysis
243  InstructionSemantics::BaseSemantics::StatePtr finalState_; // Final state for analysis
244 
245 public:
252  : hasResults_(false), didConverge_(false) {}
253 
257  explicit Analysis(const Disassembler::BasePtr &d, const Settings &settings = Settings())
258  : settings_(settings), hasResults_(false), didConverge_(false) {
259  init(d);
260  }
261 
269  const Settings &settings = Settings())
270  : settings_(settings), cpu_(cpu), hasResults_(false), didConverge_(false) {}
271 
275  const Settings& settings() const { return settings_; }
276 
283 
288  bool hasResults() const { return hasResults_; }
289 
294  bool didConverge() const { return didConverge_; }
295 
300  void clearResults();
301 
306  void clearNonResults();
307 
313  return codePointers_;
314  }
315 
321  return dataPointers_;
322  }
323 
330  return initialState_;
331  }
332 
339  return finalState_;
340  }
341 
342 private:
343  void init(const Disassembler::BasePtr&);
344 
346  makeRiscOperators(const Partitioner2::Partitioner&) const;
347 
348  // Prints instructions to the mlog[DEBUG] diagnostic stream if that stream is enabled.
349  void
350  printInstructionsForDebugging(const Partitioner2::Partitioner&, const Sawyer::SharedPointer<Partitioner2::Function>&);
351 
352  // Given a potential pointer's r-value, determine if the r-value is a pointer and if so, store its address in the
353  // result. The pointer's value and the defining instructions are added to the two sets, and the result is not updated for
354  // values and instructions that have already been processed.
355  void
356  conditionallySavePointer(const InstructionSemantics::BaseSemantics::SValuePtr &ptrValue,
358 
359  // Prune results based on settings
360  void pruneResults(PointerDescriptors&);
361 };
362 
363 } // namespace
364 } // namespace
365 } // namespace
366 
367 #endif
368 #endif
bool saveDataPointers
Save information about data pointers.
Ordered set of values.
Definition: Set.h:52
InstructionSemantics::BaseSemantics::StatePtr finalState() const
Final state for analysis.
Analysis(const InstructionSemantics::BaseSemantics::DispatcherPtr &cpu, const Settings &settings=Settings())
Construct an analysis using a specified dispatcher.
Direction
Information about how a pointer is dereferenced.
InstructionSemantics::BaseSemantics::StatePtr initialState() const
Initial state for analysis.
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
Collection of streams.
Definition: Message.h:1606
bool didConverge() const
Whether the analysis results are valid.
const Settings & settings() const
Property: Analysis settings.
rose_addr_t insnVa
Instruction location where memory is accessed.
bool ignoreConstIp
Whether to ignore branches to concrete addresses.
bool ignoreStrangeSizes
Whether to ignore strange-sized pointers.
Settings to control the pointer analysis.
void clearNonResults()
Clears everything but results.
Main namespace for the ROSE library.
bool savePointerAccesses
Save information about where pointer variables are accessed.
boost::shared_ptr< State > StatePtr
Shared-ownership pointer to a semantic state.
SymbolicExpression::Ptr pointerVa
Symbolic address where pointer variable is stored.
std::set< Access > pointerAccesses
Where pointer variable's value was accessed.
boost::shared_ptr< Dispatcher > DispatcherPtr
Shared-ownership pointer to a semantics instruction dispatcher.
std::set< Access > dereferences
Where pointer was dereferenced.
bool savePointerVas
Save the pointer variable addresses in the results.
Direction direction
Whether memory is read or written.
bool savePointerDereferences
Save information about where pointer values are dereferenced.
Sawyer::Message::Facility mlog
Facility for diagnostic output.
void initDiagnostics()
Initialize diagnostics.
void clearResults()
Clear analysis results.
SymbolicExpression::Ptr value
Value read or written.
bool savePointerAccessValues
Save pointer accessed values if pointer accesses are saved.
size_t maximumDataFlowIterationFactor
Maximum data-flow iteration factor.
const PointerDescriptors & codePointers() const
Property: Code pointers.
Analysis(const Disassembler::BasePtr &d, const Settings &settings=Settings())
Construct an analysis using a specific disassembler.
const PointerDescriptors & dataPointers() const
Property: Data pointers.
void analyzeFunction(const Partitioner2::Partitioner &, const Sawyer::SharedPointer< Partitioner2::Function > &)
Analyze one function.
Partitions instructions into basic blocks and functions.
Definition: Partitioner.h:294
bool hasResults() const
Whether a function has been analyzed.
bool saveCodePointers
Save information about code pointers.
uint64_t symbolicTrimThreshold
Threshold for replacing large symbolic expressions with new variables.
std::list< PointerDescriptor > PointerDescriptors
Set of pointers.
bool savePointerDereferenceValues
Save pointer dereferenced values if dereferences are saved.