From 231afab8b0ba6c8c9eff879681c52724b6688c18 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Mon, 3 Dec 2018 22:20:28 -0500 Subject: Commonize all InstructionTextToken generation --- python/architecture.py | 26 ++---------------- python/basicblock.py | 12 +-------- python/binaryview.py | 12 +-------- python/datarender.py | 27 +++---------------- python/flowgraph.py | 35 +++--------------------- python/function.py | 71 ++++++++++++++++++++++++++++++------------------- python/lowlevelil.py | 12 +-------- python/mediumlevelil.py | 12 +-------- python/types.py | 42 +++++------------------------ 9 files changed, 62 insertions(+), 187 deletions(-) (limited to 'python') diff --git a/python/architecture.py b/python/architecture.py index 7bef1b67..b5daaa6d 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -533,19 +533,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)): tokens = info[0] length[0] = info[1] count[0] = len(tokens) - token_buf = (core.BNInstructionTextToken * len(tokens))() - for i in range(0, len(tokens)): - if isinstance(tokens[i].type, str): - token_buf[i].type = InstructionTextTokenType[tokens[i].type] - else: - token_buf[i].type = tokens[i].type - token_buf[i].text = tokens[i].text - token_buf[i].value = tokens[i].value - token_buf[i].size = tokens[i].size - token_buf[i].operand = tokens[i].operand - token_buf[i].context = tokens[i].context - token_buf[i].confidence = tokens[i].confidence - token_buf[i].address = tokens[i].address + token_buf = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens) result[0] = token_buf ptr = ctypes.cast(token_buf, ctypes.c_void_p) self._pending_token_lists[ptr.value] = (ptr.value, token_buf) @@ -2328,17 +2316,7 @@ class CoreArchitecture(Architecture): tokens = ctypes.POINTER(core.BNInstructionTextToken)() if not core.BNGetInstructionText(self.handle, buf, addr, length, tokens, count): return None, 0 - result = [] - for i in range(0, count.value): - token_type = InstructionTextTokenType(tokens[i].type) - text = tokens[i].text - value = tokens[i].value - size = tokens[i].size - operand = tokens[i].operand - context = tokens[i].context - confidence = tokens[i].confidence - address = tokens[i].address - result.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) + result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value) core.BNFreeInstructionText(tokens, count.value) return result, length.value diff --git a/python/basicblock.py b/python/basicblock.py index d66a41c2..d68189ab 100644 --- a/python/basicblock.py +++ b/python/basicblock.py @@ -338,17 +338,7 @@ class BasicBlock(object): else: il_instr = None color = highlight.HighlightColor._from_core_struct(lines[i].highlight) - tokens = [] - for j in range(0, lines[i].count): - token_type = InstructionTextTokenType(lines[i].tokens[j].type) - text = lines[i].tokens[j].text - value = lines[i].tokens[j].value - size = lines[i].tokens[j].size - operand = lines[i].tokens[j].operand - context = lines[i].tokens[j].context - confidence = lines[i].tokens[j].confidence - address = lines[i].tokens[j].address - tokens.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) + tokens = binaryninja.function.InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count) result.append(binaryninja.function.DisassemblyTextLine(tokens, addr, il_instr, color)) core.BNFreeDisassemblyTextLines(lines, count.value) return result diff --git a/python/binaryview.py b/python/binaryview.py index 612632d3..cefe6481 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -3271,17 +3271,7 @@ class BinaryView(object): block = basicblock.BasicBlock(self, core.BNNewBasicBlockReference(lines[i].block)) color = highlight.HighlightColor._from_core_struct(lines[i].contents.highlight) addr = lines[i].contents.addr - tokens = [] - for j in range(0, lines[i].contents.count): - token_type = InstructionTextTokenType(lines[i].contents.tokens[j].type) - text = lines[i].contents.tokens[j].text - value = lines[i].contents.tokens[j].value - size = lines[i].contents.tokens[j].size - operand = lines[i].contents.tokens[j].operand - context = lines[i].contents.tokens[j].context - confidence = lines[i].contents.tokens[j].confidence - address = lines[i].contents.tokens[j].address - tokens.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) + tokens = binaryninja.function.InstructionTextToken.get_instruction_lines(lines[i].contents.tokens, lines[i].contents.count) contents = binaryninja.function.DisassemblyTextLine(tokens, addr, color = color) result.append(lineardisassembly.LinearDisassemblyLine(lines[i].type, func, block, lines[i].lineOffset, contents)) diff --git a/python/datarender.py b/python/datarender.py index db60f42e..c0a1dd3b 100644 --- a/python/datarender.py +++ b/python/datarender.py @@ -112,18 +112,7 @@ class DataRenderer(object): view = BinaryView(file_metadata=file_metadata, handle=core.BNNewViewReference(view)) type = Type(handle=core.BNNewTypeReference(type)) - prefixTokens = [] - for i in range(prefixCount): - token_type = InstructionTextTokenType(prefix[i].type) - text = prefix[i].text - value = prefix[i].value - size = prefix[i].size - operand = prefix[i].operand - context = prefix[i].context - address = prefix[i].address - confidence = prefix[i].confidence - prefixTokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) - + prefixTokens = InstructionTextToken.get_instruction_lines(prefix, prefixCount) pycontext = [] for i in range(ctxCount): pycontext.append(Type(core.BNNewTypeReference(typeCtx[i]))) @@ -140,8 +129,6 @@ class DataRenderer(object): if isinstance(color, HighlightStandardColor): color = highlight.HighlightColor(color) line_buf[i].highlight = color._get_core_struct() - line_buf[i].count = len(line.tokens) - line_buf[i].tokens = (core.BNInstructionTextToken * len(line.tokens))() if line.address is None: if len(line.tokens) > 0: line_buf[i].addr = line.tokens[0].address @@ -153,15 +140,9 @@ class DataRenderer(object): line_buf[i].instrIndex = line.il_instruction.instr_index else: line_buf[i].instrIndex = 0xffffffffffffffff - for j in range(len(line.tokens)): - line_buf[i].tokens[j].type = line.tokens[j].type - line_buf[i].tokens[j].text = line.tokens[j].text - line_buf[i].tokens[j].value = line.tokens[j].value - line_buf[i].tokens[j].size = line.tokens[j].size - line_buf[i].tokens[j].operand = line.tokens[j].operand - line_buf[i].tokens[j].context = line.tokens[j].context - line_buf[i].tokens[j].confidence = line.tokens[j].confidence - line_buf[i].tokens[j].address = line.tokens[j].address + + line_buf[i].count = len(line.tokens) + line_buf[i].tokens = InstructionTextToken.get_instruction_lines(line.tokens) return ctypes.cast(line_buf, ctypes.c_void_p).value except: diff --git a/python/flowgraph.py b/python/flowgraph.py index 79351838..9d786704 100644 --- a/python/flowgraph.py +++ b/python/flowgraph.py @@ -128,17 +128,7 @@ class FlowGraphNode(object): else: il_instr = None color = highlight.HighlightColor._from_core_struct(lines[i].highlight) - tokens = [] - for j in range(0, lines[i].count): - token_type = InstructionTextTokenType(lines[i].tokens[j].type) - text = lines[i].tokens[j].text - value = lines[i].tokens[j].value - size = lines[i].tokens[j].size - operand = lines[i].tokens[j].operand - context = lines[i].tokens[j].context - confidence = lines[i].tokens[j].confidence - address = lines[i].tokens[j].address - tokens.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) + tokens = function.InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count) result.append(function.DisassemblyTextLine(tokens, addr, il_instr, color)) core.BNFreeDisassemblyTextLines(lines, count.value) return result @@ -172,16 +162,7 @@ class FlowGraphNode(object): color = highlight.HighlightColor(color) line_buf[i].highlight = color._get_core_struct() line_buf[i].count = len(line.tokens) - line_buf[i].tokens = (core.BNInstructionTextToken * len(line.tokens))() - for j in range(0, len(line.tokens)): - line_buf[i].tokens[j].type = line.tokens[j].type - line_buf[i].tokens[j].text = line.tokens[j].text - line_buf[i].tokens[j].value = line.tokens[j].value - line_buf[i].tokens[j].size = line.tokens[j].size - line_buf[i].tokens[j].operand = line.tokens[j].operand - line_buf[i].tokens[j].context = line.tokens[j].context - line_buf[i].tokens[j].confidence = line.tokens[j].confidence - line_buf[i].tokens[j].address = line.tokens[j].address + line_buf[i].tokens = function.InstructionTextToken.get_instruction_lines(line.tokens) core.BNSetFlowGraphNodeLines(self.handle, line_buf, len(lines)) @property @@ -244,17 +225,7 @@ class FlowGraphNode(object): il_instr = block.il_function[lines[i].instrIndex] else: il_instr = None - tokens = [] - for j in range(0, lines[i].count): - token_type = InstructionTextTokenType(lines[i].tokens[j].type) - text = lines[i].tokens[j].text - value = lines[i].tokens[j].value - size = lines[i].tokens[j].size - operand = lines[i].tokens[j].operand - context = lines[i].tokens[j].context - confidence = lines[i].tokens[j].confidence - address = lines[i].tokens[j].address - tokens.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) + tokens = function.InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count) yield function.DisassemblyTextLine(tokens, addr, il_instr) finally: core.BNFreeDisassemblyTextLines(lines, count.value) diff --git a/python/function.py b/python/function.py index bda06091..d1899d18 100644 --- a/python/function.py +++ b/python/function.py @@ -1164,7 +1164,7 @@ class Function(object): count = ctypes.c_ulonglong() branches = core.BNGetIndirectBranchesAt(self.handle, arch.handle, addr, count) result = [] - for i in range(0, count.value): + for i in range(count.value): result.append(IndirectBranchInfo(binaryninja.architecture.CoreArchitecture._from_cache(branches[i].sourceArch), branches[i].sourceAddr, binaryninja.architecture.CoreArchitecture._from_cache(branches[i].destArch), branches[i].destAddr, branches[i].autoDefined)) core.BNFreeIndirectBranchList(branches) return result @@ -1175,21 +1175,8 @@ class Function(object): count = ctypes.c_ulonglong(0) lines = core.BNGetFunctionBlockAnnotations(self.handle, arch.handle, addr, count) result = [] - for i in range(0, count.value): - tokens = [] - for j in range(0, lines[i].count): - token_type = InstructionTextTokenType(lines[i].tokens[j].type) - text = lines[i].tokens[j].text - if not isinstance(text, str): - text = text.encode("charmap") - value = lines[i].tokens[j].value - size = lines[i].tokens[j].size - operand = lines[i].tokens[j].operand - context = lines[i].tokens[j].context - confidence = lines[i].tokens[j].confidence - address = lines[i].tokens[j].address - tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) - result.append(tokens) + for i in range(count.value): + result.append(InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count)) core.BNFreeInstructionTextLines(lines, count.value) return result @@ -1487,17 +1474,7 @@ class Function(object): for i in range(0, count.value): addr = lines[i].addr color = highlight.HighlightColor._from_core_struct(lines[i].highlight) - tokens = [] - for j in range(0, lines[i].count): - token_type = InstructionTextTokenType(lines[i].tokens[j].type) - text = lines[i].tokens[j].text - value = lines[i].tokens[j].value - size = lines[i].tokens[j].size - operand = lines[i].tokens[j].operand - context = lines[i].tokens[j].context - confidence = lines[i].tokens[j].confidence - address = lines[i].tokens[j].address - tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) + tokens = InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count) result.append(DisassemblyTextLine(tokens, addr, color = color)) core.BNFreeDisassemblyTextLines(lines, count.value) return result @@ -1815,7 +1792,7 @@ class InstructionTextToken(object): """ def __init__(self, token_type, text, value = 0, size = 0, operand = 0xffffffff, - context = InstructionTextTokenContext.NoTokenContext, address = 0, confidence = types.max_confidence): + context = InstructionTextTokenContext.NoTokenContext, address = 0, confidence = types.max_confidence, typeName=""): self.type = InstructionTextTokenType(token_type) self.text = text self.value = value @@ -1824,6 +1801,44 @@ class InstructionTextToken(object): self.context = InstructionTextTokenContext(context) self.confidence = confidence self.address = address + self.typeName = typeName + + @classmethod + def get_instruction_lines(cls, tokens, count=0): + """ Helper method for converting between core.BNInstructionTextToken and InstructionTextToken lists """ + if isinstance(tokens, list): + result = (core.BNInstructionTextToken * len(tokens))() + for j in range(len(tokens)): + result.type = tokens[j].type + result.text = tokens[j].text + result.value = tokens[j].value + result.size = tokens[j].size + result.operand = tokens[j].operand + result.context = tokens[j].context + result.confidence = tokens[j].confidence + result.address = tokens[j].address + result.typeName = tokens[j].typeName + return result + + if not isinstance(tokens, core.BNInstructionTextToken): + raise TypeError("tokens is not of type core.BNInstructionTextToken") + result = [] + for j in range(count): + token_type = InstructionTextTokenType(tokens[j].type) + text = tokens[j].text + if not isinstance(text, str): + text = text.encode("charmap") + value = tokens[j].value + size = tokens[j].size + operand = tokens[j].operand + context = tokens[j].context + confidence = tokens[j].confidence + address = tokens[j].address + typeName = tokens[j].typeName + if not isinstance(typeName, str): + typeName = typeName.encode("charmap") + result.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence, typeName)) + return result def __str__(self): return self.text diff --git a/python/lowlevelil.py b/python/lowlevelil.py index a98de6d3..2a8ba5d0 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -524,17 +524,7 @@ class LowLevelILInstruction(object): if not core.BNGetLowLevelILExprText(self.function.handle, self.function.arch.handle, self.expr_index, tokens, count): return None - result = [] - for i in range(0, count.value): - token_type = InstructionTextTokenType(tokens[i].type) - text = tokens[i].text - value = tokens[i].value - size = tokens[i].size - operand = tokens[i].operand - context = tokens[i].context - confidence = tokens[i].confidence - address = tokens[i].address - result.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) + result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value) core.BNFreeInstructionText(tokens, count.value) return result diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index c88ab6b8..2dae008a 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -331,17 +331,7 @@ class MediumLevelILInstruction(object): if not core.BNGetMediumLevelILExprText(self.function.handle, self.function.arch.handle, self.expr_index, tokens, count): return None - result = [] - for i in range(0, count.value): - token_type = InstructionTextTokenType(tokens[i].type) - text = tokens[i].text - value = tokens[i].value - size = tokens[i].size - operand = tokens[i].operand - context = tokens[i].context - confidence = tokens[i].confidence - address = tokens[i].address - result.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) + result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value) core.BNFreeInstructionText(tokens, count.value) return result diff --git a/python/types.py b/python/types.py index 05e531e1..e6913f93 100644 --- a/python/types.py +++ b/python/types.py @@ -455,18 +455,8 @@ class Type(object): if self.platform is not None: platform = self.platform.handle tokens = core.BNGetTypeTokens(self.handle, platform, base_confidence, count) - result = [] - for i in range(0, count.value): - token_type = InstructionTextTokenType(tokens[i].type) - text = tokens[i].text - value = tokens[i].value - size = tokens[i].size - operand = tokens[i].operand - context = tokens[i].context - confidence = tokens[i].confidence - address = tokens[i].address - result.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) - core.BNFreeTokenList(tokens, count.value) + result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value) + core.BNFreeInstructionText(tokens, count.value) return result def get_tokens_before_name(self, base_confidence = max_confidence): @@ -475,18 +465,8 @@ class Type(object): if self.platform is not None: platform = self.platform.handle tokens = core.BNGetTypeTokensBeforeName(self.handle, platform, base_confidence, count) - result = [] - for i in range(0, count.value): - token_type = InstructionTextTokenType(tokens[i].type) - text = tokens[i].text - value = tokens[i].value - size = tokens[i].size - operand = tokens[i].operand - context = tokens[i].context - confidence = tokens[i].confidence - address = tokens[i].address - result.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) - core.BNFreeTokenList(tokens, count.value) + result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value) + core.BNFreeInstructionText(tokens, count.value) return result def get_tokens_after_name(self, base_confidence = max_confidence): @@ -495,18 +475,8 @@ class Type(object): if self.platform is not None: platform = self.platform.handle tokens = core.BNGetTypeTokensAfterName(self.handle, platform, base_confidence, count) - result = [] - for i in range(0, count.value): - token_type = InstructionTextTokenType(tokens[i].type) - text = tokens[i].text - value = tokens[i].value - size = tokens[i].size - operand = tokens[i].operand - context = tokens[i].context - confidence = tokens[i].confidence - address = tokens[i].address - result.append(binaryninja.function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence)) - core.BNFreeTokenList(tokens, count.value) + result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value) + core.BNFreeInstructionText(tokens, count.value) return result @classmethod -- cgit v1.3.1