summaryrefslogtreecommitdiff
path: root/languagerepresentation.cpp
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 /languagerepresentation.cpp
parent0e281a30d73c0f31ef9442fef0346779164231ad (diff)
Allow multiple high level representations for display, add Pseudo Rust and a Pseudo Python example plugin
Diffstat (limited to 'languagerepresentation.cpp')
-rw-r--r--languagerepresentation.cpp484
1 files changed, 481 insertions, 3 deletions
diff --git a/languagerepresentation.cpp b/languagerepresentation.cpp
index 62f592e8..906b4901 100644
--- a/languagerepresentation.cpp
+++ b/languagerepresentation.cpp
@@ -1,15 +1,493 @@
#include "binaryninjaapi.h"
+#include "highlevelilinstruction.h"
using namespace BinaryNinja;
using namespace std;
-LanguageRepresentationFunction::LanguageRepresentationFunction(Architecture* arch, Function* func)
+LanguageRepresentationFunction::LanguageRepresentationFunction(Architecture* arch, Function* func, HighLevelILFunction* highLevelIL)
{
- m_object = BNCreateLanguageRepresentationFunction(arch->GetObject(), func ? func->GetObject() : nullptr);
+ BNCustomLanguageRepresentationFunction callbacks;
+ callbacks.context = this;
+ callbacks.freeObject = FreeCallback;
+ callbacks.externalRefTaken = nullptr;
+ callbacks.externalRefReleased = nullptr;
+ callbacks.initTokenEmitter = InitTokenEmitterCallback;
+ callbacks.getExprText = GetExprTextCallback;
+ callbacks.beginLines = BeginLinesCallback;
+ callbacks.endLines = EndLinesCallback;
+ callbacks.getCommentStartString = GetCommentStartStringCallback;
+ callbacks.getCommentEndString = GetCommentEndStringCallback;
+ callbacks.getAnnotationStartString = GetAnnotationStartStringCallback;
+ callbacks.getAnnotationEndString = GetAnnotationEndStringCallback;
+ AddRefForRegistration();
+ m_object = BNCreateCustomLanguageRepresentationFunction(arch->GetObject(), func->GetObject(),
+ highLevelIL->GetObject(), &callbacks);
}
LanguageRepresentationFunction::LanguageRepresentationFunction(BNLanguageRepresentationFunction* func)
{
m_object = func;
-} \ No newline at end of file
+}
+
+
+vector<DisassemblyTextLine> LanguageRepresentationFunction::GetExprText(const HighLevelILInstruction& instr,
+ DisassemblySettings* settings, bool asFullAst, BNOperatorPrecedence precedence, bool statement)
+{
+ size_t count = 0;
+ BNDisassemblyTextLine* lines = BNGetLanguageRepresentationFunctionExprText(m_object,
+ instr.function->GetObject(), instr.exprIndex, settings ? settings->GetObject() : nullptr,
+ asFullAst, precedence, statement, &count);
+
+ vector<DisassemblyTextLine> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ {
+ DisassemblyTextLine line;
+ line.addr = lines[i].addr;
+ line.instrIndex = lines[i].instrIndex;
+ line.highlight = lines[i].highlight;
+ line.tokens = InstructionTextToken::ConvertInstructionTextTokenList(lines[i].tokens, lines[i].count);
+ line.tags = Tag::ConvertTagList(lines[i].tags, lines[i].tagCount);
+ result.push_back(line);
+ }
+
+ BNFreeDisassemblyTextLines(lines, count);
+ return result;
+}
+
+
+vector<DisassemblyTextLine> LanguageRepresentationFunction::GetLinearLines(
+ const HighLevelILInstruction& instr, DisassemblySettings* settings, bool asFullAst)
+{
+ size_t count = 0;
+ BNDisassemblyTextLine* lines = BNGetLanguageRepresentationFunctionLinearLines(m_object, instr.function->GetObject(),
+ instr.exprIndex, settings ? settings->GetObject() : nullptr, asFullAst, &count);
+
+ vector<DisassemblyTextLine> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ {
+ DisassemblyTextLine line;
+ line.addr = lines[i].addr;
+ line.instrIndex = lines[i].instrIndex;
+ line.highlight = lines[i].highlight;
+ line.tokens = InstructionTextToken::ConvertInstructionTextTokenList(lines[i].tokens, lines[i].count);
+ line.tags = Tag::ConvertTagList(lines[i].tags, lines[i].tagCount);
+ result.push_back(line);
+ }
+
+ BNFreeDisassemblyTextLines(lines, count);
+ return result;
+}
+
+
+vector<DisassemblyTextLine> LanguageRepresentationFunction::GetBlockLines(
+ BasicBlock* block, DisassemblySettings* settings)
+{
+ size_t count = 0;
+ BNDisassemblyTextLine* lines = BNGetLanguageRepresentationFunctionBlockLines(
+ m_object, block->GetObject(), settings ? settings->GetObject() : nullptr, &count);
+
+ vector<DisassemblyTextLine> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ {
+ DisassemblyTextLine line;
+ line.addr = lines[i].addr;
+ line.instrIndex = lines[i].instrIndex;
+ line.highlight = lines[i].highlight;
+ line.tokens = InstructionTextToken::ConvertInstructionTextTokenList(lines[i].tokens, lines[i].count);
+ line.tags = Tag::ConvertTagList(lines[i].tags, lines[i].tagCount);
+ result.push_back(line);
+ }
+
+ BNFreeDisassemblyTextLines(lines, count);
+ return result;
+}
+
+
+BNHighlightColor LanguageRepresentationFunction::GetHighlight(BasicBlock* block)
+{
+ return BNGetLanguageRepresentationFunctionHighlight(m_object, block->GetObject());
+}
+
+
+Ref<Architecture> LanguageRepresentationFunction::GetArchitecture() const
+{
+ return new CoreArchitecture(BNGetLanguageRepresentationArchitecture(m_object));
+}
+
+
+Ref<Function> LanguageRepresentationFunction::GetFunction() const
+{
+ return new Function(BNGetLanguageRepresentationOwnerFunction(m_object));
+}
+
+
+Ref<HighLevelILFunction> LanguageRepresentationFunction::GetHighLevelILFunction() const
+{
+ return new HighLevelILFunction(BNGetLanguageRepresentationILFunction(m_object));
+}
+
+
+void LanguageRepresentationFunction::InitTokenEmitter(HighLevelILTokenEmitter&)
+{
+}
+
+
+void LanguageRepresentationFunction::BeginLines(const HighLevelILInstruction&, HighLevelILTokenEmitter&)
+{
+}
+
+
+void LanguageRepresentationFunction::EndLines(const HighLevelILInstruction&, HighLevelILTokenEmitter&)
+{
+}
+
+
+void LanguageRepresentationFunction::FreeCallback(void* ctxt)
+{
+ LanguageRepresentationFunction* func = (LanguageRepresentationFunction*)ctxt;
+ func->ReleaseForRegistration();
+}
+
+
+void LanguageRepresentationFunction::InitTokenEmitterCallback(void* ctxt, BNHighLevelILTokenEmitter* tokens)
+{
+ LanguageRepresentationFunction* func = (LanguageRepresentationFunction*)ctxt;
+ Ref<HighLevelILTokenEmitter> tokenObj = new HighLevelILTokenEmitter(BNNewHighLevelILTokenEmitterReference(tokens));
+ func->InitTokenEmitter(*tokenObj);
+}
+
+
+void LanguageRepresentationFunction::GetExprTextCallback(void* ctxt, BNHighLevelILFunction* il, size_t exprIndex,
+ BNHighLevelILTokenEmitter* tokens, BNDisassemblySettings* settings, bool asFullAst,
+ BNOperatorPrecedence precedence, bool statement)
+{
+ LanguageRepresentationFunction* func = (LanguageRepresentationFunction*)ctxt;
+ Ref<HighLevelILFunction> ilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(il));
+ HighLevelILInstruction instr = ilObj->GetExpr(exprIndex);
+ Ref<HighLevelILTokenEmitter> tokenObj = new HighLevelILTokenEmitter(BNNewHighLevelILTokenEmitterReference(tokens));
+ Ref<DisassemblySettings> settingsObj = settings ? new DisassemblySettings(BNNewDisassemblySettingsReference(settings)) : nullptr;
+ func->GetExprText(instr, *tokenObj, settingsObj, asFullAst, precedence, statement);
+}
+
+
+void LanguageRepresentationFunction::BeginLinesCallback(void* ctxt, BNHighLevelILFunction* il, size_t exprIndex,
+ BNHighLevelILTokenEmitter* tokens)
+{
+ LanguageRepresentationFunction* func = (LanguageRepresentationFunction*)ctxt;
+ Ref<HighLevelILFunction> ilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(il));
+ HighLevelILInstruction instr = ilObj->GetExpr(exprIndex);
+ Ref<HighLevelILTokenEmitter> tokenObj = new HighLevelILTokenEmitter(BNNewHighLevelILTokenEmitterReference(tokens));
+ func->BeginLines(instr, *tokenObj);
+}
+
+
+void LanguageRepresentationFunction::EndLinesCallback(void* ctxt, BNHighLevelILFunction* il, size_t exprIndex,
+ BNHighLevelILTokenEmitter* tokens)
+{
+ LanguageRepresentationFunction* func = (LanguageRepresentationFunction*)ctxt;
+ Ref<HighLevelILFunction> ilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(il));
+ HighLevelILInstruction instr = ilObj->GetExpr(exprIndex);
+ Ref<HighLevelILTokenEmitter> tokenObj = new HighLevelILTokenEmitter(BNNewHighLevelILTokenEmitterReference(tokens));
+ func->EndLines(instr, *tokenObj);
+}
+
+
+char* LanguageRepresentationFunction::GetCommentStartStringCallback(void* ctxt)
+{
+ LanguageRepresentationFunction* func = (LanguageRepresentationFunction*)ctxt;
+ return BNAllocString(func->GetCommentStartString().c_str());
+}
+
+
+char* LanguageRepresentationFunction::GetCommentEndStringCallback(void* ctxt)
+{
+ LanguageRepresentationFunction* func = (LanguageRepresentationFunction*)ctxt;
+ return BNAllocString(func->GetCommentEndString().c_str());
+}
+
+
+char* LanguageRepresentationFunction::GetAnnotationStartStringCallback(void* ctxt)
+{
+ LanguageRepresentationFunction* func = (LanguageRepresentationFunction*)ctxt;
+ return BNAllocString(func->GetAnnotationStartString().c_str());
+}
+
+
+char* LanguageRepresentationFunction::GetAnnotationEndStringCallback(void* ctxt)
+{
+ LanguageRepresentationFunction* func = (LanguageRepresentationFunction*)ctxt;
+ return BNAllocString(func->GetAnnotationEndString().c_str());
+}
+
+
+CoreLanguageRepresentationFunction::CoreLanguageRepresentationFunction(BNLanguageRepresentationFunction* func):
+ LanguageRepresentationFunction(func)
+{
+}
+
+
+void CoreLanguageRepresentationFunction::GetExprText(const HighLevelILInstruction&, HighLevelILTokenEmitter&,
+ DisassemblySettings*, bool, BNOperatorPrecedence, bool statement)
+{
+}
+
+
+string CoreLanguageRepresentationFunction::GetCommentStartString() const
+{
+ char* result = BNGetLanguageRepresentationFunctionCommentStartString(m_object);
+ string resultStr(result);
+ BNFreeString(result);
+ return resultStr;
+}
+
+
+string CoreLanguageRepresentationFunction::GetCommentEndString() const
+{
+ char* result = BNGetLanguageRepresentationFunctionCommentEndString(m_object);
+ string resultStr(result);
+ BNFreeString(result);
+ return resultStr;
+}
+
+
+string CoreLanguageRepresentationFunction::GetAnnotationStartString() const
+{
+ char* result = BNGetLanguageRepresentationFunctionAnnotationStartString(m_object);
+ string resultStr(result);
+ BNFreeString(result);
+ return resultStr;
+}
+
+
+string CoreLanguageRepresentationFunction::GetAnnotationEndString() const
+{
+ char* result = BNGetLanguageRepresentationFunctionAnnotationEndString(m_object);
+ string resultStr(result);
+ BNFreeString(result);
+ return resultStr;
+}
+
+
+LanguageRepresentationFunctionType::LanguageRepresentationFunctionType(const std::string& name): m_nameForRegister(name)
+{
+ m_object = nullptr;
+}
+
+
+LanguageRepresentationFunctionType::LanguageRepresentationFunctionType(BNLanguageRepresentationFunctionType* type)
+{
+ m_object = type;
+}
+
+
+string LanguageRepresentationFunctionType::GetName() const
+{
+ char* name = BNGetLanguageRepresentationFunctionTypeName(m_object);
+ string result = name;
+ BNFreeString(name);
+ return result;
+}
+
+
+bool LanguageRepresentationFunctionType::IsValid(BinaryView*)
+{
+ return true;
+}
+
+
+vector<DisassemblyTextLine> LanguageRepresentationFunctionType::GetFunctionTypeTokens(Function*, DisassemblySettings*)
+{
+ return {};
+}
+
+
+void LanguageRepresentationFunctionType::Register(LanguageRepresentationFunctionType* type)
+{
+ BNCustomLanguageRepresentationFunctionType callbacks;
+ callbacks.context = type;
+ callbacks.create = CreateCallback;
+ callbacks.isValid = IsValidCallback;
+ callbacks.getTypePrinter = GetTypePrinterCallback;
+ callbacks.getTypeParser = GetTypeParserCallback;
+ callbacks.getFunctionTypeTokens = GetFunctionTypeTokensCallback;
+ callbacks.freeLines = FreeLinesCallback;
+
+ type->AddRefForRegistration();
+ type->m_object =
+ BNRegisterLanguageRepresentationFunctionType(type->m_nameForRegister.c_str(), &callbacks);
+}
+
+
+BNLanguageRepresentationFunction* LanguageRepresentationFunctionType::CreateCallback(
+ void* ctxt, BNArchitecture* arch, BNFunction* owner, BNHighLevelILFunction* highLevelIL)
+{
+ LanguageRepresentationFunctionType* type = (LanguageRepresentationFunctionType*)ctxt;
+ Ref<Architecture> archObj = new CoreArchitecture(arch);
+ Ref<Function> ownerObj = new Function(BNNewFunctionReference(owner));
+ Ref<HighLevelILFunction> il = new HighLevelILFunction(BNNewHighLevelILFunctionReference(highLevelIL));
+ Ref<LanguageRepresentationFunction> result = type->Create(archObj, ownerObj, il);
+ if (!result)
+ return nullptr;
+ return BNNewLanguageRepresentationFunctionReference(result->GetObject());
+}
+
+
+bool LanguageRepresentationFunctionType::IsValidCallback(void* ctxt, BNBinaryView* view)
+{
+ LanguageRepresentationFunctionType* type = (LanguageRepresentationFunctionType*)ctxt;
+ Ref<BinaryView> viewObj = new BinaryView(BNNewViewReference(view));
+ return type->IsValid(viewObj);
+}
+
+
+BNTypePrinter* LanguageRepresentationFunctionType::GetTypePrinterCallback(void* ctxt)
+{
+ LanguageRepresentationFunctionType* type = (LanguageRepresentationFunctionType*)ctxt;
+ Ref<TypePrinter> result = type->GetTypePrinter();
+ if (!result)
+ return nullptr;
+ return result->GetObject();
+}
+
+
+BNTypeParser* LanguageRepresentationFunctionType::GetTypeParserCallback(void* ctxt)
+{
+ LanguageRepresentationFunctionType* type = (LanguageRepresentationFunctionType*)ctxt;
+ Ref<TypeParser> result = type->GetTypeParser();
+ if (!result)
+ return nullptr;
+ return result->GetObject();
+}
+
+
+BNDisassemblyTextLine* LanguageRepresentationFunctionType::GetFunctionTypeTokensCallback(
+ void* ctxt, BNFunction* func, BNDisassemblySettings* settings, size_t* count)
+{
+ LanguageRepresentationFunctionType* type = (LanguageRepresentationFunctionType*)ctxt;
+ Ref<Function> funcObj = new Function(BNNewFunctionReference(func));
+ Ref<DisassemblySettings> settingsObj = settings ? new DisassemblySettings(BNNewDisassemblySettingsReference(settings)) : nullptr;
+ auto lines = type->GetFunctionTypeTokens(funcObj, settingsObj);
+ *count = lines.size();
+ BNDisassemblyTextLine* buf = new BNDisassemblyTextLine[lines.size()];
+ for (size_t i = 0; i < lines.size(); i++)
+ {
+ const DisassemblyTextLine& line = lines[i];
+ buf[i].addr = line.addr;
+ buf[i].instrIndex = line.instrIndex;
+ buf[i].highlight = line.highlight;
+ buf[i].tokens = InstructionTextToken::CreateInstructionTextTokenList(line.tokens);
+ buf[i].count = line.tokens.size();
+ buf[i].tags = Tag::CreateTagList(line.tags, &(buf[i].tagCount));
+ }
+
+ return buf;
+}
+
+
+void LanguageRepresentationFunctionType::FreeLinesCallback(void*, BNDisassemblyTextLine* lines, size_t)
+{
+ delete[] lines;
+}
+
+
+Ref<LanguageRepresentationFunctionType> LanguageRepresentationFunctionType::GetByName(const std::string& name)
+{
+ BNLanguageRepresentationFunctionType* type = BNGetLanguageRepresentationFunctionTypeByName(name.c_str());
+ if (!type)
+ return nullptr;
+ return new CoreLanguageRepresentationFunctionType(type);
+}
+
+
+bool LanguageRepresentationFunctionType::IsValidByName(const std::string& name, BinaryView* view)
+{
+ Ref<LanguageRepresentationFunctionType> type = GetByName(name);
+ if (!type)
+ return false;
+ return type->IsValid(view);
+}
+
+
+vector<Ref<LanguageRepresentationFunctionType>> LanguageRepresentationFunctionType::GetTypes()
+{
+ size_t count = 0;
+ BNLanguageRepresentationFunctionType** types = BNGetLanguageRepresentationFunctionTypeList(&count);
+
+ vector<Ref<LanguageRepresentationFunctionType>> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ result.push_back(new CoreLanguageRepresentationFunctionType(types[i]));
+
+ BNFreeLanguageRepresentationFunctionTypeList(types);
+ return result;
+}
+
+
+CoreLanguageRepresentationFunctionType::CoreLanguageRepresentationFunctionType(BNLanguageRepresentationFunctionType* type):
+ LanguageRepresentationFunctionType(type)
+{
+}
+
+
+Ref<LanguageRepresentationFunction> CoreLanguageRepresentationFunctionType::Create(
+ Architecture* arch, Function* owner, HighLevelILFunction* highLevelIL)
+{
+ BNLanguageRepresentationFunction* func = BNCreateLanguageRepresentationFunction(
+ m_object, arch->GetObject(), owner->GetObject(), highLevelIL->GetObject());
+ if (!func)
+ return nullptr;
+ return new CoreLanguageRepresentationFunction(func);
+}
+
+
+bool CoreLanguageRepresentationFunctionType::IsValid(BinaryView* view)
+{
+ return BNIsLanguageRepresentationFunctionTypeValid(m_object, view->GetObject());
+}
+
+
+Ref<TypePrinter> CoreLanguageRepresentationFunctionType::GetTypePrinter()
+{
+ BNTypePrinter* printer = BNGetLanguageRepresentationFunctionTypePrinter(m_object);
+ if (!printer)
+ return nullptr;
+ return new CoreTypePrinter(printer);
+}
+
+
+Ref<TypeParser> CoreLanguageRepresentationFunctionType::GetTypeParser()
+{
+ BNTypeParser* parser = BNGetLanguageRepresentationFunctionTypeParser(m_object);
+ if (!parser)
+ return nullptr;
+ return new CoreTypeParser(parser);
+}
+
+
+vector<DisassemblyTextLine> CoreLanguageRepresentationFunctionType::GetFunctionTypeTokens(
+ Function* func, DisassemblySettings* settings)
+{
+ size_t count = 0;
+ BNDisassemblyTextLine* lines = BNGetLanguageRepresentationFunctionTypeFunctionTypeTokens(m_object,
+ func->GetObject(), settings ? settings->GetObject() : nullptr, &count);
+
+ vector<DisassemblyTextLine> result;
+ result.reserve(count);
+ for (size_t i = 0; i < count; i++)
+ {
+ DisassemblyTextLine line;
+ line.addr = lines[i].addr;
+ line.instrIndex = lines[i].instrIndex;
+ line.highlight = lines[i].highlight;
+ line.tokens = InstructionTextToken::ConvertInstructionTextTokenList(lines[i].tokens, lines[i].count);
+ line.tags = Tag::ConvertTagList(lines[i].tags, lines[i].tagCount);
+ result.push_back(line);
+ }
+
+ BNFreeDisassemblyTextLines(lines, count);
+ return result;
+}