ROSE 2.20.0
Loading...
Searching...
No Matches
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/Architecture/BasicTypes.h>
7#include <Rose/BinaryAnalysis/AddressIntervalSet.h>
8#include <Rose/BinaryAnalysis/Partitioner2/Engine.h>
9#include <Rose/BinaryAnalysis/Partitioner2/ModulesLinux.h>
10#include <Rose/BinaryAnalysis/Partitioner2/Utility.h>
11#include <Rose/BinaryAnalysis/SerialIo.h>
12
13#include <boost/noncopyable.hpp>
14#include <boost/regex.hpp>
15#include <stdexcept>
16#include <tuple>
17
18#ifdef ROSE_ENABLE_PYTHON_API
19#undef slots // stupid Qt pollution
20#include <boost/python.hpp>
21#endif
22
23namespace Rose {
24namespace BinaryAnalysis {
25namespace Partitioner2 {
26
50class EngineBinary: public Engine {
52 // Types
54public:
57
58private:
59 using Super = Engine;
60
62 // Data members
64private:
65 BinaryLoaderPtr binaryLoader_; // how to remap, link, and fixup
66 ModulesLinux::LibcStartMain::Ptr libcStartMain_; // looking for "main" by analyzing libc_start_main?
67 ThunkPredicatesPtr functionMatcherThunks_; // predicates to find thunks when looking for functions
68 ThunkPredicatesPtr functionSplittingThunks_; // predicates for splitting thunks from front of functions
69
71 // Constructors
73protected:
75 EngineBinary() = delete;
76
77 explicit EngineBinary(const Settings&);
78
79public:
80 virtual ~EngineBinary();
81
83 static Ptr instance();
84
86 static Ptr instance(const Settings&);
87
89 static Ptr factory();
90
92 // Command-line parsing
94public:
95
100
105
110
115
120
121
123 // Container parsing
124 //
125 // top-level: parseContainers
127public:
132 virtual void loadVxCore(const std::string &spec);
133
135 // Load specimens
136 //
137 // top-level: loadSpecimens
139public:
166 virtual void loadContainers(const std::vector<std::string> &fileNames);
167
172 virtual void loadNonContainers(const std::vector<std::string> &names);
173
175 // Partitioner high-level functions
176 //
177 // top-level: partition
179public:
185
191
198 virtual std::tuple<bool, std::vector<Address>> partitionCilSections(const PartitionerPtr&);
199
205
211
216 virtual std::vector<Address> cilMethodRvasToVas(const std::vector<Address>&) const;
217
219 // Partitioner mid-level functions
220 //
221 // These are the functions called by the partitioner high-level stuff. These are sometimes overridden in subclasses,
222 // although it is more likely that the high-level stuff is overridden.
224public:
231 virtual std::vector<FunctionPtr> makeEntryFunctions(const PartitionerPtr&, SgAsmInterpretation*);
232
239 virtual std::vector<FunctionPtr> makeErrorHandlingFunctions(const PartitionerPtr&, SgAsmInterpretation*);
240
250 virtual std::vector<FunctionPtr> makeImportFunctions(const PartitionerPtr&, SgAsmInterpretation*);
251
258 virtual std::vector<FunctionPtr> makeExportFunctions(const PartitionerPtr&, SgAsmInterpretation*);
259
266 virtual std::vector<FunctionPtr> makeSymbolFunctions(const PartitionerPtr&, SgAsmInterpretation*);
267
275 virtual std::vector<FunctionPtr> makeContainerFunctions(const PartitionerPtr&, SgAsmInterpretation*);
276
283 virtual std::vector<FunctionPtr> makeInterruptVectorFunctions(const PartitionerPtr&, const AddressInterval &vector);
284
289 virtual std::vector<FunctionPtr> makeUserFunctions(const PartitionerPtr&, const std::vector<Address>&);
290
292 virtual std::vector<FunctionPtr> makeCilNativeFunctions(const PartitionerPtr&, const std::vector<Address>&);
293
301
314
329
336 virtual std::vector<FunctionPtr> makeCalledFunctions(const PartitionerPtr&);
337
353 virtual std::vector<FunctionPtr> makeNextPrologueFunction(const PartitionerPtr&, Address startVa);
354 virtual std::vector<FunctionPtr> makeNextPrologueFunction(const PartitionerPtr&, Address startVa, Address &lastSearchedVa);
375 virtual std::vector<FunctionPtr>
377
384 virtual void discoverFunctions(const PartitionerPtr&);
385
400 virtual std::set<Address> attachDeadCodeToFunction(const PartitionerPtr&, const FunctionPtr&, size_t maxIterations=size_t(-1));
401
410
415 virtual std::vector<DataBlockPtr> attachPaddingToFunctions(const PartitionerPtr&);
416
429
438
444
451 virtual std::set<Address> attachDeadCodeToFunctions(const PartitionerPtr&, size_t maxIterations=size_t(-1));
452
462 virtual std::vector<DataBlockPtr> attachSurroundedDataToFunctions(const PartitionerPtr&);
463
465 // Partitioner low-level functions
466 //
467 // These are functions that a subclass seldom overrides, and maybe even shouldn't override because of their complexity or
468 // the way the interact with one another.
470public:
481 virtual bool makeNextCallReturnEdge(const PartitionerPtr&, boost::logic::tribool assumeCallReturns);
482
489
505
506
508 // Build AST
510
512 // Settings and properties
514public:
521 BinaryLoaderPtr binaryLoader() const /*final*/;
522 virtual void binaryLoader(const BinaryLoaderPtr&);
550 // Python API support functions
552#ifdef ROSE_ENABLE_PYTHON_API
553
554 // Similar to frontend, but returns a partitioner rather than an AST since the Python API doesn't yet support ASTs.
555 PartitionerPtr pythonParseVector(boost::python::list &pyArgs, const std::string &purpose, const std::string &description);
556 PartitionerPtr pythonParseSingle(const std::string &specimen, const std::string &purpose, const std::string &description);
557
558#endif
559
561 // Internal stuff
563private:
564 struct BinaryPartitionPass {
565 enum class Kind {
566 primary,
567 cilNativeSecondary
568 };
569
570 Kind kind = Kind::primary;
571 std::vector<Address> cilNativeFunctionVas;
572
573 bool isCilNativeSecondary() const {
574 return Kind::cilNativeSecondary == kind;
575 }
576 };
577
578 void init();
579 void runPartitionerWithSavedSettings(const PartitionerPtr&, BinaryPartitionPass&);
580 PartitionerPtr createPartitionerForMap(const Architecture::BaseConstPtr&, const MemoryMapPtr&);
581 AddressIntervalSet cilManagedCodeExclusionIntervals() const;
582 MemoryMapPtr filteredCilNativeMemoryMap(const AddressIntervalSet&, const std::vector<Address>&) const;
583 PartitionerPtr partitionCilNativeFunctions(const std::vector<Address>&);
584 void runPartitionerInit(const PartitionerPtr&, const BinaryPartitionPass&);
585 void runPartitionerRecursive(const PartitionerPtr&, BinaryPartitionPass&);
586 void discoverFunctions(const PartitionerPtr&, const BinaryPartitionPass&);
587
589 // Overrides documented in the base class
591public:
593 bool matchFactory(const Sawyer::CommandLine::ParserResult &result, const std::vector<std::string> &specimen) const override;
595 void reset() override;
596
597 using Engine::frontend;
598 SgAsmBlock* frontend(const std::vector<std::string> &args,
599 const std::string &purpose, const std::string &description) override;
600
602 SgAsmInterpretation* parseContainers(const std::vector<std::string> &fileNames) override;
603
605 MemoryMapPtr loadSpecimens(const std::vector<std::string> &fileNames = std::vector<std::string>()) override;
606
607 using Engine::partition;
608 PartitionerPtr partition(const std::vector<std::string> &fileNames = std::vector<std::string>()) override;
609
610 using Engine::buildAst;
611 SgAsmBlock* buildAst(const std::vector<std::string> &fileNames = std::vector<std::string>()) override;
612
613 std::list<Sawyer::CommandLine::SwitchGroup> commandLineSwitches() override;
614 std::pair<std::string, std::string> specimenNameDocumentation() override;
615 bool isNonContainer(const std::string&) override;
616 bool areContainersParsed() const override;
618 void runPartitioner(const PartitionerPtr&) override;
619 void runPartitionerInit(const PartitionerPtr&) override;
621 void runPartitionerFinal(const PartitionerPtr&) override;
622 SgProject* roseFrontendReplacement(const std::vector<boost::filesystem::path> &fileNames) override;
623};
624
625} // namespace
626} // namespace
627} // namespace
628
629#endif
630#endif
Engine for specimens containing machine instructions.
virtual std::vector< FunctionPtr > makeCalledFunctions(const PartitionerPtr &)
Make functions for function call edges.
void runPartitionerFinal(const PartitionerPtr &) override
Runs the final parts of partitioning.
virtual std::vector< FunctionPtr > makeExportFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions at export addresses.
virtual BasicBlockPtr makeNextBasicBlock(const PartitionerPtr &)
Discover a basic block.
PartitionerPtr createPartitioner() override
Create partitioner.
virtual std::vector< DataBlockPtr > attachPaddingToFunctions(const PartitionerPtr &)
Attach padding to all functions.
static Sawyer::CommandLine::SwitchGroup disassemblerSwitches(DisassemblerSettings &)
Command-line switches related to decoding instructions.
SgAsmBlock * buildAst(const std::vector< std::string > &fileNames=std::vector< std::string >()) override
Obtain an abstract syntax tree.
virtual std::vector< FunctionPtr > makeFunctionFromInterFunctionCalls(const PartitionerPtr &, Address &startVa)
Make functions from inter-function calls.
virtual BinaryLoaderPtr obtainLoader(const BinaryLoaderPtr &hint)
Obtain a binary loader.
virtual std::vector< FunctionPtr > makeImportFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions at import trampolines.
virtual std::vector< DataBlockPtr > attachSurroundedDataToFunctions(const PartitionerPtr &)
Attach intra-function data to functions.
static Sawyer::CommandLine::SwitchGroup engineSwitches(EngineSettings &)
Command-line switches related to the general engine behavior.
virtual BasicBlockPtr makeNextBasicBlockFromPlaceholder(const PartitionerPtr &)
Discover basic block at next placeholder.
virtual std::tuple< bool, std::vector< Address > > partitionCilSections(const PartitionerPtr &)
Partition any sections containing CIL code.
virtual std::vector< FunctionPtr > makeContainerFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions based on specimen container.
virtual void attachBlocksToFunctions(const PartitionerPtr &)
Attach basic blocks to functions.
virtual PartitionerPtr createPartitionerFromAst(SgAsmInterpretation *)
Create a partitioner from an AST.
bool matchFactory(const Sawyer::CommandLine::ParserResult &result, const std::vector< std::string > &specimen) const override
Predicate for matching a concrete engine factory by command-line parser result and specimen.
bool isNonContainer(const std::string &) override
Determine whether a specimen name is a non-container.
virtual FunctionPtr makeNextCodeReferencedFunction(const PartitionerConstPtr &)
Scan instruction ASTs to function pointers.
virtual void discoverFunctions(const PartitionerPtr &)
Discover as many functions as possible.
ThunkPredicatesPtr functionMatcherThunks() const
Property: Predicate for finding functions that are thunks.
virtual std::vector< FunctionPtr > makeSymbolFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions for symbols.
SgAsmBlock * frontend(const std::vector< std::string > &args, const std::string &purpose, const std::string &description) override
Most basic usage of the partitioner.
virtual std::vector< FunctionPtr > makeNextPrologueFunction(const PartitionerPtr &, Address startVa)
Make function at prologue pattern.
void runPartitionerInit(const PartitionerPtr &) override
Finds interesting things to work on initially.
virtual std::set< Address > attachDeadCodeToFunction(const PartitionerPtr &, const FunctionPtr &, size_t maxIterations=size_t(-1))
Attach dead code to function.
virtual size_t attachSurroundedCodeToFunctions(const PartitionerPtr &)
Attach intra-function basic blocks to functions.
virtual std::vector< FunctionPtr > makeEntryFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions at specimen entry addresses.
virtual std::set< Address > attachDeadCodeToFunctions(const PartitionerPtr &, size_t maxIterations=size_t(-1))
Attach dead code to functions.
virtual std::vector< FunctionPtr > makeErrorHandlingFunctions(const PartitionerPtr &, SgAsmInterpretation *)
Make functions at error handling addresses.
bool areContainersParsed() const override
Returns true if containers are parsed.
static Sawyer::CommandLine::SwitchGroup astConstructionSwitches(AstConstructionSettings &)
Command-line switches related to constructing an AST from the partitioner.
virtual std::vector< FunctionPtr > makeCilNativeFunctions(const PartitionerPtr &, const std::vector< Address > &)
Make functions at native MethodDef addresses discovered from CIL metadata.
virtual FunctionPtr makeNextDataReferencedFunction(const PartitionerConstPtr &, Address &startVa)
Scan read-only data to find function pointers.
void reset() override
Reset the engine to its initial state.
virtual DataBlockPtr attachPaddingToFunction(const PartitionerPtr &, const FunctionPtr &)
Attach function padding to function.
MemoryMapPtr loadSpecimens(const std::vector< std::string > &fileNames=std::vector< std::string >()) override
Load and/or link interpretation.
static Sawyer::CommandLine::SwitchGroup partitionerSwitches(PartitionerSettings &)
Command-line switches related to partitioning instructions.
BinaryLoaderPtr binaryLoader() const
Property: binary loader.
virtual std::vector< FunctionPtr > makeNextPrologueFunction(const PartitionerPtr &, Address startVa, Address &lastSearchedVa)
Make function at prologue pattern.
static Ptr factory()
Allocate a factory.
virtual bool makeNextCallReturnEdge(const PartitionerPtr &, boost::logic::tribool assumeCallReturns)
Insert a call-return edge and discover its basic block.
PartitionerPtr partition(const std::vector< std::string > &fileNames=std::vector< std::string >()) override
Partition instructions into basic blocks and functions.
static Sawyer::CommandLine::SwitchGroup loaderSwitches(LoaderSettings &)
Command-line switches related to loading specimen into memory.
EnginePtr instanceFromFactory(const Settings &) override
Virtual constructor for factories.
virtual BinaryLoaderPtr obtainLoader()
Obtain a binary loader.
bool hasCilCodeSection()
Determine whether the interpretation header contains a CIL code section.
virtual std::vector< Address > cilMethodRvasToVas(const std::vector< Address > &) const
Convert and validate CIL method RVAs to virtual addresses.
SgProject * roseFrontendReplacement(const std::vector< boost::filesystem::path > &fileNames) override
Property: classes.
virtual void loadNonContainers(const std::vector< std::string > &names)
Loads memory from non-containers.
virtual PartitionerPtr createTunedPartitioner()
Create a tuned partitioner.
virtual std::vector< FunctionPtr > makeUserFunctions(const PartitionerPtr &, const std::vector< Address > &)
Make a function at each specified address.
std::list< Sawyer::CommandLine::SwitchGroup > commandLineSwitches() override
Command-line switches for a particular engine.
static Ptr instance(const Settings &)
Allocating constructor with settings.
virtual Address cilMethodRvaToVa(Address) const
Convert a CIL method RVA to a virtual address.
void runPartitioner(const PartitionerPtr &) override
Partitions instructions into basic blocks and functions.
ThunkPredicatesPtr functionSplittingThunks() const
Property: Predicate for finding thunks at the start of functions.
static Ptr instance()
Allocating constructor.
std::pair< std::string, std::string > specimenNameDocumentation() override
Documentation about how the specimen is specified.
virtual std::vector< FunctionPtr > makeInterruptVectorFunctions(const PartitionerPtr &, const AddressInterval &vector)
Make functions from an interrupt vector.
SgAsmInterpretation * parseContainers(const std::vector< std::string > &fileNames) override
Parse specimen binary containers.
virtual void loadVxCore(const std::string &spec)
Parses a vxcore specification and initializes memory.
virtual size_t attachAllSurroundedCodeToFunctions(const PartitionerPtr &)
Attach all possible intra-function basic blocks to functions.
virtual void loadContainers(const std::vector< std::string > &fileNames)
Loads memory from binary containers.
virtual void discoverBasicBlocks(const PartitionerPtr &)
Discover as many basic blocks as possible.
void runPartitionerRecursive(const PartitionerPtr &) override
Runs the recursive part of partioning.
Base class for engines driving the partitioner.
const std::vector< std::string > & specimen() const
Property: specimen.
SgAsmBlock * frontend(int argc, char *argv[], const std::string &purpose, const std::string &description)
Most basic usage of the partitioner.
Engine()=delete
Default constructor.
virtual SgAsmBlock * buildAst(const std::vector< std::string > &fileNames=std::vector< std::string >())=0
Obtain an abstract syntax tree.
virtual SgAsmInterpretation * parseContainers(const std::vector< std::string > &fileNames)=0
Parse specimen binary containers.
virtual MemoryMapPtr loadSpecimens(const std::vector< std::string > &fileNames=std::vector< std::string >())=0
Load and/or link interpretation.
virtual PartitionerPtr partition(const std::vector< std::string > &fileNames=std::vector< std::string >())=0
Partition instructions into basic blocks and functions.
The result from parsing a command line.
A collection of related switch declarations.
Reference-counting intrusive smart pointer.
Instruction basic block.
Represents an interpretation of a binary container.
This class represents a source project, with a list of SgFile objects and global information about th...
std::shared_ptr< const Base > BaseConstPtr
Reference counted pointer for Architecture::Base.
Sawyer::SharedPointer< EngineBinary > EngineBinaryPtr
Shared-ownership pointer for EngineBinary.
Sawyer::SharedPointer< Partitioner > PartitionerPtr
Shared-ownership pointer for Partitioner.
Sawyer::Container::IntervalSet< AddressInterval > AddressIntervalSet
A set of virtual addresses.
Sawyer::SharedPointer< MemoryMap > MemoryMapPtr
Reference counting pointer.
std::uint64_t Address
Address.
Definition Address.h:11
The ROSE library.