ROSE  0.11.145.0
EngineBinary.h
1 #ifndef ROSE_BinaryAnalysis_Partitioner2_EngineBinary_H
2 #define ROSE_BinaryAnalysis_Partitioner2_EngineBinary_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include <Rose/BinaryAnalysis/Partitioner2/Engine.h>
7 #include <Rose/BinaryAnalysis/Partitioner2/ModulesLinux.h>
8 #include <Rose/BinaryAnalysis/Partitioner2/Utility.h>
9 #include <Rose/BinaryAnalysis/SerialIo.h>
10 
11 #include <boost/noncopyable.hpp>
12 #include <boost/regex.hpp>
13 #include <stdexcept>
14 
15 #ifdef ROSE_ENABLE_PYTHON_API
16 #undef slots // stupid Qt pollution
17 #include <boost/python.hpp>
18 #endif
19 
20 namespace Rose {
21 namespace BinaryAnalysis {
22 namespace Partitioner2 {
23 
47 class EngineBinary: public Engine {
49  // Types
51 public:
54 
55 private:
56  using Super = Engine;
57 
59  // Data members
61 private:
62  BinaryLoaderPtr binaryLoader_; // how to remap, link, and fixup
63  ModulesLinux::LibcStartMain::Ptr libcStartMain_; // looking for "main" by analyzing libc_start_main?
64  ThunkPredicatesPtr functionMatcherThunks_; // predicates to find thunks when looking for functions
65  ThunkPredicatesPtr functionSplittingThunks_; // predicates for splitting thunks from front of functions
66 
68  // Constructors
70 protected:
72  EngineBinary() = delete;
73 
74  explicit EngineBinary(const Settings&);
75 
76 public:
77  virtual ~EngineBinary();
78 
80  static EngineBinaryPtr instance();
81 
83  static EngineBinaryPtr instance(const Settings&);
84 
86  static EngineBinaryPtr factory();
87 
88  virtual bool matchFactory(const std::vector<std::string> &specimen) const override;
89  virtual EnginePtr instanceFromFactory(const Settings&) override;
90 
92  // The very top-level use case
94 public:
119  using Engine::frontend;
120  SgAsmBlock* frontend(const std::vector<std::string> &args,
121  const std::string &purpose, const std::string &description) override;
124  // Basic top-level steps
127 public:
133  virtual void reset() override;
134 
154  using Engine::parseContainers;
155  virtual SgAsmInterpretation* parseContainers(const std::vector<std::string> &fileNames) override;
178  using Engine::loadSpecimens;
179  virtual MemoryMapPtr loadSpecimens(const std::vector<std::string> &fileNames = std::vector<std::string>()) override;
201  using Engine::partition;
202  virtual PartitionerPtr partition(const std::vector<std::string> &fileNames = std::vector<std::string>()) override;
219  using Engine::buildAst;
220  virtual SgAsmBlock* buildAst(const std::vector<std::string> &fileNames = std::vector<std::string>()) override;
223  // Command-line parsing
226 
227  virtual std::list<Sawyer::CommandLine::SwitchGroup> commandLineSwitches() override;
228  virtual std::pair<std::string, std::string> specimenNameDocumentation() override;
229 
234 
239 
244 
249 
254 
255 
257  // Container parsing
258  //
259  // top-level: parseContainers
261 public:
266  virtual bool isNonContainer(const std::string&) override;
267 
273  virtual bool areContainersParsed() const override;
274 
279  virtual void loadVxCore(const std::string &spec);
280 
282  // Load specimens
283  //
284  // top-level: loadSpecimens
286 public:
304  virtual BinaryLoaderPtr obtainLoader(const BinaryLoaderPtr &hint);
305  virtual BinaryLoaderPtr obtainLoader();
313  virtual void loadContainers(const std::vector<std::string> &fileNames);
314 
319  virtual void loadNonContainers(const std::vector<std::string> &names);
320 
322  // Partitioner high-level functions
323  //
324  // top-level: partition
326 public:
333 
340 
346 
351  virtual PartitionerPtr createPartitioner() override;
352 
356  virtual void runPartitionerInit(const PartitionerPtr&) override;
357 
361  virtual void runPartitionerRecursive(const PartitionerPtr&) override;
362 
367  virtual void runPartitionerFinal(const PartitionerPtr&) override;
368 
374  virtual bool partitionCilSections(const PartitionerPtr&);
375 
380  bool hasCilCodeSection();
381 
383  // Partitioner mid-level functions
384  //
385  // These are the functions called by the partitioner high-level stuff. These are sometimes overridden in subclasses,
386  // although it is more likely that the high-level stuff is overridden.
388 public:
395  virtual std::vector<FunctionPtr> makeEntryFunctions(const PartitionerPtr&, SgAsmInterpretation*);
396 
403  virtual std::vector<FunctionPtr> makeErrorHandlingFunctions(const PartitionerPtr&, SgAsmInterpretation*);
404 
414  virtual std::vector<FunctionPtr> makeImportFunctions(const PartitionerPtr&, SgAsmInterpretation*);
415 
422  virtual std::vector<FunctionPtr> makeExportFunctions(const PartitionerPtr&, SgAsmInterpretation*);
423 
430  virtual std::vector<FunctionPtr> makeSymbolFunctions(const PartitionerPtr&, SgAsmInterpretation*);
431 
439  virtual std::vector<FunctionPtr> makeContainerFunctions(const PartitionerPtr&, SgAsmInterpretation*);
440 
447  virtual std::vector<FunctionPtr> makeInterruptVectorFunctions(const PartitionerPtr&, const AddressInterval &vector);
448 
453  virtual std::vector<FunctionPtr> makeUserFunctions(const PartitionerPtr&, const std::vector<rose_addr_t>&);
454 
461  virtual void discoverBasicBlocks(const PartitionerPtr&);
462 
474  virtual FunctionPtr makeNextDataReferencedFunction(const PartitionerConstPtr&, rose_addr_t &startVa /*in,out*/);
475 
490 
497  virtual std::vector<FunctionPtr> makeCalledFunctions(const PartitionerPtr&);
498 
514  virtual std::vector<FunctionPtr> makeNextPrologueFunction(const PartitionerPtr&, rose_addr_t startVa);
515  virtual std::vector<FunctionPtr> makeNextPrologueFunction(const PartitionerPtr&, rose_addr_t startVa,
516  rose_addr_t &lastSearchedVa);
537  virtual std::vector<FunctionPtr>
538  makeFunctionFromInterFunctionCalls(const PartitionerPtr&, rose_addr_t &startVa /*in,out*/);
539 
546  virtual void discoverFunctions(const PartitionerPtr&);
547 
562  virtual std::set<rose_addr_t> attachDeadCodeToFunction(const PartitionerPtr&, const FunctionPtr&,
563  size_t maxIterations=size_t(-1));
564 
573 
578  virtual std::vector<DataBlockPtr> attachPaddingToFunctions(const PartitionerPtr&);
579 
590  virtual size_t attachAllSurroundedCodeToFunctions(const PartitionerPtr&);
591 
599  virtual size_t attachSurroundedCodeToFunctions(const PartitionerPtr&);
600 
605  virtual void attachBlocksToFunctions(const PartitionerPtr&);
606 
613  virtual std::set<rose_addr_t> attachDeadCodeToFunctions(const PartitionerPtr&, size_t maxIterations=size_t(-1));
614 
624  virtual std::vector<DataBlockPtr> attachSurroundedDataToFunctions(const PartitionerPtr&);
625 
627  // Partitioner low-level functions
628  //
629  // These are functions that a subclass seldom overrides, and maybe even shouldn't override because of their complexity or
630  // the way the interact with one another.
632 public:
643  virtual bool makeNextCallReturnEdge(const PartitionerPtr&, boost::logic::tribool assumeCallReturns);
644 
651 
667 
668 
670  // Build AST
672 
674  // Settings and properties
676 public:
683  BinaryLoaderPtr binaryLoader() const /*final*/;
684  virtual void binaryLoader(const BinaryLoaderPtr&);
695  ThunkPredicatesPtr functionMatcherThunks() const /*final*/;
696  virtual void functionMatcherThunks(const ThunkPredicatesPtr&);
707  ThunkPredicatesPtr functionSplittingThunks() const /*final*/;
708  virtual void functionSplittingThunks(const ThunkPredicatesPtr&);
711  // Python API support functions
714 #ifdef ROSE_ENABLE_PYTHON_API
715 
716  // Similar to frontend, but returns a partitioner rather than an AST since the Python API doesn't yet support ASTs.
717  PartitionerPtr pythonParseVector(boost::python::list &pyArgs, const std::string &purpose, const std::string &description);
718  PartitionerPtr pythonParseSingle(const std::string &specimen, const std::string &purpose, const std::string &description);
719 
720 #endif
721 
723  // Internal stuff
725 private:
726  void init();
727 
728  // Similar to ::frontend but a lot less complicated.
729  virtual SgProject* roseFrontendReplacement(const std::vector<boost::filesystem::path> &fileNames) override;
730 };
731 
732 } // namespace
733 } // namespace
734 } // namespace
735 
736 #endif
737 #endif
virtual std::set< rose_addr_t > attachDeadCodeToFunction(const PartitionerPtr &, const FunctionPtr &, size_t maxIterations=size_t(-1))
Attach dead code to function.
virtual void reset() override
Reset the engine to its initial state.
virtual void loadVxCore(const std::string &spec)
Parses a vxcore specification and initializes memory.
virtual void runPartitionerInit(const PartitionerPtr &) override
Finds interesting things to work on initially.
EngineBinary()=delete
Default constructor.
virtual std::vector< FunctionPtr > makeFunctionFromInterFunctionCalls(const PartitionerPtr &, rose_addr_t &startVa)
Make functions from inter-function calls.
Instruction basic block.
virtual std::vector< FunctionPtr > makeCalledFunctions(const PartitionerPtr &)
Make functions for function call edges.
virtual bool areContainersParsed() const override
Returns true if containers are parsed.
virtual void attachBlocksToFunctions(const PartitionerPtr &)
Attach basic blocks to functions.
virtual size_t attachSurroundedCodeToFunctions(const PartitionerPtr &)
Attach intra-function basic blocks to functions.
Engine for specimens containing machine instructions.
Definition: EngineBinary.h:47
Base class for engines driving the partitioner.
virtual FunctionPtr makeNextDataReferencedFunction(const PartitionerConstPtr &, rose_addr_t &startVa)
Scan read-only data to find function pointers.
virtual PartitionerPtr createPartitionerFromAst(SgAsmInterpretation *)
Create a partitioner from an AST.
virtual BasicBlockPtr makeNextBasicBlockFromPlaceholder(const PartitionerPtr &)
Discover basic block at next placeholder.
virtual std::vector< FunctionPtr > makeErrorHandlingFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions at error handling addresses.
static Sawyer::CommandLine::SwitchGroup disassemblerSwitches(DisassemblerSettings &)
Command-line switches related to decoding instructions.
Engine()=delete
Default constructor.
A collection of related switch declarations.
virtual std::vector< FunctionPtr > makeImportFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions at import trampolines.
virtual DataBlockPtr attachPaddingToFunction(const PartitionerPtr &, const FunctionPtr &)
Attach function padding to function.
Main namespace for the ROSE library.
static Sawyer::CommandLine::SwitchGroup engineSwitches(EngineSettings &)
Command-line switches related to the general engine behavior.
ThunkPredicatesPtr functionSplittingThunks() const
Property: Predicate for finding thunks at the start of functions.
static EngineBinaryPtr instance()
Allocating constructor.
static Sawyer::CommandLine::SwitchGroup astConstructionSwitches(AstConstructionSettings &)
Command-line switches related to constructing an AST from the partitioner.
BinaryLoaderPtr binaryLoader() const
Property: binary loader.
virtual void loadContainers(const std::vector< std::string > &fileNames)
Loads memory from binary containers.
static Sawyer::CommandLine::SwitchGroup loaderSwitches(LoaderSettings &)
Command-line switches related to loading specimen into memory.
virtual PartitionerPtr createTunedPartitioner()
Create a tuned partitioner.
virtual void runPartitionerFinal(const PartitionerPtr &) override
Runs the final parts of partitioning.
virtual std::vector< FunctionPtr > makeInterruptVectorFunctions(const PartitionerPtr &, const AddressInterval &vector)
Make functions from an interrupt vector.
virtual bool partitionCilSections(const PartitionerPtr &)
Partition any sections containing CIL code.
virtual std::vector< DataBlockPtr > attachPaddingToFunctions(const PartitionerPtr &)
Attach padding to all functions.
virtual size_t attachAllSurroundedCodeToFunctions(const PartitionerPtr &)
Attach all possible intra-function basic blocks to functions.
virtual std::set< rose_addr_t > attachDeadCodeToFunctions(const PartitionerPtr &, size_t maxIterations=size_t(-1))
Attach dead code to functions.
virtual FunctionPtr makeNextCodeReferencedFunction(const PartitionerConstPtr &)
Scan instruction ASTs to function pointers.
Sawyer::SharedPointer< EngineBinary > EngineBinaryPtr
Shared-ownership pointer for EngineBinary.
static Sawyer::CommandLine::SwitchGroup partitionerSwitches(PartitionerSettings &)
Command-line switches related to partitioning instructions.
static EngineBinaryPtr factory()
Allocate a factory.
virtual PartitionerPtr createGenericPartitioner()
Create a generic partitioner.
virtual std::vector< FunctionPtr > makeContainerFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions based on specimen container.
virtual void discoverBasicBlocks(const PartitionerPtr &)
Discover as many basic blocks as possible.
virtual std::vector< FunctionPtr > makeExportFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions at export addresses.
virtual std::vector< FunctionPtr > makeUserFunctions(const PartitionerPtr &, const std::vector< rose_addr_t > &)
Make a function at each specified address.
virtual void loadNonContainers(const std::vector< std::string > &names)
Loads memory from non-containers.
bool hasCilCodeSection()
Determine whether the interpretation header contains a CIL code section.
virtual std::vector< FunctionPtr > makeEntryFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions at specimen entry addresses.
virtual void discoverFunctions(const PartitionerPtr &)
Discover as many functions as possible.
virtual bool isNonContainer(const std::string &) override
Determine whether a specimen name is a non-container.
virtual BinaryLoaderPtr obtainLoader()
Obtain a binary loader.
virtual PartitionerPtr createPartitioner() override
Create partitioner.
virtual bool makeNextCallReturnEdge(const PartitionerPtr &, boost::logic::tribool assumeCallReturns)
Insert a call-return edge and discover its basic block.
virtual std::vector< FunctionPtr > makeNextPrologueFunction(const PartitionerPtr &, rose_addr_t startVa)
Make function at prologue pattern.
ThunkPredicatesPtr functionMatcherThunks() const
Property: Predicate for finding functions that are thunks.
This class represents a source project, with a list of SgFile objects and global information about th...
virtual std::vector< DataBlockPtr > attachSurroundedDataToFunctions(const PartitionerPtr &)
Attach intra-function data to functions.
virtual BasicBlockPtr makeNextBasicBlock(const PartitionerPtr &)
Discover a basic block.
virtual void runPartitionerRecursive(const PartitionerPtr &) override
Runs the recursive part of partioning.
Represents an interpretation of a binary container.
virtual std::vector< FunctionPtr > makeSymbolFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions for symbols.