diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2024-08-22 12:55:49 -0600 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2024-10-21 13:56:55 -0400 |
| commit | d8e3001e535fad178c621ff07418f81f25123dc4 (patch) | |
| tree | 54c03cef2f0bdfd9a3b6df4334c81becb63e4993 /languagerepresentation.cpp | |
| parent | 0e281a30d73c0f31ef9442fef0346779164231ad (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.cpp | 484 |
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; +} |
