ROSE  0.11.145.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/Partitioner2/BasicTypes.h>
8 #include <Rose/BinaryAnalysis/InstructionSemantics/BaseSemantics.h>
9 #include <Sawyer/Set.h>
10 
11 namespace Rose {
12 namespace BinaryAnalysis {
13 
106 namespace PointerDetection {
107 
111 void initDiagnostics();
112 
117 
119 // Settings
121 
123 class Settings {
124 public:
130  bool ignoreConstIp = true;
131 
136  bool ignoreStrangeSizes = true;
137 
139  bool saveDataPointers = true;
140 
142  bool saveCodePointers = true;
143 
145  bool savePointerVas = true;
146 
148  bool savePointerAccesses = true;
149 
152 
155 
158 
160  uint64_t symbolicTrimThreshold = std::numeric_limits<uint64_t>::max();
161 
167 };
168 
170 // PointerDescriptor
172 
175 public:
177  enum Direction {
180  };
181 
183  struct Access {
184  rose_addr_t insnVa;
188  Access(rose_addr_t insnVa, Direction direction, const SymbolicExpression::Ptr &value)
189  : insnVa(insnVa), direction(direction), value(value) {}
190 
191  bool operator<(const Access &other) const {
192  if (insnVa != other.insnVa)
193  return insnVa < other.insnVa;
194  if (direction != other.direction)
195  return direction < other.direction;
196  if (value && other.value) {
197  return value->hash() < other.value->hash();
198  } else {
199  return !value && other.value;
200  }
201  }
202  };
203 
205  size_t nBits;
206  std::set<Access> pointerAccesses;
207  std::set<Access> dereferences;
209  PointerDescriptor(const SymbolicExpression::Ptr &pointerVa, size_t nBits, rose_addr_t insnVa, Direction dir,
210  const SymbolicExpression::Ptr &pointerValue)
211  : pointerVa(pointerVa), nBits(nBits) {
212  pointerAccesses.insert(Access(insnVa, dir, pointerValue));
213  }
214 };
215 
217 using PointerDescriptors = std::list<PointerDescriptor>;
218 
220 // Pointer analysis
222 
227 class Analysis {
228 public:
229 
230 private:
231  Settings settings_;
233  bool hasResults_; // Are the following data members initialized?
234  bool didConverge_; // Are the following data members valid (else only appoximations)?
235  PointerDescriptors codePointers_; // Memory addresses that hold a pointer to code
236  PointerDescriptors dataPointers_; // Memory addresses that hold a pointer to data
237  InstructionSemantics::BaseSemantics::StatePtr initialState_; // Initial state for analysis
238  InstructionSemantics::BaseSemantics::StatePtr finalState_; // Final state for analysis
239 
240 public:
247  : hasResults_(false), didConverge_(false) {}
248 
252  explicit Analysis(const Disassembler::BasePtr &d, const Settings &settings = Settings())
253  : settings_(settings), hasResults_(false), didConverge_(false) {
254  init(d);
255  }
256 
264  const Settings &settings = Settings())
265  : settings_(settings), cpu_(cpu), hasResults_(false), didConverge_(false) {}
266 
270  const Settings& settings() const { return settings_; }
271 
278 
283  bool hasResults() const { return hasResults_; }
284 
289  bool didConverge() const { return didConverge_; }
290 
295  void clearResults();
296 
301  void clearNonResults();
302 
308  return codePointers_;
309  }
310 
316  return dataPointers_;
317  }
318 
325  return initialState_;
326  }
327 
334  return finalState_;
335  }
336 
337 private:
338  void init(const Disassembler::BasePtr&);
339 
341  makeRiscOperators(const Partitioner2::PartitionerConstPtr&) const;
342 
343  // Prints instructions to the mlog[DEBUG] diagnostic stream if that stream is enabled.
344  void
345  printInstructionsForDebugging(const Partitioner2::PartitionerConstPtr&, const Sawyer::SharedPointer<Partitioner2::Function>&);
346 
347  // Given a potential pointer's r-value, determine if the r-value is a pointer and if so, store its address in the
348  // result. The pointer's value and the defining instructions are added to the two sets, and the result is not updated for
349  // values and instructions that have already been processed.
350  void
351  conditionallySavePointer(const InstructionSemantics::BaseSemantics::SValuePtr &ptrValue,
353 
354  // Prune results based on settings
355  void pruneResults(PointerDescriptors&);
356 };
357 
358 } // namespace
359 } // namespace
360 } // namespace
361 
362 #endif
363 #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.
void analyzeFunction(const Partitioner2::PartitionerConstPtr &, const Sawyer::SharedPointer< Partitioner2::Function > &)
Analyze one function.
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.
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.