#include "binaryninjaapi.h" #include "highlevelilinstruction.h" using namespace BinaryNinja; using namespace std; LanguageRepresentationFunction::LanguageRepresentationFunction(Architecture* arch, Function* func, HighLevelILFunction* highLevelIL) { 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; } vector LanguageRepresentationFunction::GetExprText( const HighLevelILInstruction& instr, DisassemblySettings* settings, BNOperatorPrecedence precedence, bool statement) { size_t count = 0; BNDisassemblyTextLine* lines = BNGetLanguageRepresentationFunctionExprText(m_object, instr.function->GetObject(), instr.exprIndex, settings ? settings->GetObject() : nullptr, instr.ast, precedence, statement, &count); vector 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 LanguageRepresentationFunction::GetLinearLines( const HighLevelILInstruction& instr, DisassemblySettings* settings) { size_t count = 0; BNDisassemblyTextLine* lines = BNGetLanguageRepresentationFunctionLinearLines(m_object, instr.function->GetObject(), instr.exprIndex, settings ? settings->GetObject() : nullptr, instr.ast, &count); vector 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 LanguageRepresentationFunction::GetBlockLines( BasicBlock* block, DisassemblySettings* settings) { size_t count = 0; BNDisassemblyTextLine* lines = BNGetLanguageRepresentationFunctionBlockLines( m_object, block->GetObject(), settings ? settings->GetObject() : nullptr, &count); vector 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 LanguageRepresentationFunction::GetArchitecture() const { return new CoreArchitecture(BNGetLanguageRepresentationArchitecture(m_object)); } Ref LanguageRepresentationFunction::GetFunction() const { return new Function(BNGetLanguageRepresentationOwnerFunction(m_object)); } Ref 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 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 ilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(il)); HighLevelILInstruction instr = ilObj->GetExpr(exprIndex, asFullAst); Ref tokenObj = new HighLevelILTokenEmitter(BNNewHighLevelILTokenEmitterReference(tokens)); Ref settingsObj = settings ? new DisassemblySettings(BNNewDisassemblySettingsReference(settings)) : nullptr; func->GetExprText(instr, *tokenObj, settingsObj, precedence, statement); } void LanguageRepresentationFunction::BeginLinesCallback(void* ctxt, BNHighLevelILFunction* il, size_t exprIndex, BNHighLevelILTokenEmitter* tokens) { LanguageRepresentationFunction* func = (LanguageRepresentationFunction*)ctxt; Ref ilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(il)); HighLevelILInstruction instr = ilObj->GetExpr(exprIndex); Ref 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 ilObj = new HighLevelILFunction(BNNewHighLevelILFunctionReference(il)); HighLevelILInstruction instr = ilObj->GetExpr(exprIndex); Ref 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*, BNOperatorPrecedence, bool) { } 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 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 archObj = new CoreArchitecture(arch); Ref ownerObj = new Function(BNNewFunctionReference(owner)); Ref il = new HighLevelILFunction(BNNewHighLevelILFunctionReference(highLevelIL)); Ref 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 viewObj = new BinaryView(BNNewViewReference(view)); return type->IsValid(viewObj); } BNTypePrinter* LanguageRepresentationFunctionType::GetTypePrinterCallback(void* ctxt) { LanguageRepresentationFunctionType* type = (LanguageRepresentationFunctionType*)ctxt; Ref result = type->GetTypePrinter(); if (!result) return nullptr; return result->GetObject(); } BNTypeParser* LanguageRepresentationFunctionType::GetTypeParserCallback(void* ctxt) { LanguageRepresentationFunctionType* type = (LanguageRepresentationFunctionType*)ctxt; Ref 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 funcObj = new Function(BNNewFunctionReference(func)); Ref 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 count) { for (size_t i = 0; i < count; i++) { InstructionTextToken::FreeInstructionTextTokenList(lines[i].tokens, lines[i].count); Tag::FreeTagList(lines[i].tags, lines[i].tagCount); } delete[] lines; } Ref 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 type = GetByName(name); if (!type) return false; return type->IsValid(view); } vector> LanguageRepresentationFunctionType::GetTypes() { size_t count = 0; BNLanguageRepresentationFunctionType** types = BNGetLanguageRepresentationFunctionTypeList(&count); vector> 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 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 CoreLanguageRepresentationFunctionType::GetTypePrinter() { BNTypePrinter* printer = BNGetLanguageRepresentationFunctionTypePrinter(m_object); if (!printer) return nullptr; return new CoreTypePrinter(printer); } Ref CoreLanguageRepresentationFunctionType::GetTypeParser() { BNTypeParser* parser = BNGetLanguageRepresentationFunctionTypeParser(m_object); if (!parser) return nullptr; return new CoreTypeParser(parser); } vector CoreLanguageRepresentationFunctionType::GetFunctionTypeTokens( Function* func, DisassemblySettings* settings) { size_t count = 0; BNDisassemblyTextLine* lines = BNGetLanguageRepresentationFunctionTypeFunctionTypeTokens(m_object, func->GetObject(), settings ? settings->GetObject() : nullptr, &count); vector 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; }