1#ifndef ROSE_BinaryAnalysis_FeasiblePath_H
2#define ROSE_BinaryAnalysis_FeasiblePath_H
3#include <featureTests.h>
4#ifdef ROSE_ENABLE_BINARY_ANALYSIS
6#include <Rose/BinaryAnalysis/BasicTypes.h>
7#include <Rose/BinaryAnalysis/InstructionSemantics/SymbolicSemantics.h>
8#include <Rose/BinaryAnalysis/SmtSolver.h>
9#include <Rose/BinaryAnalysis/SymbolicExpressionParser.h>
10#include <Rose/BinaryAnalysis/Partitioner2/CfgPath.h>
11#include <Rose/Exception.h>
12#include <Sawyer/CommandLine.h>
13#include <Sawyer/Message.h>
14#include <boost/filesystem/path.hpp>
15#include <boost/logic/tribool.hpp>
18namespace BinaryAnalysis {
80 void print(std::ostream&)
const;
159 std::string registerName;
169 std::string toString()
const;
320 Partitioner2::ControlFlowGraph::ConstVertexIterator cfgCallTarget) = 0;
351 bool isDirectedSearch_ =
true;
360 mutable SAWYER_THREAD_TRAITS::Mutex statsMutex_;
378 SAWYER_THREAD_TRAITS::LockGuard lock(statsMutex_);
428 const Partitioner2::ControlFlowGraph::ConstVertexIterator &pathsBeginVertex);
444 size_t pathInsnIndex);
452 size_t pathInsnIndex);
459 const Partitioner2::ControlFlowGraph::ConstVertexIterator &pathsVertex,
460 size_t pathInsnIndex);
466 const Partitioner2::ControlFlowGraph::ConstVertexIterator &cfgCallTarget);
489 Partitioner2::ControlFlowGraph::ConstVertexIterator
490 pathToCfg(
const Partitioner2::ControlFlowGraph::ConstVertexIterator &pathVertex)
const;
506 bool isFunctionCall(
const Partitioner2::ControlFlowGraph::ConstVertexIterator&)
const;
509 void printPathVertex(std::ostream &out,
const Partitioner2::ControlFlowGraph::Vertex &pathVertex,
510 size_t &insnIdx )
const;
522 const Partitioner2::ControlFlowGraph::ConstVertexIterator &beginVertex,
546 const Partitioner2::ControlFlowGraph::ConstVertexIterator &cfgBeginVertex,
547 const Partitioner2::ControlFlowGraph::ConstVertexIterator &cfgEndVertex,
557 const Partitioner2::ControlFlowGraph::ConstVertexIterator &cfgBeginVertex,
568 return isDirectedSearch_;
596 return functionSummaries_;
638 SAWYER_THREAD_TRAITS::LockGuard lock(statsMutex_);
647 void checkSettings()
const;
649 static rose_addr_t virtualAddress(
const Partitioner2::ControlFlowGraph::ConstVertexIterator &vertex);
651 void insertCallSummary(
const Partitioner2::ControlFlowGraph::ConstVertexIterator &pathsCallSite,
653 const Partitioner2::ControlFlowGraph::ConstEdgeIterator &cfgCallEdge);
655 boost::filesystem::path emitPathGraph(
size_t callId,
size_t graphId);
668 SymbolicExpressionPtr pathEdgeConstraint(
const Partitioner2::ControlFlowGraph::ConstEdgeIterator &pathEdge,
681 static size_t vertexSize(
const Partitioner2::ControlFlowGraph::ConstVertexIterator&);
684 struct Substitutions {
686 std::vector<Expression> assertions;
694 solvePathConstraints(
const SmtSolverPtr&,
const Partitioner2::CfgPath&,
const SymbolicExpressionPtr &edgeAssertion,
695 const Substitutions&,
bool atEndOfPath);
698 void markAsReached(
const Partitioner2::ControlFlowGraph::ConstVertexIterator&);
707 Substitutions parseSubstitutions();
723 Semantics createSemantics(
const Partitioner2::CfgPath&, PathProcessor&,
const SmtSolverPtr&);
736 size_t incomingStepCount(
const Partitioner2::CfgPath&,
int position);
739 size_t outgoingStepCount(
const Partitioner2::CfgPath&,
int position);
747 boost::logic::tribool isFeasible(Partitioner2::CfgPath&,
const Substitutions&,
const Semantics&,
const SmtSolverPtr&);
754 double adjustEffectiveK(Partitioner2::CfgPath&,
double oldK);
758 void summarizeOrInline(Partitioner2::CfgPath&,
const Semantics&);
768 namespace CommandLine {
Exception for errors specific to feasible path analysis.
Base class for callbacks for function summaries.
virtual InstructionSemantics::SymbolicSemantics::SValuePtr returnValue(const FeasiblePath &analysis, const FunctionSummary &summary, const InstructionSemantics::SymbolicSemantics::RiscOperatorsPtr &ops)=0
Return value for function.
virtual void init(const FeasiblePath &analysis, FunctionSummary &summary, const Partitioner2::FunctionPtr &function, Partitioner2::ControlFlowGraph::ConstVertexIterator cfgCallTarget)=0
Invoked when a new summary is created.
Sawyer::SharedPointer< FunctionSummarizer > Ptr
Reference counting pointer.
virtual bool process(const FeasiblePath &analysis, const FunctionSummary &summary, const InstructionSemantics::SymbolicSemantics::RiscOperatorsPtr &ops)=0
Invoked when the analysis traverses the summary.
virtual Action memoryIo(const FeasiblePath &analyzer, const Partitioner2::CfgPath &path, SgAsmInstruction *insn, const InstructionSemantics::BaseSemantics::RiscOperatorsPtr &cpu, const SmtSolverPtr &solver, IoMode ioMode, const InstructionSemantics::BaseSemantics::SValuePtr &addr, const InstructionSemantics::BaseSemantics::SValuePtr &value)
Function invoked every time a memory reference occurs.
@ CONTINUE
Continue along this path.
@ BREAK
Do not continue along this path.
virtual Action nullDeref(const FeasiblePath &analyzer, const Partitioner2::CfgPath &path, SgAsmInstruction *insn, const InstructionSemantics::BaseSemantics::RiscOperatorsPtr &cpu, const SmtSolverPtr &solver, IoMode ioMode, const InstructionSemantics::BaseSemantics::SValuePtr &addr)
Function invoked whenever a null pointer dereference is detected.
virtual Action found(const FeasiblePath &analyzer, const Partitioner2::CfgPath &path, const InstructionSemantics::BaseSemantics::DispatcherPtr &cpu, const SmtSolverPtr &solver)
Function invoked whenever a complete path is found.
Statistics statistics() const
Cumulative statistics about prior analyses.
RegisterDescriptor REG_PATH
Descriptor of path pseudo-registers.
static Sawyer::CommandLine::SwitchGroup commandLineSwitches(Settings &settings)
Describe command-line switches.
void settings(const Settings &s)
Property: Settings used by this analysis.
IoMode
Read or write operation.
void setSearchBoundary(const Partitioner2::PartitionerConstPtr &partitioner, const Partitioner2::ControlFlowGraph::ConstVertexIterator &cfgBeginVertex, const Partitioner2::ControlFlowGraph::ConstVertexIterator &cfgEndVertex, const Partitioner2::CfgConstVertexSet &cfgAvoidVertices=Partitioner2::CfgConstVertexSet(), const Partitioner2::CfgConstEdgeSet &cfgAvoidEdges=Partitioner2::CfgConstEdgeSet())
Specify search boundary.
void setSearchBoundary(const Partitioner2::PartitionerConstPtr &partitioner, const Partitioner2::ControlFlowGraph::ConstVertexIterator &cfgBeginVertex, const Partitioner2::CfgConstVertexSet &cfgAvoidVertices=Partitioner2::CfgConstVertexSet(), const Partitioner2::CfgConstEdgeSet &cfgAvoidEdges=Partitioner2::CfgConstEdgeSet())
Specify search boundary.
Partitioner2::CfgConstVertexSet cfgToPaths(const Partitioner2::CfgConstVertexSet &) const
Convert CFG vertices to path vertices.
FeasiblePath()
Constructs a new feasible path analyzer.
MayOrMust
Types of comparisons.
bool isFunctionCall(const Partitioner2::ControlFlowGraph::ConstVertexIterator &) const
True if vertex is a function call.
double pathEffectiveK(const Partitioner2::CfgPath &) const
Effective maximum path length.
Sawyer::Container::Map< std::string, FeasiblePath::VarDetail > VarDetails
Variable detail by name.
void resetStatistics()
Reset only statistics.
virtual InstructionSemantics::BaseSemantics::DispatcherPtr buildVirtualCpu(const Partitioner2::PartitionerConstPtr &, const Partitioner2::CfgPath *, PathProcessor *, const SmtSolverPtr &)
Create the virtual CPU.
EdgeVisitOrder
Edge visitation order.
@ VISIT_NATURAL
Visit edges in their natural, forward order.
@ VISIT_RANDOM
Visit edges in random order.
@ VISIT_REVERSE
Visit edges in reverse of the natural order.
void setSearchBoundary(const Partitioner2::PartitionerConstPtr &partitioner, const Partitioner2::CfgConstVertexSet &cfgBeginVertices, const Partitioner2::CfgConstVertexSet &cfgEndVertices, const Partitioner2::CfgConstVertexSet &cfgAvoidVertices=Partitioner2::CfgConstVertexSet(), const Partitioner2::CfgConstEdgeSet &cfgAvoidEdges=Partitioner2::CfgConstEdgeSet())
Specify search boundary.
const VarDetail & varDetail(const InstructionSemantics::BaseSemantics::StatePtr &, const std::string &varName) const
Details about a variable.
virtual bool shouldInline(const Partitioner2::CfgPath &path, const Partitioner2::ControlFlowGraph::ConstVertexIterator &cfgCallTarget)
Determines whether a function call should be inlined.
bool isDirectedSearch() const
Property: Whether search is directed or not.
const FunctionSummaries & functionSummaries() const
Function summary information.
virtual void processVertex(const InstructionSemantics::BaseSemantics::DispatcherPtr &cpu, const Partitioner2::ControlFlowGraph::ConstVertexIterator &pathsVertex, size_t pathInsnIndex)
Process one vertex.
static InstructionSemantics::BaseSemantics::StatePtr pathPostState(const Partitioner2::CfgPath &, size_t vertexIdx)
Get the state at the end of the specified vertex.
virtual bool shouldSummarizeCall(const Partitioner2::ControlFlowGraph::ConstVertexIterator &pathVertex, const Partitioner2::ControlFlowGraph &cfg, const Partitioner2::ControlFlowGraph::ConstVertexIterator &cfgCallTarget)
Determines whether a function call should be summarized instead of inlined.
Partitioner2::CfgConstEdgeSet cfgToPaths(const Partitioner2::CfgConstEdgeSet &) const
Convert CFG edges to path edges.
bool isAnyEndpointReachable(const Partitioner2::ControlFlowGraph &cfg, const Partitioner2::ControlFlowGraph::ConstVertexIterator &beginVertex, const Partitioner2::CfgConstVertexSet &endVertices)
Determine whether any ending vertex is reachable.
void depthFirstSearch(PathProcessor &pathProcessor)
Find all feasible paths.
virtual void processFunctionSummary(const Partitioner2::ControlFlowGraph::ConstVertexIterator &pathsVertex, const InstructionSemantics::BaseSemantics::DispatcherPtr &cpu, size_t pathInsnIndex)
Process a function summary vertex.
Partitioner2::PartitionerConstPtr partitioner() const
Property: Partitioner currently in use.
static std::string expressionDocumentation()
Documentation for the symbolic expression parser.
FunctionSummarizer::Ptr functionSummarizer() const
Property: Function summary handling.
static Sawyer::Message::Facility mlog
Diagnostic output.
InstructionSemantics::BaseSemantics::StatePtr initialState() const
Get the initial state before the first path vertex.
void printPathVertex(std::ostream &out, const Partitioner2::ControlFlowGraph::Vertex &pathVertex, size_t &insnIdx) const
Print one vertex of a path for debugging.
virtual void setInitialState(const InstructionSemantics::BaseSemantics::DispatcherPtr &cpu, const Partitioner2::ControlFlowGraph::ConstVertexIterator &pathsBeginVertex)
Initialize state for first vertex of path.
Partitioner2::ControlFlowGraph::ConstVertexIterator pathToCfg(const Partitioner2::ControlFlowGraph::ConstVertexIterator &pathVertex) const
Convert path vertex to a CFG vertex.
const VarDetails & varDetails(const InstructionSemantics::BaseSemantics::StatePtr &) const
Details about all variables by name.
void functionSummarizer(const FunctionSummarizer::Ptr &f)
Property: Function summary handling.
void setSearchBoundary(const Partitioner2::PartitionerConstPtr &partitioner, const Partitioner2::CfgConstVertexSet &cfgBeginVertices, const Partitioner2::CfgConstVertexSet &cfgAvoidVertices=Partitioner2::CfgConstVertexSet(), const Partitioner2::CfgConstEdgeSet &cfgAvoidEdges=Partitioner2::CfgConstEdgeSet())
Specify search boundary.
SemanticMemoryParadigm
Organization of semantic memory.
@ MAP_BASED_MEMORY
Fast but not precise.
@ LIST_BASED_MEMORY
Precise but slow.
virtual void processBasicBlock(const Partitioner2::BasicBlockPtr &bblock, const InstructionSemantics::BaseSemantics::DispatcherPtr &cpu, size_t pathInsnIndex)
Process instructions for one basic block on the specified virtual CPU.
static size_t pathLength(const Partitioner2::CfgPath &, int position=-1)
Total length of path up to and including the specified vertex.
Settings & settings()
Property: Settings used by this analysis.
static void initDiagnostics()
Initialize diagnostic output.
SearchMode
How to search for paths.
@ SEARCH_SINGLE_DFS
Perform a depth first search.
@ SEARCH_SINGLE_BFS
Perform a breadth first search.
@ SEARCH_MULTI
Blast everything at once to the SMT solver.
const Settings & settings() const
Property: Settings used by this analysis.
bool pathEndsWithFunctionCall(const Partitioner2::CfgPath &) const
True if path ends with a function call.
const FunctionSummary & functionSummary(rose_addr_t entryVa) const
Function summary information.
Sawyer::Container::Map< rose_addr_t, FunctionSummary > FunctionSummaries
Summaries for multiple functions.
std::set< rose_addr_t > AddressSet
Set of basic block addresses.
virtual void processIndeterminateBlock(const Partitioner2::ControlFlowGraph::ConstVertexIterator &vertex, const InstructionSemantics::BaseSemantics::DispatcherPtr &cpu, size_t pathInsnIndex)
Process an indeterminate block.
void reset()
Reset to initial state without changing settings.
void printPath(std::ostream &out, const Partitioner2::CfgPath &) const
Print the path to the specified output stream.
A path through a control flow graph.
Describes (part of) a physical CPU register.
Satisfiable
Satisfiability constants.
Parses symbolic expressions from text.
Base class for all ROSE exceptions.
A collection of related switch declarations.
Container associating values with keys.
Converts text to messages.
Holds a value or nothing.
Base class for reference counted objects.
Base class for machine instructions.
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
boost::shared_ptr< Dispatcher > DispatcherPtr
Shared-ownership pointer to a semantics instruction dispatcher.
boost::shared_ptr< State > StatePtr
Shared-ownership pointer to a semantic state.
boost::shared_ptr< class RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to symbolic RISC operations.
std::shared_ptr< SmtSolver > SmtSolverPtr
Reference counting pointer.
const size_t UNLIMITED
Effectively unlimited size.
size_t Id
Attribute identification.
Expression to be evaluated.
SymbolicExpressionPtr expr
Symbolic expression.
AddressIntervalSet location
Location where constraint applies.
std::string parsable
String to be parsed as an expression.
Information stored per V_USER_DEFINED path vertex.
FunctionSummary()
Construct empty function summary.
std::string name
Name of summarized function.
FunctionSummary(const Partitioner2::ControlFlowGraph::ConstVertexIterator &cfgFuncVertex, uint64_t stackDelta)
Construct function summary with information.
int64_t stackDelta
Stack delta for summarized function.
rose_addr_t address
Address of summarized function.
rose_addr_t minValid
Minnimum address that is not treated as a null dereference.
bool constOnly
If true, check only constants or sets of constants.
MayOrMust mode
Check for addrs that may or must be null.
bool check
If true, look for null dereferences along the paths.
Settings that control this analysis.
struct Rose::BinaryAnalysis::FeasiblePath::Settings::NullDeref nullDeref
Settings for null-dereference analysis.
std::vector< rose_addr_t > summarizeFunctions
Functions to always summarize.
size_t maxPathLength
Limit path length in terms of number of instructions.
Sawyer::Optional< boost::chrono::duration< double > > smtTimeout
Max seconds allowed per SMT solve call.
SearchMode searchMode
Method to use when searching for feasible paths.
size_t maxVertexVisit
Max times to visit a particular vertex in one path.
Sawyer::Optional< rose_addr_t > initialStackPtr
Concrete value to use for stack pointer register initial value.
std::vector< std::string > assertionLocations
Locations at which "constraints" are checked.
bool processFinalVertex
Whether to process the last vertex of the path.
size_t maxCallDepth
Max length of path in terms of function calls.
bool ignoreSemanticFailure
Whether to ignore instructions with no semantic info.
std::vector< rose_addr_t > ipRewrite
An even number of from,to pairs for rewriting the insn ptr reg.
bool traceSemantics
Trace all instruction semantics operations.
bool nonAddressIsFeasible
Indeterminate/undiscovered vertices are feasible?
double kCycleCoefficient
Coefficient for adjusting maxPathLengh during CFG cycles.
SemanticMemoryParadigm memoryParadigm
Type of memory state when there's a choice to be made.
size_t maxRecursionDepth
Max path length in terms of recursive function calls.
std::string solverName
Type of SMT solver.
std::vector< Expression > assertions
Constraints to be satisfied at some point along the path.
bool trackingCodeCoverage
If set, track which block addresses are reached.
Settings()
Default settings.
EdgeVisitOrder edgeVisitOrder
Order in which to visit edges.
size_t maxExprSize
Maximum symbolic expression size before replacement.
std::string exprParserDoc
String documenting how expressions are parsed, empty for default.
Statistics from path searching.
size_t maxPathLengthHits
Number of times settings.maxPathLength was hit (effective K).
size_t maxVertexVisitHits
Number of times settings.maxVertexVisit was hit.
size_t nPathsExplored
Number of paths explored.
size_t maxCallDepthHits
Number of times settings.maxCallDepth was hit.
Sawyer::Container::Map< rose_addr_t, size_t > reachedBlockVas
Number of times each basic block was reached.
size_t maxRecursionDepthHits
Number of times settings.maxRecursionDepth was hit.
Information about a variable seen on a path.
Sawyer::Optional< size_t > firstAccessIdx
Instruction position in path where this var was first read.
std::string firstAccessMode
How was variable first accessed ("read" or "write").
SymbolicExpressionPtr memAddress
Address where variable is located.
size_t memSize
Size of total memory access in bytes.
Sawyer::Optional< rose_addr_t > returnFrom
This variable is the return value from the specified function.
size_t memByteNumber
Byte number for memory access.
SgAsmInstruction * firstAccessInsn
Instruction address where this var was first read.