From ded6f3551d8c8635fe011e295b73a44263ca91af Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Fri, 13 Dec 2019 09:47:32 -0500 Subject: Fix for issue with custom display types --- binaryninjaapi.h | 4 ++-- binaryninjacore.h | 8 ++++---- datarenderer.cpp | 20 ++++++++++---------- python/datarender.py | 26 +++++++++++++++++++++----- 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 00b7d719..4d9ca8e5 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -4714,9 +4714,9 @@ __attribute__ ((format (printf, 1, 2))) class DataRenderer: public CoreRefCountObject { static bool IsValidForDataCallback(void* ctxt, BNBinaryView* data, uint64_t addr, BNType* type, - BNTypeContext** typeCtx, size_t ctxCount); + 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, + const BNInstructionTextToken* prefix, size_t prefixCount, size_t width, size_t* count, BNTypeContext* typeCxt, size_t ctxCount); static void FreeCallback(void* ctxt); public: diff --git a/binaryninjacore.h b/binaryninjacore.h index e1aa78e4..b584f0da 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -1919,10 +1919,10 @@ extern "C" { void* context; void (*freeObject)(void* ctxt); - bool (*isValidForData)(void* ctxt, BNBinaryView* view, uint64_t addr, BNType* type, BNTypeContext** typeCtx, + bool (*isValidForData)(void* ctxt, BNBinaryView* view, uint64_t addr, BNType* type, BNTypeContext* typeCtx, size_t ctxCount); BNDisassemblyTextLine* (*getLinesForData)(void* ctxt, BNBinaryView* view, uint64_t addr, BNType* type, - const BNInstructionTextToken* prefix, size_t prefixCount, size_t width, size_t* count, BNTypeContext** typeCtx, + const BNInstructionTextToken* prefix, size_t prefixCount, size_t width, size_t* count, BNTypeContext* typeCtx, size_t ctxCount); }; @@ -4197,10 +4197,10 @@ __attribute__ ((format (printf, 1, 2))) BINARYNINJACOREAPI BNDataRenderer* BNCreateDataRenderer(BNCustomDataRenderer* renderer); BINARYNINJACOREAPI BNDataRenderer* BNNewDataRendererReference(BNDataRenderer* renderer); BINARYNINJACOREAPI bool BNIsValidForData(void* ctxt, BNBinaryView* view, uint64_t addr, BNType* type, - BNTypeContext** typeCtx, size_t ctxCount); + BNTypeContext* typeCtx, size_t ctxCount); BINARYNINJACOREAPI BNDisassemblyTextLine* BNGetLinesForData(void* ctxt, BNBinaryView* view, uint64_t addr, BNType* type, const BNInstructionTextToken* prefix, size_t prefixCount, size_t width, size_t* count, - BNTypeContext** typeCtx, size_t ctxCount); + BNTypeContext* typeCtx, size_t ctxCount); BINARYNINJACOREAPI void BNFreeDataRenderer(BNDataRenderer* renderer); BINARYNINJACOREAPI BNDataRendererContainer* BNGetDataRendererContainer(); BINARYNINJACOREAPI void BNRegisterGenericDataRenderer(BNDataRendererContainer* container, BNDataRenderer* renderer); diff --git a/datarenderer.cpp b/datarenderer.cpp index 3d892987..18cc8d31 100644 --- a/datarenderer.cpp +++ b/datarenderer.cpp @@ -38,7 +38,7 @@ bool DataRenderer::IsStructOfTypeName(Type* type, const string& name, vector viewObj = new BinaryView(BNNewViewReference(view)); @@ -46,14 +46,14 @@ bool DataRenderer::IsValidForDataCallback(void* ctxt, BNBinaryView* view, uint64 vector> context; context.reserve(ctxCount); for (size_t i = 0; i < ctxCount; i++) - context.push_back({new Type(BNNewTypeReference(typeCtx[i]->type)), typeCtx[i]->offset}); + context.push_back({new Type(BNNewTypeReference(typeCtx[i].type)), typeCtx[i].offset}); return renderer->IsValidForData(viewObj, addr, typeObj, context); } BNDisassemblyTextLine* DataRenderer::GetLinesForDataCallback(void* ctxt, BNBinaryView* view, uint64_t addr, BNType* type, - const BNInstructionTextToken* prefix, size_t prefixCount, size_t width, size_t* count, BNTypeContext** typeCtx, + const BNInstructionTextToken* prefix, size_t prefixCount, size_t width, size_t* count, BNTypeContext* typeCtx, size_t ctxCount) { DataRenderer* renderer = (DataRenderer*)ctxt; @@ -64,7 +64,7 @@ BNDisassemblyTextLine* DataRenderer::GetLinesForDataCallback(void* ctxt, BNBinar vector> context; context.reserve(ctxCount); for (size_t i = 0; i < ctxCount; i++) - context.push_back({new Type(BNNewTypeReference(typeCtx[i]->type)), typeCtx[i]->offset}); + context.push_back({new Type(BNNewTypeReference(typeCtx[i].type)), typeCtx[i].offset}); auto lines = renderer->GetLinesForData(viewObj, addr, typeObj, prefixes, width, context); *count = lines.size(); BNDisassemblyTextLine* buf = new BNDisassemblyTextLine[lines.size()]; @@ -91,11 +91,11 @@ void DataRenderer::FreeCallback(void* ctxt) bool DataRenderer::IsValidForData(BinaryView* data, uint64_t addr, Type* type, vector>& context) { - BNTypeContext** typeCtx = new BNTypeContext*[context.size()]; + BNTypeContext* typeCtx = new BNTypeContext[context.size()]; for (size_t i = 0; i < context.size(); i++) { - typeCtx[i]->type = context[i].first->GetObject(); - typeCtx[i]->offset = context[i].second; + typeCtx[i].type = context[i].first->GetObject(); + typeCtx[i].offset = context[i].second; } bool result = BNIsValidForData(m_object, data->GetObject(), addr, type->GetObject(), typeCtx, context.size()); delete[] typeCtx; @@ -107,11 +107,11 @@ vector DataRenderer::GetLinesForData(BinaryView* data, uint const std::vector& prefix, size_t width, vector>& context) { BNInstructionTextToken* prefixes = InstructionTextToken::CreateInstructionTextTokenList(prefix); - BNTypeContext** typeCtx = new BNTypeContext*[context.size()]; + BNTypeContext* typeCtx = new BNTypeContext[context.size()]; for (size_t i = 0; i < context.size(); i++) { - typeCtx[i]->type = context[i].first->GetObject(); - typeCtx[i]->offset = context[i].second; + typeCtx[i].type = context[i].first->GetObject(); + typeCtx[i].offset = context[i].second; } size_t count = 0; BNDisassemblyTextLine* lines = BNGetLinesForData(m_object, data->GetObject(), addr, type->GetObject(), prefixes, diff --git a/python/datarender.py b/python/datarender.py index 4b81b1dd..52591ebc 100644 --- a/python/datarender.py +++ b/python/datarender.py @@ -32,6 +32,22 @@ from binaryninja import log from binaryninja import types from binaryninja import highlight + +class TypeContext(object): + def __init__(self, _type, _offset): + self._type = _type + self._offset = _offset + + @property + def type(self): + """The Type object for the current context record""" + return self._type + + @property + def offset(self): + """The offset into the given type object""" + return self._offset + class DataRenderer(object): """ DataRenderer objects tell the Linear View how to render specific types. @@ -61,7 +77,7 @@ class DataRenderer(object): return [DisassemblyTextLine(prefix, addr)] def __del__(self): pass - + BarDataRenderer().register_type_specific() Note that the formatting is sub-optimal to work around an issue with Sphinx and reStructured text @@ -79,8 +95,8 @@ class DataRenderer(object): @classmethod def is_type_of_struct_name(cls, type, name, context): return (type.type_class == enums.TypeClass.StructureTypeClass and len(context) > 0 - and context[-1].type_class == enums.TypeClass.NamedTypeReferenceClass and - context[-1].named_type_reference.name == name) + and context[-1].type.type_class == enums.TypeClass.NamedTypeReferenceClass and + context[-1].type.named_type_reference.name == name) def register_type_specific(self): core.BNRegisterTypeSpecificDataRenderer(core.BNGetDataRendererContainer(), self.handle) @@ -103,7 +119,7 @@ class DataRenderer(object): type = types.Type(handle=core.BNNewTypeReference(type)) pycontext = [] for i in range(0, ctxCount): - pycontext.append(types.Type(core.BNNewTypeReference(context[i]))) + pycontext.append(TypeContext(types.Type(core.BNNewTypeReference(context[i].type)), context[i].offset)) return self.perform_is_valid_for_data(ctxt, view, addr, type, pycontext) except: log.log_error(traceback.format_exc()) @@ -118,7 +134,7 @@ class DataRenderer(object): prefixTokens = function.InstructionTextToken.get_instruction_lines(prefix, prefixCount) pycontext = [] for i in range(ctxCount): - pycontext.append(types.Type(core.BNNewTypeReference(typeCtx[i]))) + pycontext.append(TypeContext(types.Type(core.BNNewTypeReference(typeCtx[i].type)), typeCtx[i].offset)) result = self.perform_get_lines_for_data(ctxt, view, addr, type, prefixTokens, width, pycontext) -- cgit v1.3.1