diff options
| author | Rusty Wagner <rusty@vector35.com> | 2019-02-22 15:36:40 -0500 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2019-02-22 15:41:02 -0500 |
| commit | 2f84b5c600f08101a6a7ee08738a3e3a32686f46 (patch) | |
| tree | 909537511998daa9796737e4cd287b89488761f7 | |
| parent | e7228de8fe2640f126a01064a8485c1270846bd1 (diff) | |
Add API for constructing disassembly text
| -rw-r--r-- | architecture.cpp | 264 | ||||
| -rw-r--r-- | binaryninjaapi.h | 46 | ||||
| -rw-r--r-- | binaryninjacore.h | 38 | ||||
| -rw-r--r-- | python/flowgraph.py | 2 | ||||
| -rw-r--r-- | python/function.py | 192 |
5 files changed, 533 insertions, 9 deletions
diff --git a/architecture.cpp b/architecture.cpp index b07f5a38..65593e94 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -68,6 +68,16 @@ InstructionTextToken::InstructionTextToken(BNInstructionTextTokenType t, BNInstr } +InstructionTextToken::InstructionTextToken(const BNInstructionTextToken& token): + type(token.type), text(token.text), value(token.value), size(token.size), operand(token.operand), + context(token.context), confidence(token.confidence), address(token.address) +{ + typeNames.reserve(token.namesCount); + for (size_t j = 0; j < token.namesCount; j++) + typeNames.push_back(token.typeNames[j]); +} + + InstructionTextToken InstructionTextToken::WithConfidence(uint8_t conf) { return InstructionTextToken(type, context, text, address, value, size, operand, conf, typeNames); @@ -113,14 +123,7 @@ vector<InstructionTextToken> InstructionTextToken::ConvertInstructionTextTokenLi vector<InstructionTextToken> result; result.reserve(count); for (size_t i = 0; i < count; i++) - { - vector<string> names; - names.reserve(tokens[i].namesCount); - for (size_t j = 0; j < tokens[i].namesCount; j++) - names.push_back(tokens[i].typeNames[j]); - result.emplace_back(tokens[i].type, tokens[i].context, tokens[i].text, tokens[i].address, tokens[i].value, tokens[i].size, - tokens[i].operand, tokens[i].confidence, names); - } + result.emplace_back(tokens[i]); return result; } @@ -2137,3 +2140,248 @@ void ArchitectureHook::Register(BNCustomArchitecture* callbacks) AddRefForRegistration(); m_object = BNRegisterArchitectureHook(m_base->GetObject(), callbacks); } + + +DisassemblyTextRenderer::DisassemblyTextRenderer(Function* func, DisassemblySettings* settings) +{ + m_object = BNCreateDisassemblyTextRenderer(func->GetObject(), settings ? settings->GetObject() : nullptr); +} + + +DisassemblyTextRenderer::DisassemblyTextRenderer(LowLevelILFunction* func, DisassemblySettings* settings) +{ + m_object = BNCreateLowLevelILDisassemblyTextRenderer(func->GetObject(), settings ? settings->GetObject() : nullptr); +} + + +DisassemblyTextRenderer::DisassemblyTextRenderer(MediumLevelILFunction* func, DisassemblySettings* settings) +{ + m_object = BNCreateMediumLevelILDisassemblyTextRenderer(func->GetObject(), settings ? settings->GetObject() : nullptr); +} + + +DisassemblyTextRenderer::DisassemblyTextRenderer(BNDisassemblyTextRenderer* renderer) +{ + m_object = renderer; +} + + +Ref<BasicBlock> DisassemblyTextRenderer::GetBasicBlock() const +{ + BNBasicBlock* block = BNGetDisassemblyTextRendererBasicBlock(m_object); + if (block) + return new BasicBlock(block); + return nullptr; +} + + +Ref<Architecture> DisassemblyTextRenderer::GetArchitecture() const +{ + return new CoreArchitecture(BNGetDisassemblyTextRendererArchitecture(m_object)); +} + + +Ref<DisassemblySettings> DisassemblyTextRenderer::GetSettings() const +{ + return new DisassemblySettings(BNGetDisassemblyTextRendererSettings(m_object)); +} + + +Ref<Function> DisassemblyTextRenderer::GetFunction() const +{ + return new Function(BNGetDisassemblyTextRendererFunction(m_object)); +} + + +Ref<LowLevelILFunction> DisassemblyTextRenderer::GetLowLevelILFunction() const +{ + BNLowLevelILFunction* result = BNGetDisassemblyTextRendererLowLevelILFunction(m_object); + if (result) + return new LowLevelILFunction(result); + return nullptr; +} + + +Ref<MediumLevelILFunction> DisassemblyTextRenderer::GetMediumLevelILFunction() const +{ + BNMediumLevelILFunction* result = BNGetDisassemblyTextRendererMediumLevelILFunction(m_object); + if (result) + return new MediumLevelILFunction(result); + return nullptr; +} + + +void DisassemblyTextRenderer::SetBasicBlock(BasicBlock* block) +{ + BNSetDisassemblyTextRendererBasicBlock(m_object, block ? block->GetObject() : nullptr); +} + + +void DisassemblyTextRenderer::SetArchitecture(Architecture* arch) +{ + BNSetDisassemblyTextRendererArchitecture(m_object, arch->GetObject()); +} + + +void DisassemblyTextRenderer::SetSettings(DisassemblySettings* settings) +{ + BNSetDisassemblyTextRendererSettings(m_object, settings ? settings->GetObject() : nullptr); +} + + +bool DisassemblyTextRenderer::IsIL() const +{ + return BNIsILDisassemblyTextRenderer(m_object); +} + + +bool DisassemblyTextRenderer::HasDataFlow() const +{ + return BNDisassmblyTextRendererHasDataFlow(m_object); +} + + +void DisassemblyTextRenderer::GetInstructionAnnotations(vector<InstructionTextToken>& tokens, uint64_t addr) +{ + size_t count = 0; + BNInstructionTextToken* result = BNGetDisassemblyTextRendererInstructionAnnotations(m_object, addr, &count); + vector<InstructionTextToken> newTokens; + newTokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(result, count); + tokens.insert(tokens.end(), newTokens.begin(), newTokens.end()); +} + + +bool DisassemblyTextRenderer::GetInstructionText(uint64_t addr, size_t& len, + vector<InstructionTextToken>& tokens, uint64_t& displayAddr) +{ + BNInstructionTextToken* outTokens = nullptr; + size_t count = 0; + if (!BNGetDisassemblyTextRendererInstructionText(m_object, addr, &len, &outTokens, &count, &displayAddr)) + return false; + tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(outTokens, count); + return true; +} + + +bool DisassemblyTextRenderer::GetDisassemblyText(uint64_t addr, size_t& len, vector<DisassemblyTextLine>& lines) +{ + BNDisassemblyTextLine* result = nullptr; + size_t count = 0; + if (!BNGetDisassemblyTextRendererLines(m_object, addr, &len, &result, &count)) + return false; + + for (size_t i = 0; i < count; i++) + { + DisassemblyTextLine line; + line.addr = result[i].addr; + line.instrIndex = result[i].instrIndex; + line.highlight = result[i].highlight; + line.tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(result[i].tokens, result[i].count); + lines.push_back(line); + } + + BNFreeDisassemblyTextLines(result, count); + return true; +} + + +void DisassemblyTextRenderer::ResetDeduplicatedComments() +{ + BNResetDisassemblyTextRendererDeduplicatedComments(m_object); +} + + +bool DisassemblyTextRenderer::AddSymbolToken(vector<InstructionTextToken>& tokens, uint64_t addr, size_t size, size_t operand) +{ + BNInstructionTextToken* result = nullptr; + size_t count = 0; + if (!BNGetDisassemblyTextRendererSymbolTokens(m_object, addr, size, operand, &result, &count)) + return false; + vector<InstructionTextToken> newTokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(result, count); + tokens.insert(tokens.end(), newTokens.begin(), newTokens.end()); + return true; +} + + +void DisassemblyTextRenderer::AddStackVariableReferenceTokens(vector<InstructionTextToken>& tokens, + const StackVariableReference& ref) +{ + BNStackVariableReference stackRef; + stackRef.sourceOperand = ref.sourceOperand; + stackRef.type = ref.type.GetValue() ? ref.type->GetObject() : nullptr; + stackRef.typeConfidence = ref.type.GetConfidence(); + stackRef.name = BNAllocString(ref.name.c_str()); + stackRef.varIdentifier = ref.var.ToIdentifier(); + stackRef.referencedOffset = ref.referencedOffset; + stackRef.size = ref.size; + + size_t count = 0; + BNInstructionTextToken* result = BNGetDisassemblyTextRendererStackVariableReferenceTokens( + m_object, &stackRef, &count); + BNFreeString(stackRef.name); + + vector<InstructionTextToken> newTokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(result, count); + tokens.insert(tokens.end(), newTokens.begin(), newTokens.end()); +} + + +bool DisassemblyTextRenderer::IsIntegerToken(BNInstructionTextTokenType type) +{ + return BNIsIntegerToken(type); +} + + +void DisassemblyTextRenderer::AddIntegerToken(vector<InstructionTextToken>& tokens, const InstructionTextToken& token, + Architecture* arch, uint64_t addr) +{ + BNInstructionTextToken inToken; + ConvertInstructionTextToken(token, &inToken); + + size_t count = 0; + BNInstructionTextToken* result = BNGetDisassemblyTextRendererIntegerTokens(m_object, &inToken, + arch ? arch->GetObject() : nullptr, addr, &count); + + vector<InstructionTextToken> newTokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(result, count); + tokens.insert(tokens.end(), newTokens.begin(), newTokens.end()); + + BNFreeString(inToken.text); + for (size_t i = 0; i < inToken.namesCount; i++) + BNFreeString(inToken.typeNames[i]); + delete[] inToken.typeNames; +} + + +void DisassemblyTextRenderer::WrapComment(DisassemblyTextLine& line, vector<DisassemblyTextLine>& lines, + const string& comment, bool hasAutoAnnotations, const string& leadingSpaces) +{ + BNDisassemblyTextLine inLine; + inLine.addr = line.addr; + inLine.instrIndex = line.instrIndex; + inLine.highlight = line.highlight; + inLine.count = line.tokens.size(); + inLine.tokens = InstructionTextToken::CreateInstructionTextTokenList(line.tokens); + + size_t count = 0; + BNDisassemblyTextLine* result = BNDisassemblyTextRendererWrapComment(m_object, &inLine, &count, + comment.c_str(), hasAutoAnnotations, leadingSpaces.c_str()); + + for (size_t i = 0; i < count; i++) + { + DisassemblyTextLine line; + line.addr = result[i].addr; + line.instrIndex = result[i].instrIndex; + line.highlight = result[i].highlight; + line.tokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(result[i].tokens, result[i].count); + lines.push_back(line); + } + + BNFreeDisassemblyTextLines(result, count); + for (size_t i = 0; i < inLine.count; i++) + { + BNFreeString(inLine.tokens[i].text); + for (size_t j = 0; j < inLine.tokens[j].namesCount; j++) + BNFreeString(inLine.tokens[i].typeNames[j]); + delete[] inLine.tokens[i].typeNames; + } + delete[] inLine.tokens; +} diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 5f02b41b..33b0c24a 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1048,6 +1048,7 @@ namespace BinaryNinja InstructionTextToken(BNInstructionTextTokenType type, BNInstructionTextTokenContext context, const std::string& text, uint64_t address, uint64_t value = 0, size_t size = 0, size_t operand = BN_INVALID_OPERAND, uint8_t confidence = BN_FULL_CONFIDENCE, const std::vector<std::string>& typeName={}); + InstructionTextToken(const BNInstructionTextToken& token); InstructionTextToken WithConfidence(uint8_t conf); static BNInstructionTextToken* CreateInstructionTextTokenList(const std::vector<InstructionTextToken>& tokens); @@ -4386,4 +4387,49 @@ namespace BinaryNinja static void RegisterGenericDataRenderer(DataRenderer* renderer); static void RegisterTypeSpecificDataRenderer(DataRenderer* renderer); }; + + class DisassemblyTextRenderer: public CoreRefCountObject<BNDisassemblyTextRenderer, + BNNewDisassemblyTextRendererReference, BNFreeDisassemblyTextRenderer> + { + public: + DisassemblyTextRenderer(Function* func, DisassemblySettings* settings = nullptr); + DisassemblyTextRenderer(LowLevelILFunction* func, DisassemblySettings* settings = nullptr); + DisassemblyTextRenderer(MediumLevelILFunction* func, DisassemblySettings* settings = nullptr); + DisassemblyTextRenderer(BNDisassemblyTextRenderer* renderer); + + Ref<Function> GetFunction() const; + Ref<LowLevelILFunction> GetLowLevelILFunction() const; + Ref<MediumLevelILFunction> GetMediumLevelILFunction() const; + + Ref<BasicBlock> GetBasicBlock() const; + Ref<Architecture> GetArchitecture() const; + Ref<DisassemblySettings> GetSettings() const; + void SetBasicBlock(BasicBlock* block); + void SetArchitecture(Architecture* arch); + void SetSettings(DisassemblySettings* settings); + + virtual bool IsIL() const; + virtual bool HasDataFlow() const; + + virtual void GetInstructionAnnotations(std::vector<InstructionTextToken>& tokens, uint64_t addr); + virtual bool GetInstructionText(uint64_t addr, size_t& len, + std::vector<InstructionTextToken>& tokens, uint64_t& displayAddr); + + virtual bool GetDisassemblyText(uint64_t addr, size_t& len, std::vector<DisassemblyTextLine>& lines); + void ResetDeduplicatedComments(); + + bool AddSymbolToken(std::vector<InstructionTextToken>& tokens, uint64_t addr, size_t size, size_t operand); + void AddStackVariableReferenceTokens(std::vector<InstructionTextToken>& tokens, + const StackVariableReference& ref); + + static bool IsIntegerToken(BNInstructionTextTokenType type); + void AddIntegerToken(std::vector<InstructionTextToken>& tokens, const InstructionTextToken& token, + Architecture* arch, uint64_t addr); + + void WrapComment(DisassemblyTextLine& line, + std::vector<DisassemblyTextLine>& lines, + const std::string& comment, + bool hasAutoAnnotations, + const std::string& leadingSpaces=" "); + }; } diff --git a/binaryninjacore.h b/binaryninjacore.h index 9f735f76..2e8b6a9a 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -159,6 +159,7 @@ extern "C" struct BNDataBuffer; struct BNDataRenderer; struct BNDataRendererContainer; + struct BNDisassemblyTextRenderer; typedef bool (*BNLoadPluginCallback)(const char* repoPath, const char* pluginPath, void* ctx); @@ -2609,6 +2610,43 @@ extern "C" BNDisassemblySettings* settings, size_t* count); BINARYNINJACOREAPI void BNFreeDisassemblyTextLines(BNDisassemblyTextLine* lines, size_t count); + BINARYNINJACOREAPI BNDisassemblyTextRenderer* BNCreateDisassemblyTextRenderer(BNFunction* func, + BNDisassemblySettings* settings); + BINARYNINJACOREAPI BNDisassemblyTextRenderer* BNCreateLowLevelILDisassemblyTextRenderer(BNLowLevelILFunction* func, + BNDisassemblySettings* settings); + BINARYNINJACOREAPI BNDisassemblyTextRenderer* BNCreateMediumLevelILDisassemblyTextRenderer(BNMediumLevelILFunction* func, + BNDisassemblySettings* settings); + BINARYNINJACOREAPI BNDisassemblyTextRenderer* BNNewDisassemblyTextRendererReference(BNDisassemblyTextRenderer* renderer); + BINARYNINJACOREAPI void BNFreeDisassemblyTextRenderer(BNDisassemblyTextRenderer* renderer); + BINARYNINJACOREAPI BNFunction* BNGetDisassemblyTextRendererFunction(BNDisassemblyTextRenderer* renderer); + BINARYNINJACOREAPI BNLowLevelILFunction* BNGetDisassemblyTextRendererLowLevelILFunction(BNDisassemblyTextRenderer* renderer); + BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetDisassemblyTextRendererMediumLevelILFunction(BNDisassemblyTextRenderer* renderer); + BINARYNINJACOREAPI BNBasicBlock* BNGetDisassemblyTextRendererBasicBlock(BNDisassemblyTextRenderer* renderer); + BINARYNINJACOREAPI BNArchitecture* BNGetDisassemblyTextRendererArchitecture(BNDisassemblyTextRenderer* renderer); + BINARYNINJACOREAPI BNDisassemblySettings* BNGetDisassemblyTextRendererSettings(BNDisassemblyTextRenderer* renderer); + BINARYNINJACOREAPI void BNSetDisassemblyTextRendererBasicBlock(BNDisassemblyTextRenderer* renderer, BNBasicBlock* block); + BINARYNINJACOREAPI void BNSetDisassemblyTextRendererArchitecture(BNDisassemblyTextRenderer* renderer, BNArchitecture* arch); + BINARYNINJACOREAPI void BNSetDisassemblyTextRendererSettings(BNDisassemblyTextRenderer* renderer, BNDisassemblySettings* settings); + BINARYNINJACOREAPI bool BNIsILDisassemblyTextRenderer(BNDisassemblyTextRenderer* renderer); + BINARYNINJACOREAPI bool BNDisassmblyTextRendererHasDataFlow(BNDisassemblyTextRenderer* renderer); + BINARYNINJACOREAPI BNInstructionTextToken* BNGetDisassemblyTextRendererInstructionAnnotations( + BNDisassemblyTextRenderer* renderer, uint64_t addr, size_t* count); + BINARYNINJACOREAPI bool BNGetDisassemblyTextRendererInstructionText(BNDisassemblyTextRenderer* renderer, + uint64_t addr, size_t* len, BNInstructionTextToken** result, size_t* count, uint64_t* displayAddr); + BINARYNINJACOREAPI bool BNGetDisassemblyTextRendererLines(BNDisassemblyTextRenderer* renderer, + uint64_t addr, size_t* len, BNDisassemblyTextLine** result, size_t* count); + BINARYNINJACOREAPI void BNResetDisassemblyTextRendererDeduplicatedComments(BNDisassemblyTextRenderer* renderer); + BINARYNINJACOREAPI bool BNGetDisassemblyTextRendererSymbolTokens(BNDisassemblyTextRenderer* renderer, uint64_t addr, + size_t size, size_t operand, BNInstructionTextToken** result, size_t* count); + BINARYNINJACOREAPI BNInstructionTextToken* BNGetDisassemblyTextRendererStackVariableReferenceTokens( + BNDisassemblyTextRenderer* renderer, BNStackVariableReference* ref, size_t* count); + BINARYNINJACOREAPI bool BNIsIntegerToken(BNInstructionTextTokenType type); + BINARYNINJACOREAPI BNInstructionTextToken* BNGetDisassemblyTextRendererIntegerTokens(BNDisassemblyTextRenderer* renderer, + BNInstructionTextToken* token, BNArchitecture* arch, uint64_t addr, size_t* count); + BINARYNINJACOREAPI BNDisassemblyTextLine* BNDisassemblyTextRendererWrapComment(BNDisassemblyTextRenderer* renderer, + const BNDisassemblyTextLine* inLine, size_t* outLineCount, const char* comment, bool hasAutoAnnotations, + const char* leadingSpaces); + BINARYNINJACOREAPI void BNMarkFunctionAsRecentlyUsed(BNFunction* func); BINARYNINJACOREAPI void BNMarkBasicBlockAsRecentlyUsed(BNBasicBlock* block); diff --git a/python/flowgraph.py b/python/flowgraph.py index d3c57a56..103eed69 100644 --- a/python/flowgraph.py +++ b/python/flowgraph.py @@ -355,7 +355,7 @@ class FlowGraph(object): graph = self.update() if graph is None: return None - return core.BNNewFlowGraphReference(graph.handle) + return ctypes.cast(core.BNNewFlowGraphReference(graph.handle), ctypes.c_void_p).value except: log.log_error(traceback.format_exc()) return None diff --git a/python/function.py b/python/function.py index c8e339cd..7471d639 100644 --- a/python/function.py +++ b/python/function.py @@ -1856,3 +1856,195 @@ class InstructionTextToken(object): def __repr__(self): return repr(self.text) + + +class DisassemblyTextRenderer(object): + def __init__(self, func = None, settings = None, handle = None): + if handle is None: + if func is None: + raise ValueError("function required for disassembly") + settings_obj = None + if settings is not None: + settings_obj = settings.handle + if isinstance(func, Function): + self.handle = core.BNCreateDisassemblyTextRenderer(func.handle, settings_obj) + elif isinstance(func, binaryninja.lowlevelil.LowLevelILFunction): + self.handle = core.BNCreateLowLevelILDisassemblyTextRenderer(func.handle, settings_obj) + elif isinstance(func, binaryninja.mediumlevelil.MediumLevelILFunction): + self.handle = core.BNCreateMediumLevelILDisassemblyTextRenderer(func.handle, settings_obj) + else: + raise TypeError("invalid function object") + else: + self.handle = handle + + def __del__(self): + core.BNFreeDisassemblyTextRenderer(self.handle) + + @property + def function(self): + return Function(handle = core.BNGetDisassemblyTextRendererFunction(self.handle)) + + @property + def il_function(self): + llil = core.BNGetDisassemblyTextRendererLowLevelILFunction(self.handle) + if llil: + return binaryninja.lowlevelil.LowLevelILFunction(handle = llil) + mlil = core.BNGetDisassemblyTextRendererMediumLevelILFunction(self.handle) + if mlil: + return binaryninja.mediumlevelil.MediumLevelILFunction(handle = mlil) + return None + + @property + def basic_block(self): + result = core.BNGetDisassemblyTextRendererBasicBlock(self.handle) + if result: + return binaryninja.basicblock.BasicBlock(handle = result) + return None + + @basic_block.setter + def basic_block(self, block): + if block is not None: + core.BNSetDisassemblyTextRendererBasicBlock(self.handle, block.handle) + core.BNSetDisassemblyTextRendererBasicBlock(self.handle, None) + + @property + def arch(self): + return binaryninja.architecture.Architecture(handle = core.BNSetDisassemblyTextRendererArchitecture(self.handle)) + + @arch.setter + def arch(self, arch): + core.BNSetDisassemblyTextRendererArchitecture(self.handle, arch.handle) + + @property + def settings(self): + return DisassemblySettings(handle = core.BNGetDisassemblyTextRendererSettings(self.handle)) + + @settings.setter + def settings(self, settings): + if settings is not None: + core.BNSetDisassemblyTextRendererSettings(self.handle, settings.handle) + core.BNSetDisassemblyTextRendererSettings(self.handle, None) + + @property + def il(self): + return core.BNIsILDisassemblyTextRenderer(self.handle) + + @property + def has_data_flow(self): + return core.BNDisassmblyTextRendererHasDataFlow(self.handle) + + def get_instruction_annotations(self, addr): + count = ctypes.c_ulonglong() + tokens = core.BNGetDisassemblyTextRendererInstructionAnnotations(self.handle, addr, count) + result = InstructionTextToken.get_instruction_lines(tokens, count.value) + core.BNFreeInstructionText(tokens, count.value) + return result + + def get_instruction_text(self, addr): + count = ctypes.c_ulonglong() + length = ctypes.c_ulonglong() + display_addr = ctypes.c_ulonglong() + tokens = ctypes.POINTER(core.BNInstructionTextToken)() + if not core.BNGetDisassemblyTextRendererInstructionText(self.handle, addr, length, tokens, count, display_addr): + return None, 0, 0 + result = InstructionTextToken.get_instruction_lines(tokens, count.value) + core.BNFreeInstructionText(tokens, count.value) + return result, length.value, display_addr.value + + def get_disassembly_text(self, addr): + count = ctypes.c_ulonglong() + length = ctypes.c_ulonglong() + length.value = 0 + lines = ctypes.POINTER(core.BNDisassemblyTextLine)() + ok = core.BNGetDisassemblyTextRendererLines(self.handle, addr, length, lines, count) + if not ok: + return None, 0 + il_function = self.il_function + result = [] + for i in range(0, count.value): + addr = lines[i].addr + if (lines[i].instrIndex != 0xffffffffffffffff) and (il_function is not None): + il_instr = il_function[lines[i].instrIndex] + else: + il_instr = None + color = highlight.HighlightColor._from_core_struct(lines[i].highlight) + tokens = InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count) + result.append(DisassemblyTextLine(tokens, addr, il_instr, color)) + core.BNFreeDisassemblyTextLines(lines, count.value) + return (result, length.value) + + def reset_deduplicated_comments(self): + core.BNResetDisassemblyTextRendererDeduplicatedComments(self.handle) + + def add_symbol_token(self, tokens, addr, size, operand = None): + if operand is None: + operand = 0xffffffff + count = ctypes.c_ulonglong() + new_tokens = ctypes.POINTER(core.BNInstructionTextToken)() + if not core.BNGetDisassemblyTextRendererSymbolTokens(self.handle, addr, size, operand, new_tokens, count): + return False + result = binaryninja.function.InstructionTextToken.get_instruction_lines(new_tokens, count.value) + tokens += result + core.BNFreeInstructionText(new_tokens, count.value) + return True + + def add_stack_var_reference_tokens(self, tokens, ref): + stack_ref = core.BNStackVariableReference() + if ref.source_operand is None: + stack_ref.sourceOperand = 0xffffffff + else: + stack_ref.sourceOperand = ref.source_operand + if ref.type is None: + stack_ref.type = None + stack_ref.typeConfidence = 0 + else: + stack_ref.type = ref.type.handle + stack_ref.typeConfidence = ref.type.confidence + stack_ref.name = ref.name + stack_ref.varIdentifier = ref.var.identifier + stack_ref.referencedOffset = ref.referenced_offset + stack_ref.size = ref.size + count = ctypes.c_ulonglong() + new_tokens = core.BNGetDisassemblyTextRendererStackVariableReferenceTokens(self.handle, stack_ref, count) + result = InstructionTextToken.get_instruction_lines(new_tokens, count.value) + tokens += result + core.BNFreeInstructionText(new_tokens, count.value) + + @classmethod + def is_integer_token(self, token): + return core.BNIsIntegerToken(token) + + def add_integer_token(self, tokens, int_token, addr, arch = None): + if arch is not None: + arch = arch.handle + in_token_obj = InstructionTextToken.get_instruction_lines([int_token]) + count = ctypes.c_ulonglong() + new_tokens = core.BNGetDisassemblyTextRendererIntegerTokens(self.handle, in_token_obj, arch, addr, count) + result = InstructionTextToken.get_instruction_lines(new_tokens, count.value) + tokens += result + core.BNFreeInstructionText(new_tokens, count.value) + + def wrap_comment(self, lines, cur_line, comment, has_auto_annotations, leading_spaces = " "): + cur_line_obj = core.BNDisassemblyTextLine() + cur_line_obj.addr = cur_line.address + if cur_line.il_instruction is None: + cur_line_obj.instrIndex = 0xffffffffffffffff + else: + cur_line_obj.instrIndex = cur_line.il_instruction.instr_index + cur_line_obj.highlight = cur_line.highlight._get_core_struct() + cur_line_obj.tokens = InstructionTextToken.get_instruction_lines(cur_line.tokens) + cur_line_obj.count = len(cur_line.tokens) + count = ctypes.c_ulonglong() + new_lines = core.BNDisassemblyTextRendererWrapComment(self.handle, cur_line_obj, count, comment, + has_auto_annotations, leading_spaces) + il_function = self.il_function + for i in range(0, count.value): + addr = new_lines[i].addr + if (new_lines[i].instrIndex != 0xffffffffffffffff) and (il_function is not None): + il_instr = il_function[new_lines[i].instrIndex] + else: + il_instr = None + color = highlight.HighlightColor._from_core_struct(new_lines[i].highlight) + tokens = InstructionTextToken.get_instruction_lines(new_lines[i].tokens, new_lines[i].count) + lines.append(DisassemblyTextLine(tokens, addr, il_instr, color)) + core.BNFreeDisassemblyTextLines(new_lines, count.value) |
