summaryrefslogtreecommitdiff
path: root/binaryninjaapi.h
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2024-08-22 12:55:49 -0600
committerRusty Wagner <rusty.wagner@gmail.com>2024-10-21 13:56:55 -0400
commitd8e3001e535fad178c621ff07418f81f25123dc4 (patch)
tree54c03cef2f0bdfd9a3b6df4334c81becb63e4993 /binaryninjaapi.h
parent0e281a30d73c0f31ef9442fef0346779164231ad (diff)
Allow multiple high level representations for display, add Pseudo Rust and a Pseudo Python example plugin
Diffstat (limited to 'binaryninjaapi.h')
-rw-r--r--binaryninjaapi.h541
1 files changed, 517 insertions, 24 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 0223757c..01f5ba11 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -2169,16 +2169,17 @@ namespace BinaryNinja {
/*! Convert the contents of the DataBuffer to a string
- \param nullTerminates Whether the decoder should stop and return the string after encountering a null (\x00) byte.
+ \param nullTerminates Whether the decoder should stop and return the string after encountering a null (\x00)
+ byte.
- @threadunsafe
+ @threadunsafe
*/
- std::string ToEscapedString(bool nullTerminates = false) const;
+ std::string ToEscapedString(bool nullTerminates = false, bool escapePrintable = false) const;
/*! Create a DataBuffer from a given escaped string.
- \param src Input string
- \returns Databuffer created from this string
+ \param src Input string
+ \returns Databuffer created from this string
*/
static DataBuffer FromEscapedString(const std::string& src);
@@ -2397,7 +2398,9 @@ namespace BinaryNinja {
InstructionTextToken(const BNInstructionTextToken& token);
InstructionTextToken WithConfidence(uint8_t conf);
+ static void ConvertInstructionTextToken(const InstructionTextToken& token, BNInstructionTextToken* result);
static BNInstructionTextToken* CreateInstructionTextTokenList(const std::vector<InstructionTextToken>& tokens);
+ static void FreeInstructionTextToken(BNInstructionTextToken* token);
static void FreeInstructionTextTokenList(
BNInstructionTextToken* tokens, size_t count);
static std::vector<InstructionTextToken> ConvertAndFreeInstructionTextTokenList(
@@ -3956,6 +3959,29 @@ namespace BinaryNinja {
static Ref<Symbol> ImportedFunctionFromImportAddressSymbol(Symbol* sym, uint64_t addr);
};
+ struct FunctionViewType
+ {
+ BNFunctionGraphType type;
+ std::string name;
+
+ FunctionViewType() : type(NormalFunctionGraph) {}
+ FunctionViewType(BNFunctionGraphType viewType);
+ FunctionViewType(const std::string& langName) :
+ type(HighLevelLanguageRepresentationFunctionGraph), name(langName)
+ {}
+ FunctionViewType(const BNFunctionViewType& viewType);
+
+ BNFunctionViewType ToAPIObject() const;
+
+ BNFunctionGraphType GetBackingILType() const;
+
+ bool IsValidForView(BinaryView* view) const;
+
+ bool operator==(const FunctionViewType& other) const;
+ bool operator!=(const FunctionViewType& other) const;
+ bool operator<(const FunctionViewType& other) const;
+ };
+
// TODO: This describes how the xref source references the target
enum ReferenceType
{
@@ -6363,29 +6389,29 @@ namespace BinaryNinja {
bool FindNextData(
uint64_t start, const DataBuffer& data, uint64_t& result, BNFindFlag flags = FindCaseSensitive);
bool FindNextText(uint64_t start, const std::string& data, uint64_t& result, Ref<DisassemblySettings> settings,
- BNFindFlag flags = FindCaseSensitive, BNFunctionGraphType graph = NormalFunctionGraph);
+ BNFindFlag flags = FindCaseSensitive, const FunctionViewType& viewType = NormalFunctionGraph);
bool FindNextConstant(uint64_t start, uint64_t constant, uint64_t& result, Ref<DisassemblySettings> settings,
- BNFunctionGraphType graph = NormalFunctionGraph);
+ const FunctionViewType& viewType = NormalFunctionGraph);
bool FindNextData(uint64_t start, uint64_t end, const DataBuffer& data, uint64_t& addr, BNFindFlag flags,
const std::function<bool(size_t current, size_t total)>& progress);
bool FindNextText(uint64_t start, uint64_t end, const std::string& data, uint64_t& addr,
- Ref<DisassemblySettings> settings, BNFindFlag flags, BNFunctionGraphType graph,
+ Ref<DisassemblySettings> settings, BNFindFlag flags, const FunctionViewType& viewType,
const std::function<bool(size_t current, size_t total)>& progress);
bool FindNextConstant(uint64_t start, uint64_t end, uint64_t constant, uint64_t& addr,
- Ref<DisassemblySettings> settings, BNFunctionGraphType graph,
+ Ref<DisassemblySettings> settings, const FunctionViewType& viewType,
const std::function<bool(size_t current, size_t total)>& progress);
bool FindAllData(uint64_t start, uint64_t end, const DataBuffer& data, BNFindFlag flags,
const std::function<bool(size_t current, size_t total)>& progress,
const std::function<bool(uint64_t addr, const DataBuffer& match)>& matchCallback);
bool FindAllText(uint64_t start, uint64_t end, const std::string& data, Ref<DisassemblySettings> settings,
- BNFindFlag flags, BNFunctionGraphType graph,
+ BNFindFlag flags, const FunctionViewType& viewType,
const std::function<bool(size_t current, size_t total)>& progress,
const std::function<bool(uint64_t addr, const std::string& match, const LinearDisassemblyLine& line)>&
matchCallback);
bool FindAllConstant(uint64_t start, uint64_t end, uint64_t constant, Ref<DisassemblySettings> settings,
- BNFunctionGraphType graph, const std::function<bool(size_t current, size_t total)>& progress,
+ const FunctionViewType& viewType, const std::function<bool(size_t current, size_t total)>& progress,
const std::function<bool(uint64_t addr, const LinearDisassemblyLine& line)>& matchCallback);
bool Search(const std::string& query, const std::function<bool(uint64_t offset, const DataBuffer& buffer)>& otherCallback);
@@ -6819,6 +6845,9 @@ namespace BinaryNinja {
bool UserGlobalPointerValueSet() const;
void ClearUserGlobalPointerValue();
void SetUserGlobalPointerValue(const Confidence<RegisterValue>& value);
+
+ std::optional<std::pair<std::string, BNStringType>> StringifyUnicodeData(
+ Architecture* arch, const DataBuffer& buffer, bool allowShortStrings = false);
};
class MemoryMap
@@ -8801,8 +8830,11 @@ namespace BinaryNinja {
Confidence<int64_t> GetStackAdjustment() const;
QualifiedName GetStructureName() const;
Ref<NamedTypeReference> GetRegisteredName() const;
+ std::string GetAlternateName() const;
uint32_t GetSystemCallNumber() const;
BNIntegerDisplayType GetIntegerTypeDisplayType() const;
+ BNNameType GetNameType() const;
+ bool ShouldDisplayReturnType() const;
uint64_t GetElementCount() const;
uint64_t GetOffset() const;
@@ -9500,6 +9532,11 @@ namespace BinaryNinja {
Ref<Structure> WithReplacedStructure(Structure* from, Structure* to);
Ref<Structure> WithReplacedEnumeration(Enumeration* from, Enumeration* to);
Ref<Structure> WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTypeReference* to);
+
+ bool ResolveMemberOrBaseMember(BinaryView* data, uint64_t offset, size_t size,
+ const std::function<void(NamedTypeReference* baseName, Structure* s, size_t memberIndex,
+ uint64_t structOffset, uint64_t adjustedOffset, const StructureMember& member)>& resolveFunc,
+ std::optional<size_t> memberIndexHint = std::nullopt);
};
/*! StructureBuilder is a convenience class used for building Structure Types.
@@ -10419,7 +10456,7 @@ namespace BinaryNinja {
ConstantData(BNRegisterValueType state, uint64_t value);
ConstantData(BNRegisterValueType state, uint64_t value, size_t size, Ref<Function> func = nullptr);
- DataBuffer ToDataBuffer() const;
+ std::pair<DataBuffer, BNBuiltinType> ToDataBuffer() const;
RegisterValue ToRegisterValue() const;
};
@@ -10675,7 +10712,8 @@ namespace BinaryNinja {
std::set<size_t> GetLowLevelILInstructionsForAddress(Architecture* arch, uint64_t addr);
std::vector<size_t> GetLowLevelILExitsForInstruction(Architecture* arch, uint64_t addr);
- DataBuffer GetConstantData(BNRegisterValueType state, uint64_t value, size_t size = 0);
+ std::pair<DataBuffer, BNBuiltinType> GetConstantData(
+ BNRegisterValueType state, uint64_t value, size_t size = 0);
RegisterValue GetRegisterValueAtInstruction(Architecture* arch, uint64_t addr, uint32_t reg);
RegisterValue GetRegisterValueAfterInstruction(Architecture* arch, uint64_t addr, uint32_t reg);
@@ -10765,8 +10803,9 @@ namespace BinaryNinja {
\return The HLIL for this Function if it's available.
*/
Ref<HighLevelILFunction> GetHighLevelILIfAvailable() const;
- Ref<LanguageRepresentationFunction> GetLanguageRepresentation() const;
- Ref<LanguageRepresentationFunction> GetLanguageRepresentationIfAvailable() const;
+ Ref<LanguageRepresentationFunction> GetLanguageRepresentation(const std::string& language = "Pseudo C") const;
+ Ref<LanguageRepresentationFunction> GetLanguageRepresentationIfAvailable(
+ const std::string& language = "Pseudo C") const;
Ref<Type> GetType() const;
Confidence<Ref<Type>> GetReturnType() const;
@@ -10807,7 +10846,7 @@ namespace BinaryNinja {
void ApplyImportedTypes(Symbol* sym, Ref<Type> type = nullptr);
void ApplyAutoDiscoveredType(Type* type);
- Ref<FlowGraph> CreateFunctionGraph(BNFunctionGraphType type, DisassemblySettings* settings = nullptr);
+ Ref<FlowGraph> CreateFunctionGraph(const FunctionViewType& type, DisassemblySettings* settings = nullptr);
std::map<int64_t, std::vector<VariableNameAndType>> GetStackLayout();
void CreateAutoStackVariable(int64_t offset, const Confidence<Ref<Type>>& type, const std::string& name);
@@ -13280,6 +13319,7 @@ namespace BinaryNinja {
};
struct HighLevelILInstruction;
+ class HighLevelILTokenEmitter;
/*!
\ingroup highlevelil
@@ -13512,6 +13552,8 @@ namespace BinaryNinja {
bool IsSSAVarLive(const SSAVariable& var) const;
bool IsSSAVarLiveAt(const SSAVariable& var, const size_t instr) const;
bool IsVarLiveAt(const Variable& var, const size_t instr) const;
+ static bool HasSideEffects(const HighLevelILInstruction& instr);
+ static BNScopeType GetExprScopeType(const HighLevelILInstruction& instr);
std::set<size_t> GetVariableSSAVersions(const Variable& var) const;
std::set<size_t> GetVariableDefinitions(const Variable& var) const;
@@ -13559,15 +13601,254 @@ namespace BinaryNinja {
size_t GetExprIndexForLabel(uint64_t label);
std::set<size_t> GetUsesForLabel(uint64_t label);
+
+ std::set<Variable> GetVariables();
+ std::set<Variable> GetAliasedVariables();
+ std::set<SSAVariable> GetSSAVariables();
};
+ /*! LanguageRepresentationFunction represents a single function in a registered high level language.
+
+ \ingroup highlevelil
+ */
class LanguageRepresentationFunction :
public CoreRefCountObject<BNLanguageRepresentationFunction, BNNewLanguageRepresentationFunctionReference,
BNFreeLanguageRepresentationFunction>
{
- public:
- LanguageRepresentationFunction(Architecture* arch, Function* func = nullptr);
+ public:
+ LanguageRepresentationFunction(Architecture* arch, Function* func, HighLevelILFunction* highLevelIL);
LanguageRepresentationFunction(BNLanguageRepresentationFunction* func);
+
+ /*! Gets the lines of tokens for a given High Level IL instruction.
+
+ \param instr The instruction to emit lines for.
+ \param settings The settings for disassembly (optional).
+ \param asFullAst Whether to emit full AST or single expressions.
+ \param precedence The current operator precedence level.
+ \param statement Whether the instruction is a statement or an expression.
+ \return A list of lines of tokens for the instruction.
+ */
+ std::vector<DisassemblyTextLine> GetExprText(const HighLevelILInstruction& instr, DisassemblySettings* settings,
+ bool asFullAst = true, BNOperatorPrecedence precedence = TopLevelOperatorPrecedence,
+ bool statement = false);
+
+ /*! Generates lines for the given High Level IL instruction in the style of the linear view. To get the lines
+ for the entire function, pass the root instruction of a HighLevelILFunction.
+
+ \param instr The instruction to emit lines for.
+ \param settings The settings for disassembly (optional).
+ \param asFullAst Whether to emit full AST or single expressions.
+ \return A list of lines of tokens for the instruction.
+ */
+ std::vector<DisassemblyTextLine> GetLinearLines(
+ const HighLevelILInstruction& instr, DisassemblySettings* settings, bool asFullAst = true);
+
+ /*! Generates lines for a single High Level IL basic block.
+
+ \param block The basic block to emit lines for.
+ \param settings The settings for disassembly (optional).
+ \return A list of lines of tokens for the basic block.
+ */
+ std::vector<DisassemblyTextLine> GetBlockLines(BasicBlock* block, DisassemblySettings* settings);
+
+ /*! Gets the highlight color for a given basic block.
+
+ \param block The basic block to get the highlight color for.
+ \return The highlight color for the basic block.
+ */
+ BNHighlightColor GetHighlight(BasicBlock* block);
+
+ Ref<Architecture> GetArchitecture() const;
+ Ref<Function> GetFunction() const;
+ Ref<HighLevelILFunction> GetHighLevelILFunction() const;
+
+ /*! Gets the string representing the start of a comment.
+
+ \return The string representing the start of a comment.
+ */
+ virtual std::string GetCommentStartString() const { return "// "; }
+
+ /*! Gets the string representing the end of a comment.
+
+ \return The string representing the end of a comment.
+ */
+ virtual std::string GetCommentEndString() const { return ""; }
+
+ /*! Gets the string representing the start of an annotation.
+
+ \return The string representing the start of an annotation.
+ */
+ virtual std::string GetAnnotationStartString() const { return "{"; }
+
+ /*! Gets the string representing the end of an annotation.
+
+ \return The string representing the end of an annotation.
+ */
+ virtual std::string GetAnnotationEndString() const { return "}"; }
+
+ protected:
+ /*! Override this method to initialize the options for the token emitter before it is used.
+
+ \param tokens The token emitter to initialize.
+ */
+ virtual void InitTokenEmitter(HighLevelILTokenEmitter& tokens);
+
+ /*! This method must be overridden by all language representation plugins.
+
+ This method is called to emit the tokens for a given High Level IL instruction.
+
+ \param instr The instruction to emit tokens for.
+ \param tokens The token emitter to use.
+ \param settings The disassembly settings to use (may be NULL).
+ \param asFullAst Whether to emit full AST or single expressions.
+ \param precedence The current operator precedence level.
+ \param statement Whether the instruction is a statement or an expression.
+ */
+ virtual void GetExprText(const HighLevelILInstruction& instr, HighLevelILTokenEmitter& tokens,
+ DisassemblySettings* settings, bool asFullAst = true,
+ BNOperatorPrecedence precedence = TopLevelOperatorPrecedence, bool statement = false) = 0;
+
+ /*! This method can be overridden to emit tokens at the start of a function.
+
+ \param instr The root instruction of the function.
+ \param tokens The token emitter to use.
+ */
+ virtual void BeginLines(const HighLevelILInstruction& instr, HighLevelILTokenEmitter& tokens);
+
+ /*! This method can be overridden to emit tokens at the end of a function.
+
+ \param instr The root instruction of the function.
+ \param tokens The token emitter to use.
+ */
+ virtual void EndLines(const HighLevelILInstruction& instr, HighLevelILTokenEmitter& tokens);
+
+ private:
+ static void FreeCallback(void* ctxt);
+ static void InitTokenEmitterCallback(void* ctxt, BNHighLevelILTokenEmitter* tokens);
+ static void GetExprTextCallback(void* ctxt, BNHighLevelILFunction* il, size_t exprIndex,
+ BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings, bool asFullAst,
+ BNOperatorPrecedence precedence, bool statement);
+ static void BeginLinesCallback(
+ void* ctxt, BNHighLevelILFunction* il, size_t exprIndex, BNHighLevelILTokenEmitter* tokens);
+ static void EndLinesCallback(
+ void* ctxt, BNHighLevelILFunction* il, size_t exprIndex, BNHighLevelILTokenEmitter* tokens);
+ static char* GetCommentStartStringCallback(void* ctxt);
+ static char* GetCommentEndStringCallback(void* ctxt);
+ static char* GetAnnotationStartStringCallback(void* ctxt);
+ static char* GetAnnotationEndStringCallback(void* ctxt);
+ };
+
+ /*!
+ \ingroup highlevelil
+ */
+ class CoreLanguageRepresentationFunction : public LanguageRepresentationFunction
+ {
+ public:
+ CoreLanguageRepresentationFunction(BNLanguageRepresentationFunction* func);
+ std::string GetCommentStartString() const override;
+ std::string GetCommentEndString() const override;
+ std::string GetAnnotationStartString() const override;
+ std::string GetAnnotationEndString() const override;
+
+ protected:
+ void GetExprText(const HighLevelILInstruction& instr, HighLevelILTokenEmitter& tokens,
+ DisassemblySettings* settings, bool asFullAst = true,
+ BNOperatorPrecedence precedence = TopLevelOperatorPrecedence, bool statement = false) override;
+ };
+
+ class TypePrinter;
+ class TypeParser;
+
+ /*! LanguageRepresentationFunctionType represents a custom language representation function type.
+ This class provides methods to create LanguageRepresentationFunction instances for functions, as well
+ as manage the printing and parsing of types.
+
+ \ingroup highlevelil
+ */
+ class LanguageRepresentationFunctionType : public StaticCoreRefCountObject<BNLanguageRepresentationFunctionType>
+ {
+ std::string m_nameForRegister;
+
+ public:
+ LanguageRepresentationFunctionType(const std::string& name);
+ LanguageRepresentationFunctionType(BNLanguageRepresentationFunctionType* type);
+
+ std::string GetName() const;
+
+ /*! This method must be overridden. This creates the LanguageRepresentationFunction object for the
+ given architecture, owner function, and High Level IL function.
+
+ \param arch The architecture of the function.
+ \param owner The associated function.
+ \param highLevelIL The High Level IL for the function.
+ \return A LanguageRepresentationFunction instance for the given function.
+ */
+ virtual Ref<LanguageRepresentationFunction> Create(
+ Architecture* arch, Function* owner, HighLevelILFunction* highLevelIL) = 0;
+
+ /*! Returns whether the language is valid for the given binary view.
+
+ \param view The binary view to check the validity for.
+ \return True if the language is valid for the given binary view, false otherwise.
+ */
+ virtual bool IsValid(BinaryView* view);
+
+ /*! Returns the type printer for displaying types in this language. If NULL is returned, the default type
+ printer will be used.
+
+ \return The optional type printer for displaying types in this language.
+ */
+ virtual Ref<TypePrinter> GetTypePrinter() { return nullptr; }
+
+ /*! Returns the type parser for parsing types in this language. If NULL is returned, the default type
+ parser will be used.
+
+ \return The optional type parser for parsing types in this language.
+ */
+ virtual Ref<TypeParser> GetTypeParser() { return nullptr; }
+
+ /*! Returns a list of lines representing a function prototype in this language. If no lines are returned, the
+ default C-style prototype will be used.
+
+ \param func The function to get the prototype lines for.
+ \param settings The disassembly settings to use (may be NULL).
+ \return An optional vector of lines representing the function prototype.
+ */
+ virtual std::vector<DisassemblyTextLine> GetFunctionTypeTokens(
+ Function* func, DisassemblySettings* settings = nullptr);
+
+ /*! Registers the language representation function type.
+
+ \param type The language representation function type to register.
+ */
+ static void Register(LanguageRepresentationFunctionType* type);
+
+ static Ref<LanguageRepresentationFunctionType> GetByName(const std::string& name);
+ static bool IsValidByName(const std::string& name, BinaryView* view);
+ static std::vector<Ref<LanguageRepresentationFunctionType>> GetTypes();
+
+ private:
+ static BNLanguageRepresentationFunction* CreateCallback(
+ void* ctxt, BNArchitecture* arch, BNFunction* owner, BNHighLevelILFunction* highLevelIL);
+ static bool IsValidCallback(void* ctxt, BNBinaryView* view);
+ static BNTypePrinter* GetTypePrinterCallback(void* ctxt);
+ static BNTypeParser* GetTypeParserCallback(void* ctxt);
+ static BNDisassemblyTextLine* GetFunctionTypeTokensCallback(
+ void* ctxt, BNFunction* func, BNDisassemblySettings* settings, size_t* count);
+ static void FreeLinesCallback(void* ctxt, BNDisassemblyTextLine* lines, size_t count);
+ };
+
+ class CoreLanguageRepresentationFunctionType : public LanguageRepresentationFunctionType
+ {
+ public:
+ CoreLanguageRepresentationFunctionType(BNLanguageRepresentationFunctionType* type);
+ Ref<LanguageRepresentationFunction> Create(
+ Architecture* arch, Function* owner, HighLevelILFunction* highLevelIL) override;
+ bool IsValid(BinaryView* view) override;
+ Ref<TypePrinter> GetTypePrinter() override;
+ Ref<TypeParser> GetTypeParser() override;
+ std::vector<DisassemblyTextLine> GetFunctionTypeTokens(
+ Function* func, DisassemblySettings* settings = nullptr) override;
};
/*!
@@ -16431,7 +16712,7 @@ namespace BinaryNinja {
void* ctxt, BNBinaryView* data, uint64_t addr, BNType* type, BNTypeContext* typeCtx, size_t ctxCount);
static BNDisassemblyTextLine* GetLinesForDataCallback(void* ctxt, BNBinaryView* data, uint64_t addr,
BNType* type, const BNInstructionTextToken* prefix, size_t prefixCount, size_t width, size_t* count,
- BNTypeContext* typeCxt, size_t ctxCount);
+ BNTypeContext* typeCxt, size_t ctxCount, const char* language);
static void FreeCallback(void* ctxt);
static void FreeLinesCallback(void* ctxt, BNDisassemblyTextLine* lines, size_t count);
@@ -16442,10 +16723,10 @@ namespace BinaryNinja {
BinaryView* data, uint64_t addr, Type* type, std::vector<std::pair<Type*, size_t>>& context);
virtual std::vector<DisassemblyTextLine> GetLinesForData(BinaryView* data, uint64_t addr, Type* type,
const std::vector<InstructionTextToken>& prefix, size_t width,
- std::vector<std::pair<Type*, size_t>>& context);
+ std::vector<std::pair<Type*, size_t>>& context, const std::string& language = std::string());
std::vector<DisassemblyTextLine> RenderLinesForData(BinaryView* data, uint64_t addr, Type* type,
const std::vector<InstructionTextToken>& prefix, size_t width,
- std::vector<std::pair<Type*, size_t>>& context);
+ std::vector<std::pair<Type*, size_t>>& context, const std::string& language = std::string());
static bool IsStructOfTypeName(
Type* type, const QualifiedName& name, std::vector<std::pair<Type*, size_t>>& context);
@@ -16505,6 +16786,12 @@ namespace BinaryNinja {
void ResetDeduplicatedComments();
bool AddSymbolToken(std::vector<InstructionTextToken>& tokens, uint64_t addr, size_t size, size_t operand);
+ static BNSymbolDisplayResult AddSymbolTokenStatic(
+ std::vector<InstructionTextToken>& tokens, uint64_t addr, size_t size, size_t operand,
+ BinaryView* data, size_t maxSymbolWidth, Function* func, uint8_t confidence = BN_FULL_CONFIDENCE,
+ BNSymbolDisplayType symbolDisplay = DisplaySymbolOnly,
+ BNOperatorPrecedence precedence = TopLevelOperatorPrecedence,
+ uint64_t instrAddr = -1, uint64_t exprIndex = -1);
void AddStackVariableReferenceTokens(
std::vector<InstructionTextToken>& tokens, const StackVariableReference& ref);
@@ -16516,6 +16803,7 @@ namespace BinaryNinja {
bool hasAutoAnnotations, const std::string& leadingSpaces = " ", const std::string& indentSpaces = "");
static std::string GetDisplayStringForInteger(Ref<BinaryView> binaryView, BNIntegerDisplayType type,
uint64_t value, size_t inputWidth, bool isSigned = true);
+ static std::string GetStringLiteralPrefix(BNStringType type);
};
/*!
@@ -16573,7 +16861,8 @@ namespace BinaryNinja {
static Ref<LinearViewObject> CreateMappedMediumLevelILSSAForm(BinaryView* view, DisassemblySettings* settings);
static Ref<LinearViewObject> CreateHighLevelIL(BinaryView* view, DisassemblySettings* settings);
static Ref<LinearViewObject> CreateHighLevelILSSAForm(BinaryView* view, DisassemblySettings* settings);
- static Ref<LinearViewObject> CreateLanguageRepresentation(BinaryView* view, DisassemblySettings* settings);
+ static Ref<LinearViewObject> CreateLanguageRepresentation(BinaryView* view, DisassemblySettings* settings,
+ const std::string& language = "Pseudo C");
static Ref<LinearViewObject> CreateDataOnly(BinaryView* view, DisassemblySettings* settings);
static Ref<LinearViewObject> CreateSingleFunctionDisassembly(Function* func, DisassemblySettings* settings);
@@ -16592,7 +16881,7 @@ namespace BinaryNinja {
static Ref<LinearViewObject> CreateSingleFunctionHighLevelILSSAForm(
Function* func, DisassemblySettings* settings);
static Ref<LinearViewObject> CreateSingleFunctionLanguageRepresentation(
- Function* func, DisassemblySettings* settings);
+ Function* func, DisassemblySettings* settings, const std::string& language = "Pseudo C");
};
/*!
@@ -16669,7 +16958,7 @@ namespace BinaryNinja {
{
BNFindType type;
BNFindRangeType rangeType;
- BNFunctionGraphType ilType;
+ FunctionViewType ilType;
std::string string;
BNFindFlag flags;
bool findAll;
@@ -18106,6 +18395,210 @@ namespace BinaryNinja {
const size_t dataLen
);
} // namespace Unicode
+
+ /*! HighLevelILTokenEmitter contains methods for emitting text tokens for High Level IL instructions.
+ Methods are provided for typical patterns found in various high level languages.
+
+ This class cannot be instantiated directly. An instance of the class will be provided when the methods
+ in LanguageRepresentationFunction are called.
+
+ \ingroup highlevelil
+ */
+ class HighLevelILTokenEmitter:
+ public CoreRefCountObject<BNHighLevelILTokenEmitter, BNNewHighLevelILTokenEmitterReference, BNFreeHighLevelILTokenEmitter>
+ {
+ public:
+ HighLevelILTokenEmitter(BNHighLevelILTokenEmitter* emitter);
+
+ class CurrentExprGuard
+ {
+ HighLevelILTokenEmitter* m_parent;
+ BNTokenEmitterExpr m_expr;
+
+ CurrentExprGuard(const CurrentExprGuard&) = delete;
+ CurrentExprGuard& operator=(const CurrentExprGuard&) = delete;
+
+ public:
+ CurrentExprGuard(HighLevelILTokenEmitter& parent, const BNTokenEmitterExpr& expr);
+ ~CurrentExprGuard();
+ };
+
+ /*! Appends a token to the output. */
+ template <typename... Args>
+ void Append(Args&&... args)
+ {
+ InstructionTextToken token(std::forward<Args>(args)...);
+ BNInstructionTextToken converted;
+ InstructionTextToken::ConvertInstructionTextToken(token, &converted);
+ BNHighLevelILTokenEmitterAppend(m_object, &converted);
+ InstructionTextToken::FreeInstructionTextToken(&converted);
+ }
+
+ /*! Starts a new line in the output. */
+ void NewLine();
+
+ /*! Increases the indentation level by one. */
+ void IncreaseIndent();
+
+ /*! Decreases the indentation level by one. */
+ void DecreaseIndent();
+
+ /*! Indicates that visual separation of scopes is desirable at the current position. By default,
+ this will insert a blank line, but this can be configured by the user.
+ */
+ void ScopeSeparator();
+
+ /*! Begins a new scope. Insertion of newlines and braces will be handled using the current settings.
+
+ \param scopeType Type of scope to be started.
+ */
+ void BeginScope(BNScopeType scopeType);
+
+ /*! Ends the current scope.
+
+ \param scopeType Type of scope passed to BeginScope.
+ */
+ void EndScope(BNScopeType scopeType);
+
+ /*! Continues the previous scope with a new associated scope. This is most commonly used for else statements.
+
+ \param forceSameLine If true, the continuation will always be placed on the same line as the previous scope.
+ */
+ void ScopeContinuation(bool forceSameLine);
+
+ /*! Finalizes the previous scope, indicating that there are no more associated scopes. */
+ void FinalizeScope();
+
+ /*! Forces there to be no indentation for the next line. */
+ void NoIndentForThisLine();
+
+ /*! Begins a region of tokens that always have zero confidence. */
+ void BeginForceZeroConfidence();
+
+ /*! Ends a region of tokens that always have zero confidence. */
+ void EndForceZeroConfidence();
+
+ /*! Sets the current expression. When the returned guard object goes out of scope, the previously set
+ expression becomes active again.
+
+ \param expr Expression to set as the current expression.
+ \return Guard object to manage the current expression.
+ */
+ CurrentExprGuard SetCurrentExpr(const HighLevelILInstruction& expr);
+
+ /*! Finalizes the outputted lines. */
+ void Finalize();
+
+ void AppendOpenParen(); // (
+ void AppendCloseParen(); // )
+ void AppendOpenBracket(); // [
+ void AppendCloseBracket(); // ]
+ void AppendOpenBrace(); // {
+ void AppendCloseBrace(); // }
+ void AppendSemicolon();
+
+ /*! Returns the list of tokens on the current line */
+ std::vector<InstructionTextToken> GetCurrentTokens() const;
+
+ /*! Sets the requirement for insertion of braces around scopes in the output. */
+ void SetBraceRequirement(BNBraceRequirement required);
+
+ /*! Sets whether cases within switch statements should always have braces around them. */
+ void SetBracesAroundSwitchCases(bool braces);
+
+ /*! Sets whether braces should default to being on the same line as the statement that begins the scope.
+ If the user has explicitly set a preference, this setting will be ignored and the user's preference
+ will be used instead.
+ */
+ void SetDefaultBracesOnSameLine(bool sameLine);
+
+ /*! Sets whether omitting braces around single-line scopes is allowed. */
+ void SetSimpleScopeAllowed(bool allowed);
+
+ BNBraceRequirement GetBraceRequirement() const;
+ bool HasBracesAroundSwitchCases() const;
+ bool GetDefaultBracesOnSameLine() const;
+ bool IsSimpleScopeAllowed() const;
+
+ /*! Gets the list of lines in the output. */
+ std::vector<DisassemblyTextLine> GetLines() const;
+
+ /*! Appends a size token for the given size in the High Level IL syntax.
+
+ \param size Size in bytes.
+ \param type Token type to append.
+ */
+ void AppendSizeToken(size_t size, BNInstructionTextTokenType type);
+
+ /*! Appends a floating point size token for the given size in the High Level IL syntax.
+
+ \param size Size in bytes.
+ \param type Token type to append.
+ */
+ void AppendFloatSizeToken(size_t size, BNInstructionTextTokenType type);
+
+ /*! Appends tokens for access to a variable.
+
+ \param var Variable to access.
+ \param instr Instruction that accesses the variable.
+ \param size Size in bytes.
+ */
+ void AppendVarTextToken(const Variable& var, const HighLevelILInstruction& instr, size_t size);
+
+ /*! Appends tokens for a constant intenger value.
+
+ \param instr Instruction that references the value.
+ \param val Integer value.
+ \param size Size in bytes.
+ */
+ void AppendIntegerTextToken(const HighLevelILInstruction& instr, int64_t val, size_t size);
+
+ /*! Appends tokens for accessing an array by constant index.
+
+ \param instr Instruction that accesses the array.
+ \param val Index value.
+ \param size Size in bytes.
+ \param address Optional address override.
+ */
+ void AppendArrayIndexToken(const HighLevelILInstruction& instr, int64_t val, size_t size, uint64_t address = 0);
+
+ /*! Appends tokens for displaying a constant pointer value.
+
+ \param instr Instruction that references the pointer.
+ \param val Pointer value.
+ \param settings Settings for disassembly (may be NULL).
+ \param symbolDisplay Symbol display type.
+ \param precedence Current operator precedence level.
+ \param allowShortString If true, show as a string even if it is short.
+ \return Type of symbol resolved if any.
+ */
+ BNSymbolDisplayResult AppendPointerTextToken(const HighLevelILInstruction& instr, int64_t val,
+ DisassemblySettings* settings, BNSymbolDisplayType symbolDisplay, BNOperatorPrecedence precedence,
+ bool allowShortString = false);
+
+ /*! Appends tokens for a constant value.
+
+ \param instr Instruction that references the value.
+ \param val Constant value.
+ \param size Size in bytes.
+ \param settings Settings for disassembly (may be NULL).
+ \param precedence Current operator precedence level.
+ */
+ void AppendConstantTextToken(const HighLevelILInstruction& instr, int64_t val, size_t size,
+ DisassemblySettings* settings, BNOperatorPrecedence precedence);
+
+ /*! Prepends the list of names for the outer structure members when accessing a structure member. This list
+ can be passed as the list of type names in tokens.
+
+ \param data Binary view associated with the type.
+ \param type Structure Type being accessed.
+ \param var Structure variable.
+ \param nameList Existing list of member names. This list will be updated with the outer structure member
+ names.
+ */
+ static void AddNamesForOuterStructureMembers(
+ BinaryView* data, Type* type, const HighLevelILInstruction& var, std::vector<std::string>& nameList);
+ };
} // namespace BinaryNinja