summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2019-02-22 15:36:40 -0500
committerRusty Wagner <rusty@vector35.com>2019-02-22 15:41:02 -0500
commit2f84b5c600f08101a6a7ee08738a3e3a32686f46 (patch)
tree909537511998daa9796737e4cd287b89488761f7
parente7228de8fe2640f126a01064a8485c1270846bd1 (diff)
Add API for constructing disassembly text
-rw-r--r--architecture.cpp264
-rw-r--r--binaryninjaapi.h46
-rw-r--r--binaryninjacore.h38
-rw-r--r--python/flowgraph.py2
-rw-r--r--python/function.py192
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)