ROSE  0.11.101.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 struct Settings {
134  bool ignoreConstIp = true;
135 
140  bool ignoreStrangeSizes = true;
141 
143  bool saveDataPointers = true;
144 
146  bool saveCodePointers = true;
147 
149  bool savePointerVas = true;
150 
152  bool savePointerAccesses = true;
153 
156 
159 
162 
164  uint64_t symbolicTrimThreshold = std::numeric_limits<uint64_t>::max();
165 
171 };
172 
174 // PointerDescriptor
176 
180  enum Direction {
183  };
184 
186  struct Access {
187  rose_addr_t insnVa;
191  Access(rose_addr_t insnVa, Direction direction, const SymbolicExpression::Ptr &value)
192  : insnVa(insnVa), direction(direction), value(value) {}
193 
194  bool operator<(const Access &other) const {
195  if (insnVa != other.insnVa)
196  return insnVa < other.insnVa;
197  if (direction != other.direction)
198  return direction < other.direction;
199  return value->hash() < other.value->hash();
200  }
201  };
202 
204  size_t nBits;
205  std::set<Access> pointerAccesses;
206  std::set<Access> dereferences;
208  PointerDescriptor(const SymbolicExpression::Ptr &pointerVa, size_t nBits, rose_addr_t insnVa, Direction dir,
209  const SymbolicExpression::Ptr &pointerValue)
210  : pointerVa(pointerVa), nBits(nBits) {
211  pointerAccesses.insert(Access(insnVa, dir, pointerValue));
212  }
213 };
214 
216 using PointerDescriptors = std::list<PointerDescriptor>;
217 
219 // Pointer analysis
221 
226 class Analysis {
227 public:
228 
229 private:
230  Settings settings_;
232  bool hasResults_; // Are the following data members initialized?
233  bool didConverge_; // Are the following data members valid (else only appoximations)?
234  PointerDescriptors codePointers_; // Memory addresses that hold a pointer to code
235  PointerDescriptors dataPointers_; // Memory addresses that hold a pointer to data
236  InstructionSemantics::BaseSemantics::StatePtr initialState_; // Initial state for analysis
237  InstructionSemantics::BaseSemantics::StatePtr finalState_; // Final state for analysis
238 
239 public:
246  : hasResults_(false), didConverge_(false) {}
247 
251  explicit Analysis(const Disassembler::BasePtr &d, const Settings &settings = Settings())
252  : hasResults_(false), didConverge_(false) {
253  init(d);
254  }
255 
263  const Settings &settings = Settings())
264  : cpu_(cpu), hasResults_(false), didConverge_(false) {}
265 
269  const Settings& settings() const { return settings_; }
270 
277 
282  bool hasResults() const { return hasResults_; }
283 
288  bool didConverge() const { return didConverge_; }
289 
294  void clearResults();
295 
300  void clearNonResults();
301 
307  return codePointers_;
308  }
309 
315  return dataPointers_;
316  }
317 
324  return initialState_;
325  }
326 
333  return finalState_;
334  }
335 
336 private:
337  void init(const Disassembler::BasePtr&);
338 
340  makeRiscOperators(const Partitioner2::Partitioner&) const;
341 
342  // Prints instructions to the mlog[DEBUG] diagnostic stream if that stream is enabled.
343  void
344  printInstructionsForDebugging(const Partitioner2::Partitioner&, const Sawyer::SharedPointer<Partitioner2::Function>&);
345 
346  // Given a potential pointer's r-value, determine if the r-value is a pointer and if so, store its address in the
347  // result. The pointer's value and the defining instructions are added to the two sets, and the result is not updated for
348  // values and instructions that have already been processed.
349  void
350  conditionallySavePointer(const InstructionSemantics::BaseSemantics::SValuePtr &ptrValue,
352 
353  // Prune results based on settings
354  void pruneResults(PointerDescriptors&);
355 };
356 
357 } // namespace
358 } // namespace
359 } // namespace
360 
361 #endif
362 #endif
Ordered set of values.
Definition: Set.h:52
bool saveCodePointers
Save information about code pointers.
bool savePointerVas
Save the pointer variable addresses in the results.
InstructionSemantics::BaseSemantics::StatePtr finalState() const
Final state for analysis.
std::set< Access > pointerAccesses
Where pointer variable's value was accessed.
Settings to control the pointer analysis.
size_t maximumDataFlowIterationFactor
Maximum data-flow iteration factor.
Analysis(const InstructionSemantics::BaseSemantics::DispatcherPtr &cpu, const Settings &settings=Settings())
Construct an analysis using a specified dispatcher.
SymbolicExpression::Ptr pointerVa
Symbolic address where pointer variable is stored.
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.
uint64_t symbolicTrimThreshold
Threshold for replacing large symbolic expressions with new variables.
void clearNonResults()
Clears everything but results.
Main namespace for the ROSE library.
boost::shared_ptr< State > StatePtr
Shared-ownership pointer to a semantic state.
boost::shared_ptr< Dispatcher > DispatcherPtr
Shared-ownership pointer to a semantics instruction dispatcher.
Direction direction
Whether memory is read or written.
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 savePointerDereferenceValues
Save pointer dereferenced values if dereferences are saved.
Binary analysis.
std::set< Access > dereferences
Where pointer was dereferenced.
bool savePointerDereferences
Save information about where pointer values are dereferenced.
const PointerDescriptors & codePointers() const
Property: Code pointers.
bool savePointerAccesses
Save information about where pointer variables are accessed.
Analysis(const Disassembler::BasePtr &d, const Settings &settings=Settings())
Construct an analysis using a specific disassembler.
Direction
Information about how a pointer is dereferenced.
const PointerDescriptors & dataPointers() const
Property: Data pointers.
bool ignoreStrangeSizes
Whether to ignore strange-sized 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 savePointerAccessValues
Save pointer accessed values if pointer accesses are saved.
bool saveDataPointers
Save information about data pointers.
std::list< PointerDescriptor > PointerDescriptors
Set of pointers.