ghidra/Ghidra/Features/Decompiler/src/decompile/cpp/ghidra_arch.hh
2019-03-26 13:46:51 -04:00

142 lines
8.3 KiB
C++

/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// \file ghidra_arch.hh
/// \brief Ghidra specific architecture information and connection to a Ghidra client
#ifndef __GHIDRA_ARCH__
#define __GHIDRA_ARCH__
#include "architecture.hh"
/// \brief Exception that mirrors exceptions thrown by the Ghidra client
///
/// If the Ghidra client throws an exception while trying to answer a query,
/// the exception is caught and sent back to the ArchitectureGhidra object
/// in a specially formatted interrupt message. The message is decoded
/// into this object, which is than thrown.
///
/// This class also doubles as an exception generated by the decompiler
/// because of message protocol \e alignment, which should get sent back to the Ghidra client
struct JavaError : public LowlevelError {
string type; ///< The name of the Java exception class
JavaError(const string &tp,const string &message) : LowlevelError(message) {
type = tp; } ///< Construct given a class and message
};
/// \brief An implementation of the Architecture interface and connection to a Ghidra client
///
/// In addition to managing the major pieces of the architecture
/// (LoadImage, Translate, Database, TypeFactory, ContextDatbase, CommentDatabase etc.),
/// this class manages a communication channel between the decompiler and a Ghidra client
/// for a single executable. The protocol supports a simple query/response format with exceptions.
/// On top of the low level protocol, this class manages a higher level interface that performs
/// specific queries, providing addresses, names, and other info as input, and returning
/// an XML document or other structure as a result.
///
/// This class overrides the build* methods to produce Architecture components that are
/// also backed by the Ghidra client. These all use this same object to do their communication.
///
/// This class acts as a main control point for what information gets sent back to the
/// Ghidra client when it requests the main decompilation action.
/// Generally the decompiler sends back the recovered source representation of the function
/// but optionally it can send back:
/// - Recovered source code (with mark up)
/// - Data-flow and control-flow structures
/// - Local symbol and jump-table information
/// - Parameter identification information
class ArchitectureGhidra : public Architecture {
istream &sin; ///< Input stream for interfacing with Ghidra
ostream &sout; ///< Output stream for interfacing with Ghidra
mutable string warnings; ///< Warnings accumulated by the decompiler
string pspecxml; ///< XML pspec passed from Ghidra
string cspecxml; ///< XML cspec passed from Ghidra
string tspecxml; ///< Stripped down .sla file passed from Ghidra
string corespecxml; ///< A specification of the core data-types
bool sendsyntaxtree; ///< True if the syntax tree should be sent with function output
bool sendCcode; ///< True if C code should be sent with function output
bool sendParamMeasures; ///< True if measurements for argument and return parameters should be sent
virtual Scope *buildGlobalScope(void);
virtual Translate *buildTranslator(DocumentStorage &store);
virtual void buildLoader(DocumentStorage &store);
virtual PcodeInjectLibrary *buildPcodeInjectLibrary(void);
virtual void buildTypegrp(DocumentStorage &store);
virtual void buildCommentDB(DocumentStorage &store);
virtual void buildConstantPool(DocumentStorage &store);
virtual void buildContext(DocumentStorage &store);
virtual void buildSpecFile(DocumentStorage &store);
virtual void modifySpaces(Translate *trans) {} // This is handled directly by GhidraTranslate::initialize
virtual void postSpecFile(void);
virtual void resolveArchitecture(void);
public:
ArchitectureGhidra(const string &pspec,const string &cspec,const string &tspec,const string &corespec,istream &i,ostream &o);
const string &getWarnings(void) const { return warnings; } ///< Get warnings produced by the last decompilation
void clearWarnings(void) { warnings.clear(); } ///< Clear warnings
Document *getRegister(const string &regname); ///< Retrieve a register description given a name
string getRegisterName(const VarnodeData &vndata); ///< Retrieve a register name given its storage location
Document *getTrackedRegisters(const Address &addr); ///< Retrieve \e tracked register values at the given address
string getUserOpName(int4 index); ///< Get the name of a user-defined p-code op
uint1 *getPcodePacked(const Address &addr); ///< Get p-code for a single instruction
Document *getMappedSymbolsXML(const Address &addr); ///< Get symbols associated with the given address
Document *getExternalRefXML(const Address &addr); ///< Retrieve a description of an external function
string getCodeLabel(const Address &addr); ///< Retrieve a label at the given address
Document *getType(const string &name,uint8 id); ///< Retrieve a data-type description for the given name and id
Document *getComments(const Address &fad,uint4 flags); ///< Retrieve comments for a particular function
void getBytes(uint1 *buf,int4 size,const Address &inaddr); ///< Retrieve bytes in the LoadImage at the given address
Document *getPcodeInject(const string &name,int4 type,const InjectContext &con);
Document *getCPoolRef(const vector<uintb> &refs); ///< Resolve a constant pool reference
// Document *getScopeProperties(Scope *newscope);
/// \brief Toggle whether the data-flow and control-flow is emitted as part of the main decompile action
///
/// If the toggle is \b on, the decompiler will emit complete descriptions of the graphs.
/// \param val is \b true to enable emitting
void setSendSyntaxTree(bool val) { sendsyntaxtree = val; }
bool getSendSyntaxTree(void) const { return sendsyntaxtree; } ///< Get the current setting for emitting data/control-flow.
/// \brief Toggle whether the recovered source code is emitted as part of the main decompile action
///
/// If the toggle is \b on, the decompiler will emit source code (marked up in an XML document)
/// \param val is \b true to enable emitting
void setSendCCode(bool val) { sendCcode = val; }
bool getSendCCode(void) const { return sendCcode; } ///< Get the current setting for emitting source code
/// \brief Toggle whether recovered parameter information is emitted as part of the main decompile action
///
/// If the toggle is \b on, the decompiler will emit a more detailed description of what
/// it thinks the input parameters to the function are.
/// \param val is \b true enable emitting
void setSendParamMeasures(bool val) { sendParamMeasures = val; }
bool getSendParamMeasures(void) const { return sendParamMeasures; } ///< Get the current setting for emitting parameter info
virtual void printMessage(const string &message) const;
static void segvHandler(int4 sig); ///< Handler for a segment violation (SIGSEGV) signal
static int4 readToAnyBurst(istream &s); ///< Read the next message protocol marker
static void readStringStream(istream &s,string &res); ///< Receive a string from the client
static void writeStringStream(ostream &s,const string &msg); ///< Send a string to the client
static void readToResponse(istream &s); ///< Read the query response protocol marker
static void readResponseEnd(istream &s); ///< Read the ending query response protocol marker
static Document *readXMLAll(istream &s); ///< Read a whole response as an XML document
static Document *readXMLStream(istream &s); ///< Receive an XML document from the client
static uint1 *readPackedStream(istream &s); ///< Read packed p-code op information
static uint1 *readPackedAll(istream &s); ///< Read a whole response as packed p-code op information
static void passJavaException(ostream &s,const string &tp,const string &msg);
};
#endif