#include "binaryninjaapi.h"
#include "ffi.h"
#include "highlevelilinstruction.h"
using namespace BinaryNinja;
using namespace std;
LanguageRepresentationFunction::LanguageRepresentationFunction(
LanguageRepresentationFunctionType* type, 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(
type->GetObject(), 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 = ParseAPIObjectList(lines, count);
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 = ParseAPIObjectList(lines, count);
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 = ParseAPIObjectList(lines, count);
BNFreeDisassemblyTextLines(lines, count);
return result;
}
BNHighlightColor LanguageRepresentationFunction::GetHighlight(BasicBlock* block)
{
return BNGetLanguageRepresentationFunctionHighlight(m_object, block->GetObject());
}
Ref LanguageRepresentationFunction::GetLanguage() const
{
return new CoreLanguageRepresentationFunctionType(BNGetLanguageRepresentationType(m_object));
}
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.getLineFormatter = GetLineFormatterCallback;
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();
}
BNLineFormatter* LanguageRepresentationFunctionType::GetLineFormatterCallback(void* ctxt)
{
LanguageRepresentationFunctionType* type = (LanguageRepresentationFunctionType*)ctxt;
Ref result = type->GetLineFormatter();
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);
return AllocAPIObjectList(lines, count);
}
void LanguageRepresentationFunctionType::FreeLinesCallback(void*, BNDisassemblyTextLine* lines, size_t count)
{
FreeAPIObjectList(lines, count);
}
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);
}
Ref CoreLanguageRepresentationFunctionType::GetLineFormatter()
{
BNLineFormatter* formatter = BNGetLanguageRepresentationFunctionTypeLineFormatter(m_object);
if (!formatter)
return nullptr;
return new CoreLineFormatter(formatter);
}
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 = ParseAPIObjectList(lines, count);
BNFreeDisassemblyTextLines(lines, count);
return result;
}
]