def get_form_input(fields, title): """ ``get_from_input`` Prompts the user for a set of inputs specified in ``fields`` with given title. The fields parameter is a list which can contain the following types: - str - an alias for LabelField - None - an alias for SeparatorField - LabelField - Text output - SeparatorField - Vertical spacing - TextLineField - Prompt for a string value - MultilineTextField - Prompt for multi-line string value - IntegerField - Prompt for an integer - AddressField - Prompt for an address - ChoiceField - Prompt for a choice from provided options - OpenFileNameField - Prompt for file to open - SaveFileNameField - Prompt for file to save to - DirectoryNameField - Prompt for directory name This API is flexible and works both in the UI via a pop-up dialog and on the command-line. :params list fields: A list containing of the above specified classes, strings or None :params str title: The title of the pop-up dialog. :Example: >>> int_f = IntegerField("Specify Integer") >>> tex_f = TextLineField("Specify name") >>> choice_f = ChoiceField("Options", ["Yes", "No", "Maybe"]) >>> get_form_input(["Get Data", None, int_f, tex_f, choice_f], "The options") Get Data Specify Integer 1337 Specify name Peter The options 1) Yes 2) No 3) Maybe Options 1 >>> True >>> print(tex_f.result, int_f.result, choice_f.result) Peter 1337 0 """ value = (core.BNFormInputField * len(fields))() for i in range(0, len(fields)): if isinstance(fields[i], str): LabelField(fields[i])._fill_core_struct(value[i]) elif fields[i] is None: SeparatorField()._fill_core_struct(value[i]) else: fields[i]._fill_core_struct(value[i]) if not core.BNGetFormInput(value, len(fields), title): return False for i in range(0, len(fields)): if not (isinstance(fields[i], str) or (fields[i] is None)): fields[i]._get_result(value[i]) core.BNFreeFormInputResults(value, len(fields)) return True
def get_iterated_dominance_frontier(self, blocks): if len(blocks) == 0: return [] block_set = (ctypes.POINTER(core.BNBasicBlock) * len(blocks))() for i in range(len(blocks)): block_set[i] = blocks[i].handle count = ctypes.c_ulonglong() out_blocks = core.BNGetBasicBlockIteratedDominanceFrontier(block_set, len(blocks), count) result = [] for i in range(0, count.value): result.append(BasicBlock(blocks[0].view, core.BNNewBasicBlockReference(out_blocks[i]))) core.BNFreeBasicBlockList(out_blocks, count.value) return result
def __iter__(self): if self.is_array: for i in range(core.BNMetadataSize(self.handle)): yield Metadata(handle=core.BNMetadataGetForIndex(self.handle, i)).value elif self.is_dict: result = core.BNMetadataGetValueStore(self.handle) try: for i in range(result.contents.size): if isinstance(result.contents.keys[i], bytes): yield str(pyNativeStr(result.contents.keys[i])) else: yield result.contents.keys[i] finally: core.BNFreeMetadataValueStore(result) else: raise Exception("Metadata object doesn't support iteration")
def __init__(self, handle): if handle is None: self._cb = core.BNCustomTransform() self._cb.context = 0 self._cb.getParameters = self._cb.getParameters.__class__(self._get_parameters) self._cb.freeParameters = self._cb.freeParameters.__class__(self._free_parameters) self._cb.decode = self._cb.decode.__class__(self._decode) self._cb.encode = self._cb.encode.__class__(self._encode) self._pending_param_lists = {} self.type = self.__class__.transform_type if not isinstance(self.type, str): self.type = TransformType(self.type) self.name = self.__class__.name self.long_name = self.__class__.long_name self.group = self.__class__.group self.parameters = self.__class__.parameters else: self.handle = handle self.type = TransformType(core.BNGetTransformType(self.handle)) self.name = core.BNGetTransformName(self.handle) self.long_name = core.BNGetTransformLongName(self.handle) self.group = core.BNGetTransformGroup(self.handle) count = ctypes.c_ulonglong() params = core.BNGetTransformParameterList(self.handle, count) self.parameters = [] for i in range(0, count.value): self.parameters.append(TransformParameter(params[i].name, params[i].longName, params[i].fixedLength)) core.BNFreeTransformParameterList(params, count.value)
def lines(self, lines): if isinstance(lines, str): lines = lines.split('\n') line_buf = (core.BNDisassemblyTextLine * len(lines))() for i in range(0, len(lines)): line = lines[i] if isinstance(line, str): line = function.DisassemblyTextLine([function.InstructionTextToken(InstructionTextTokenType.TextToken, line)]) if not isinstance(line, function.DisassemblyTextLine): line = function.DisassemblyTextLine(line) if line.address is None: if len(line.tokens) > 0: line_buf[i].addr = line.tokens[0].address else: line_buf[i].addr = 0 else: line_buf[i].addr = line.address if line.il_instruction is not None: line_buf[i].instrIndex = line.il_instruction.instr_index else: line_buf[i].instrIndex = 0xffffffffffffffff color = line.highlight if not isinstance(color, HighlightStandardColor) and not isinstance(color, highlight.HighlightColor): raise ValueError("Specified color is not one of HighlightStandardColor, highlight.HighlightColor") 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 = function.InstructionTextToken.get_instruction_lines(line.tokens) core.BNSetFlowGraphNodeLines(self.handle, line_buf, len(lines))
def get_choice_input(prompt, title, choices): """ ``get_choice_input`` prompts the user to select the one of the provided choices. Note: This API function differently on the command-line vs the UI. In the UI a pop-up is used. On the command-line a simple text prompt is used. The UI uses a combo box. :param str prompt: String to prompt with. :param str title: Title of the window when executed in the UI. :param list choices: A list of strings for the user to choose from. :rtype: integer array index of the selected option :Example: >>> get_choice_input("PROMPT>", "choices", ["Yes", "No", "Maybe"]) choices 1) Yes 2) No 3) Maybe PROMPT> 1 0L """ choice_buf = (ctypes.c_char_p * len(choices))() for i in range(0, len(choices)): choice_buf[i] = str(choices[i]).encode('charmap') value = ctypes.c_ulonglong() if not core.BNGetChoiceInput(value, prompt, title, choice_buf, len(choices)): return None return value.value
def outgoing_edges(self): """Flow graph block list of outgoing edges (read-only)""" count = ctypes.c_ulonglong() edges = core.BNGetFlowGraphNodeOutgoingEdges(self.handle, count) result = [] for i in range(0, count.value): branch_type = BranchType(edges[i].type) target = edges[i].target if target: target = FlowGraphNode(self.graph, core.BNNewFlowGraphNodeReference(target)) points = [] for j in range(0, edges[i].pointCount): points.append((edges[i].points[j].x, edges[i].points[j].y)) result.append(FlowGraphEdge(branch_type, self, target, points, edges[i].backEdge)) core.BNFreeFlowGraphNodeOutgoingEdgeList(edges, count.value) return result
def preprocess_source(source, filename=None, include_dirs=[]): """ ``preprocess_source`` run the C preprocessor on the given source or source filename. :param str source: source to pre-process :param str filename: optional filename to pre-process :param list(str) include_dirs: list of string directories to use as include directories. :return: returns a tuple of (preprocessed_source, error_string) :rtype: tuple(str,str) :Example: >>> source = "#define TEN 10\\nint x[TEN];\\n" >>> preprocess_source(source) ('#line 1 "input"\\n\\n#line 2 "input"\\n int x [ 10 ] ;\\n', '') >>> """ if filename is None: filename = "input" dir_buf = (ctypes.c_char_p * len(include_dirs))() for i in range(0, len(include_dirs)): dir_buf[i] = include_dirs[i].encode('charmap') output = ctypes.c_char_p() errors = ctypes.c_char_p() result = core.BNPreprocessSource(source, filename, output, errors, dir_buf, len(include_dirs)) output_str = output.value error_str = errors.value core.BNFreeString(ctypes.cast(output, ctypes.POINTER(ctypes.c_byte))) core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) if result: return (output_str, error_str) return (None, error_str)
def get_disassembly_text(self, settings=None): """ ``get_disassembly_text`` returns a list of binaryninja.function.DisassemblyTextLine objects for the current basic block. :param DisassemblySettings settings: (optional) DisassemblySettings object :Example: >>> current_basic_block.get_disassembly_text() [<0x100000f30: _main:>, <0x100000f30: push rbp>, ... ] """ settings_obj = None if settings: settings_obj = settings.handle count = ctypes.c_ulonglong() lines = core.BNGetBasicBlockDisassemblyText(self.handle, settings_obj, count) result = [] for i in range(0, count.value): addr = lines[i].addr if (lines[i].instrIndex != 0xffffffffffffffff) and hasattr(self, 'il_function'): il_instr = self.il_function[lines[i].instrIndex] else: il_instr = None color = highlight.HighlightColor._from_core_struct(lines[i].highlight) 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
def _get_core_struct(self): result = core.BNNameSpace() name_list = (ctypes.c_char_p * len(self.name))() for i in range(0, len(self.name)): name_list[i] = self.name[i].encode('charmap') result.name = name_list result.nameCount = len(self.name) return result
def get_ssa_memory_uses(self, version): count = ctypes.c_ulonglong() instrs = core.BNGetMediumLevelILSSAMemoryUses(self.handle, version, count) result = [] for i in range(0, count.value): result.append(instrs[i]) core.BNFreeILInstructionList(instrs) return result
def _fill_core_struct(self, value): value.type = FormInputFieldType.ChoiceFormField value.prompt = self.prompt choice_buf = (ctypes.c_char_p * len(self.choices))() for i in range(0, len(self.choices)): choice_buf[i] = self.choices[i].encode('charmap') value.choices = choice_buf value.count = len(self.choices)
def parse_types_from_source(self, source, filename=None, include_dirs=[], auto_type_source=None): """ ``parse_types_from_source`` parses the source string and any needed headers searching for them in the optional list of directories provided in ``include_dirs``. :param str source: source string to be parsed :param str filename: optional source filename :param list(str) include_dirs: optional list of string filename include directories :param str auto_type_source: optional source of types if used for automatically generated types :return: :py:class:`TypeParserResult` (a SyntaxError is thrown on parse error) :rtype: TypeParserResult :Example: >>> platform.parse_types_from_source('int foo;\\nint bar(int x);\\nstruct bas{int x,y;};\\n') ({types: {'bas': <type: struct bas>}, variables: {'foo': <type: int32_t>}, functions:{'bar': <type: int32_t(int32_t x)>}}, '') >>> """ if filename is None: filename = "input" dir_buf = (ctypes.c_char_p * len(include_dirs))() for i in range(0, len(include_dirs)): dir_buf[i] = include_dirs[i].encode('charmap') parse = core.BNTypeParserResult() errors = ctypes.c_char_p() result = core.BNParseTypesFromSource(self.handle, source, filename, parse, errors, dir_buf, len(include_dirs), auto_type_source) error_str = errors.value core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) if not result: raise SyntaxError(error_str) type_dict = {} variables = {} functions = {} for i in range(0, parse.typeCount): name = types.QualifiedName._from_core_struct(parse.types[i].name) type_dict[name] = types.Type(core.BNNewTypeReference(parse.types[i].type), platform = self) for i in range(0, parse.variableCount): name = types.QualifiedName._from_core_struct(parse.variables[i].name) variables[name] = types.Type(core.BNNewTypeReference(parse.variables[i].type), platform = self) for i in range(0, parse.functionCount): name = types.QualifiedName._from_core_struct(parse.functions[i].name) functions[name] = types.Type(core.BNNewTypeReference(parse.functions[i].type), platform = self) core.BNFreeTypeParserResult(parse) return types.TypeParserResult(type_dict, variables, functions)
def get_nodes_in_region(self, left, top, right, bottom): count = ctypes.c_ulonglong() nodes = core.BNGetFlowGraphNodesInRegion(self.handle, left, top, right, bottom, count) result = [] for i in range(0, count.value): result.append(FlowGraphNode(self, core.BNNewFlowGraphNodeReference(nodes[i]))) core.BNFreeFlowGraphNodeList(nodes, count.value) return result
def __iter__(self): count = ctypes.c_ulonglong() nodes = core.BNGetFlowGraphNodes(self.handle, count) try: for i in range(0, count.value): yield FlowGraphNode(self, core.BNNewFlowGraphNodeReference(nodes[i])) finally: core.BNFreeFlowGraphNodeList(nodes, count.value)
def nodes(self): """List of nodes in graph (read-only)""" count = ctypes.c_ulonglong() blocks = core.BNGetFlowGraphNodes(self.handle, count) result = [] for i in range(0, count.value): result.append(FlowGraphNode(self, core.BNNewFlowGraphNodeReference(blocks[i]))) core.BNFreeFlowGraphNodeList(blocks, count.value) return result
def repositories(self): """List of Repository objects being managed""" result = [] count = ctypes.c_ulonglong(0) repos = core.BNRepositoryManagerGetRepositories(self.handle, count) for i in range(count.value): result.append(Repository(handle=repos[i])) core.BNFreeRepositoryManagerRepositoriesList(repos) return result
def plugin_types(self): """List of PluginType enumeration objects indicating the plugin type(s)""" result = [] count = ctypes.c_ulonglong(0) plugintypes = core.BNPluginGetPluginTypes(self.handle, count) for i in range(count.value): result.append(PluginType(plugintypes[i])) core.BNFreePluginTypes(plugintypes) return result
def __iter__(self): binaryninja._init_plugins() count = ctypes.c_ulonglong() platforms = core.BNGetPlatformList(count) try: for i in range(0, count.value): yield Platform(None, core.BNNewPlatformReference(platforms[i])) finally: core.BNFreePlatformList(platforms, count.value)
def dominance_frontier(self): """Dominance frontier for this basic block (read-only)""" count = ctypes.c_ulonglong() blocks = core.BNGetBasicBlockDominanceFrontier(self.handle, count) result = [] for i in range(0, count.value): result.append(self._create_instance(self.view, core.BNNewBasicBlockReference(blocks[i]))) core.BNFreeBasicBlockList(blocks, count.value) return result
def list(self): binaryninja._init_plugins() count = ctypes.c_ulonglong() platforms = core.BNGetPlatformList(count) result = [] for i in range(0, count.value): result.append(Platform(None, core.BNNewPlatformReference(platforms[i]))) core.BNFreePlatformList(platforms, count.value) return result
def branch_dependence(self): """Set of branching instructions that must take the true or false path to reach this instruction""" count = ctypes.c_ulonglong() deps = core.BNGetAllMediumLevelILBranchDependence(self.function.handle, self.instr_index, count) result = {} for i in range(0, count.value): result[deps[i].branch] = ILBranchDependence(deps[i].dependence) core.BNFreeILBranchDependenceList(deps) return result
def members(self): """Enumeration member list (read-only)""" count = ctypes.c_ulonglong() members = core.BNGetEnumerationMembers(self.handle, count) result = [] for i in range(0, count.value): result.append(EnumerationMember(members[i].name, members[i].value, members[i].isDefault)) core.BNFreeEnumerationMemberList(members, count.value) return result
def os_list(self): binaryninja._init_plugins() count = ctypes.c_ulonglong() platforms = core.BNGetPlatformOSList(count) result = [] for i in range(0, count.value): result.append(str(platforms[i])) core.BNFreePlatformOSList(platforms, count.value) return result
def __iter__(self): binaryninja._init_plugins() count = ctypes.c_ulonglong() xforms = core.BNGetTransformTypeList(count) try: for i in range(0, count.value): yield Transform(xforms[i]) finally: core.BNFreeTransformTypeList(xforms)
def list(self): binaryninja._init_plugins() count = ctypes.c_ulonglong() xforms = core.BNGetTransformTypeList(count) result = [] for i in range(0, count.value): result.append(Transform(xforms[i])) core.BNFreeTransformTypeList(xforms) return result
def list(self): binaryninja._init_plugins() count = ctypes.c_ulonglong() commands = core.BNGetAllPluginCommands(count) result = [] for i in range(0, count.value): result.append(PluginCommand(commands[i])) core.BNFreePluginCommandList(commands) return result
def list(self): """List all running background tasks (read-only)""" count = ctypes.c_ulonglong() tasks = core.BNGetRunningBackgroundTasks(count) result = [] for i in range(0, count.value): result.append(BackgroundTask(handle=core.BNNewBackgroundTaskReference(tasks[i]))) core.BNFreeBackgroundTaskList(tasks, count.value) return result
def __iter__(self): binaryninja._init_plugins() count = ctypes.c_ulonglong() tasks = core.BNGetRunningBackgroundTasks(count) try: for i in range(0, count.value): yield BackgroundTask(handle=core.BNNewBackgroundTaskReference(tasks[i])) finally: core.BNFreeBackgroundTaskList(tasks, count.value)
def __iter__(self): binaryninja._init_plugins() count = ctypes.c_ulonglong() commands = core.BNGetAllPluginCommands(count) try: for i in range(0, count.value): yield PluginCommand(commands[i]) finally: core.BNFreePluginCommandList(commands)
def keys(self): """ ``keys`` retrieve the list of setting identifiers in the active settings schema :return: list of setting identifiers :rtype: list(str) """ length = ctypes.c_ulonglong() result = core.BNSettingsKeysList(self.handle, ctypes.byref(length)) out_list = [] for i in range(length.value): out_list.append(pyNativeStr(result[i])) core.BNFreeStringList(result, length) return out_list
def set_string_list(self, id, value, view=None, scope=SettingsScope.SettingsAutoScope): if view is not None: view = view.handle length = ctypes.c_ulonglong() length.value = len(value) string_list = (ctypes.c_char_p * len(value))() for i in range(len(value)): string_list[i] = value[i].encode('charmap') return core.BNSettingsSetStringList(self.registry_id, view, scope, id, string_list, length)
def add_operand_list(self, operands): """ ``add_operand_list`` returns an operand list expression for the given list of integer operands. :param list(int) operands: list of operand numbers :return: an operand list expression :rtype: HighLevelILExpr """ operand_list = (ctypes.c_ulonglong * len(operands))() for i in range(len(operands)): operand_list[i] = operands[i] return HighLevelILExpr( core.BNHighLevelILAddOperandList(self.handle, operand_list, len(operands)))
def demangle_gnu3(arch, mangled_name): handle = ctypes.POINTER(core.BNType)() outName = ctypes.POINTER(ctypes.c_char_p)() outSize = ctypes.c_ulonglong() names = [] if core.BNDemangleGNU3(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize)): for i in range(outSize.value): names.append(pyNativeStr(outName[i])) core.BNFreeDemangledName(ctypes.byref(outName), outSize.value) if not handle: return (None, names) return (types.Type(handle), names) return (None, mangled_name)
def _get_float_arg_regs(self, ctxt, count): try: regs = self.__class__.float_arg_regs count[0] = len(regs) reg_buf = (ctypes.c_uint * len(regs))() for i in range(0, len(regs)): reg_buf[i] = self.arch.regs[regs[i]].index result = ctypes.cast(reg_buf, ctypes.c_void_p) self._pending_reg_lists[result.value] = (result, reg_buf) return result.value except: log.log_error(traceback.format_exc()) count[0] = 0 return None
def incoming_edges(self): """List of basic block incoming edges (read-only)""" count = ctypes.c_ulonglong(0) edges = core.BNGetBasicBlockIncomingEdges(self.handle, count) result = [] for i in range(0, count.value): branch_type = BranchType(edges[i].type) if edges[i].target: target = self._create_instance(core.BNNewBasicBlockReference(edges[i].target), self.view) else: target = None result.append(BasicBlockEdge(branch_type, target, self, edges[i].backEdge, edges[i].fallThrough)) core.BNFreeBasicBlockEdgeList(edges, count.value) return result
def request(self, method, url, headers=None, data=None, json=None): if headers is None: headers = {} if data is None and json is None: data = b'' elif data is None and json is not None: data = to_bytes(dumps(json)) if "Content-Type" not in headers: headers["Content-Type"] = "application/json" elif data is not None and json is None: if type(data) == dict: # Urlencode data as a form body data = to_bytes(urlencode(data)) if "Content-Type" not in headers: headers["Content-Type"] = "application/x-www-form-urlencoded" else: assert(type(data) == bytes) self._data = data if len(data) > 0 and "Content-Length" not in headers: headers["Content-Length"] = len(data) if "Content-Type" not in headers: headers["Content-Type"] = "application/octet-stream" callbacks = core.BNDownloadInstanceInputOutputCallbacks() callbacks.readCallback = callbacks.readCallback.__class__(self._read_callback) callbacks.writeCallback = callbacks.writeCallback.__class__(self._write_callback) callbacks.readContext = 0 callbacks.writeContext = 0 callbacks.progressContext = 0 self._response = b"" header_keys = (ctypes.c_char_p * len(headers))() header_values = (ctypes.c_char_p * len(headers))() for (i, item) in enumerate(headers.items()): key, value = item header_keys[i] = to_bytes(key) header_values[i] = to_bytes(value) response = ctypes.POINTER(core.BNDownloadInstanceResponse)() result = core.BNPerformCustomRequest(self.handle, method, url, len(headers), header_keys, header_values, response, callbacks) if result != 0: return None response_headers = {} for i in range(response.contents.headerCount): response_headers[response.contents.headerKeys[i]] = response.contents.headerValues[i] return DownloadInstance.Response(response.contents.statusCode, response_headers, self._response)
def encode(self, input_buf, params={}): if isinstance(input_buf, int) or isinstance(input_buf, long): return None input_buf = databuffer.DataBuffer(input_buf) output_buf = databuffer.DataBuffer() keys = list(params.keys()) param_buf = (core.BNTransformParameter * len(keys))() for i in range(0, len(keys)): data = databuffer.DataBuffer(params[keys[i]]) param_buf[i].name = keys[i] param_buf[i].value = data.handle if not core.BNEncode(self.handle, input_buf.handle, output_buf.handle, param_buf, len(keys)): return None return str(output_buf)
def encode(self, input_buf, params = {}): if isinstance(input_buf, int) or isinstance(input_buf, numbers.Integral): return None input_buf = databuffer.DataBuffer(input_buf) output_buf = databuffer.DataBuffer() keys = list(params.keys()) param_buf = (core.BNTransformParameter * len(keys))() data = [] for i in range(0, len(keys)): data.append(databuffer.DataBuffer(params[keys[i]])) param_buf[i].name = keys[i] param_buf[i].value = data[i].handle if not core.BNEncode(self.handle, input_buf.handle, output_buf.handle, param_buf, len(keys)): return None return bytes(output_buf)
def get_list(cls, os=None, arch=None): binaryninja._init_plugins() count = ctypes.c_ulonglong() if os is None: platforms = core.BNGetPlatformList(count) elif arch is None: platforms = core.BNGetPlatformListByOS(os) else: platforms = core.BNGetPlatformListByArchitecture(os, arch.handle) result = [] for i in range(0, count.value): result.append( Platform(handle=core.BNNewPlatformReference(platforms[i]))) core.BNFreePlatformList(platforms, count.value) return result
def platform_names(self): """ Returns a list of all platform names that this type library will register with during platform type registration. This returns strings, not Platform objects, as type libraries can be distributed with support for Platforms that may not be present. """ count = ctypes.c_ulonglong(0) result = [] platforms = core.BNGetTypeLibraryPlatforms(self.handle, count) for i in range(0, count.value): result.append(platforms[i]) core.BNFreeStringList(platforms, count.value) return result
def __iter__(self): count = ctypes.c_ulonglong() lines = core.BNGetFlowGraphNodeLines(self.handle, count) block = self.basic_block try: for i in range(0, count.value): addr = lines[i].addr if (lines[i].instrIndex != 0xffffffffffffffff) and (block is not None) and hasattr(block, 'il_function'): il_instr = block.il_function[lines[i].instrIndex] else: il_instr = None 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)
def basic_blocks(self): """list of HighLevelILBasicBlock objects (read-only)""" count = ctypes.c_ulonglong() blocks = core.BNGetHighLevelILBasicBlockList(self.handle, count) result = [] view = None if self._source_function is not None: view = self._source_function.view for i in range(0, count.value): result.append( HighLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self)) core.BNFreeBasicBlockList(blocks, count.value) return result
def members(self): """Structure member list (read-only)""" count = ctypes.c_ulonglong() if self._mutable: members = core.BNGetStructureBuilderMembers(self._handle, count) else: members = core.BNGetStructureMembers(self._handle, count) try: result = [] for i in range(0, count.value): result.append(StructureMember(Type(core.BNNewTypeReference(members[i].type), confidence=members[i].typeConfidence), members[i].name, members[i].offset)) finally: core.BNFreeStructureMemberList(members, count.value) return result
def __str__(self): if self.is_string: return str(core.BNMetadataGetString(self.handle)) if self.is_raw: length = ctypes.c_ulonglong() length.value = 0 native_list = core.BNMetadataGetRaw(self.handle, ctypes.byref(length)) out_list = [] for i in range(length.value): out_list.append(native_list[i]) core.BNFreeMetadataRaw(native_list) return ''.join(chr(a) for a in out_list) raise ValueError("Metadata object not a string or raw type")
def _get_parameters(self, ctxt, count): try: count[0] = len(self.parameters) param_buf = (core.BNTransformParameterInfo * len(self.parameters))() for i in range(0, len(self.parameters)): param_buf[i].name = self.parameters[i].name param_buf[i].longName = self.parameters[i].long_name param_buf[i].fixedLength = self.parameters[i].fixed_length result = ctypes.cast(param_buf, ctypes.c_void_p) self._pending_param_lists[result.value] = (result, param_buf) return result.value except: log.log_error(traceback.format_exc()) count[0] = 0 return None
def latest_version(self): """Latest version (read-only)""" count = ctypes.c_ulonglong() errors = ctypes.c_char_p() versions = core.BNGetUpdateChannelVersions(self.name, count, errors) if errors: error_str = errors.value core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) raise IOError(error_str) result = None for i in range(0, count.value): if versions[i].version == self.latest_version_num: result = UpdateVersion(self, versions[i].version, versions[i].notes, versions[i].time) break core.BNFreeUpdateChannelVersionList(versions, count.value) return result
def lines(self): """HLIL text lines (read-only)""" count = ctypes.c_ulonglong() lines = core.BNGetHighLevelILExprText(self._function.handle, self._expr_index, self._as_ast, count, None) result = [] for i in range(0, count.value): addr = lines[i].addr if lines[i].instrIndex != 0xffffffffffffffff: il_instr = self._function[lines[i].instrIndex] else: il_instr = None color = binaryninja.highlight.HighlightColor._from_core_struct(lines[i].highlight) 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
def calling_conventions(self): """ List of platform CallingConvention objects (read-only) :getter: returns the list of supported CallingConvention objects :type: list(CallingConvention) """ count = ctypes.c_ulonglong() cc = core.BNGetPlatformCallingConventions(self.handle, count) result = [] for i in range(0, count.value): result.append( binaryninja.callingconvention.CallingConvention( handle=core.BNNewCallingConventionReference(cc[i]))) core.BNFreeCallingConventionList(cc, count.value) return result
def __iter__(self): binaryninja._init_plugins() count = ctypes.c_ulonglong() errors = ctypes.c_char_p() channels = core.BNGetUpdateChannels(count, errors) if errors: error_str = errors.value core.BNFreeString( ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) raise IOError(error_str) try: for i in range(0, count.value): yield UpdateChannel(channels[i].name, channels[i].description, channels[i].latestVersion) finally: core.BNFreeUpdateChannelList(channels, count.value)
def get_string_list_with_scope(self, key, view=None, scope=SettingsScope.SettingsAutoScope): if view is not None: view = view.handle c_scope = core.SettingsScopeEnum(scope) length = ctypes.c_ulonglong() result = core.BNSettingsGetStringList(self.handle, key, view, ctypes.byref(c_scope), ctypes.byref(length)) out_list = [] for i in range(length.value): out_list.append(pyNativeStr(result[i])) core.BNFreeStringList(result, length) return (out_list, SettingsScope(c_scope.value))
def _encode(self, ctxt, input_buf, output_buf, params, count): try: input_obj = databuffer.DataBuffer(handle = core.BNDuplicateDataBuffer(input_buf)) param_map = {} for i in range(0, count): data = databuffer.DataBuffer(handle = core.BNDuplicateDataBuffer(params[i].value)) param_map[params[i].name] = str(data) result = self.perform_encode(str(input_obj), param_map) if result is None: return False result = str(result) core.BNSetDataBufferContents(output_buf, result, len(result)) return True except: log.log_error(traceback.format_exc()) return False
def lines(self): """Flow graph block list of text lines""" count = ctypes.c_ulonglong() lines = core.BNGetFlowGraphNodeLines(self.handle, count) block = self.basic_block result = [] for i in range(0, count.value): addr = lines[i].addr if (lines[i].instrIndex != 0xffffffffffffffff) and (block is not None) and hasattr(block, 'il_function'): il_instr = block.il_function[lines[i].instrIndex] else: il_instr = None color = highlight.HighlightColor._from_core_struct(lines[i].highlight) 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
def list(self): binaryninja._init_plugins() count = ctypes.c_ulonglong() errors = ctypes.c_char_p() channels = core.BNGetUpdateChannels(count, errors) if errors: error_str = errors.value core.BNFreeString( ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) raise IOError(error_str) result = [] for i in range(0, count.value): result.append( UpdateChannel(channels[i].name, channels[i].description, channels[i].latestVersion)) core.BNFreeUpdateChannelList(channels, count.value) return result
def versions(self): """List of versions (read-only)""" count = ctypes.c_ulonglong() errors = ctypes.c_char_p() versions = core.BNGetUpdateChannelVersions(self.name, count, errors) if errors: error_str = errors.value core.BNFreeString( ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) raise IOError(error_str) result = [] for i in range(0, count.value): result.append( UpdateVersion(self, versions[i].version, versions[i].notes, versions[i].time)) core.BNFreeUpdateChannelVersionList(versions, count.value) return result
def __getitem__(cls, name): binaryninja._init_plugins() count = ctypes.c_ulonglong() errors = ctypes.c_char_p() channels = core.BNGetUpdateChannels(count, errors) if errors: error_str = errors.value core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte))) raise IOError(error_str) result = None for i in range(0, count.value): if channels[i].name == str(name): result = UpdateChannel(channels[i].name, channels[i].description, channels[i].latestVersion) break core.BNFreeUpdateChannelList(channels, count.value) if result is None: raise KeyError("'%s' is not a valid channel" % str(name)) return result
def _perform_custom_request(self, ctxt, method, url, header_count, header_keys, header_values, response): # Cast response to an array of length 1 so ctypes can write to the pointer # out_response = ((BNDownloadInstanceResponse*)[1])response out_response = (ctypes.POINTER(core.BNDownloadInstanceResponse) * 1).from_address(ctypes.addressof(response.contents)) try: # Extract headers keys_ptr = ctypes.cast(header_keys, ctypes.POINTER(ctypes.c_char_p)) values_ptr = ctypes.cast(header_values, ctypes.POINTER(ctypes.c_char_p)) header_key_array = (ctypes.c_char_p * header_count).from_address(ctypes.addressof(keys_ptr.contents)) header_value_array = (ctypes.c_char_p * header_count).from_address(ctypes.addressof(values_ptr.contents)) headers = {} for i in range(header_count): headers[header_key_array[i]] = header_value_array[i] # Read all data data = b'' while True: read_buffer = ctypes.create_string_buffer(0x1000) read_len = core.BNReadDataForDownloadInstance(self.handle, ctypes.cast(read_buffer, ctypes.POINTER(ctypes.c_uint8)), 0x1000) if read_len == 0: break data += read_buffer[:read_len] py_response = self.perform_custom_request(method, url, headers, data) if py_response is not None: # Assign to an instance variable so the memory stays live until the request is done self.bn_response = core.BNDownloadInstanceResponse() self.bn_response.statusCode = py_response.status_code self.bn_response.headerCount = len(py_response.headers) self.bn_response.headerKeys = (ctypes.c_char_p * len(py_response.headers))() self.bn_response.headerValues = (ctypes.c_char_p * len(py_response.headers))() for i, (key, value) in enumerate(py_response.headers.items()): self.bn_response.headerKeys[i] = core.BNAllocString(pyNativeStr(key)) self.bn_response.headerValues[i] = core.BNAllocString(pyNativeStr(value)) out_response[0] = ctypes.pointer(self.bn_response) else: out_response[0] = None return 0 if py_response is not None else -1 except: out_response[0] = None log.log_error(traceback.format_exc()) return -1
def parameters(self): """Type parameters list (read-only)""" count = ctypes.c_ulonglong() params = core.BNGetTypeParameters(self.handle, count) result = [] for i in range(0, count.value): param_type = Type(core.BNNewTypeReference(params[i].type), platform = self.platform, confidence = params[i].typeConfidence) if params[i].defaultLocation: param_location = None else: name = params[i].name if (params[i].location.type == VariableSourceType.RegisterVariableSourceType) and (self.platform is not None): name = self.platform.arch.get_reg_name(params[i].location.storage) elif params[i].location.type == VariableSourceType.StackVariableSourceType: name = "arg_%x" % params[i].location.storage param_location = binaryninja.function.Variable(None, params[i].location.type, params[i].location.index, params[i].location.storage, name, param_type) result.append(FunctionParameter(param_type, params[i].name, param_location)) core.BNFreeTypeParameterList(params, count.value) return result
def lines(self, lines): if isinstance(lines, str): lines = lines.split('\n') line_buf = (core.BNDisassemblyTextLine * len(lines))() for i in range(0, len(lines)): line = lines[i] if isinstance(line, str): line = function.DisassemblyTextLine([ function.InstructionTextToken( InstructionTextTokenType.TextToken, line) ]) if not isinstance(line, function.DisassemblyTextLine): line = function.DisassemblyTextLine(line) if line.address is None: if len(line.tokens) > 0: line_buf[i].addr = line.tokens[0].address else: line_buf[i].addr = 0 else: line_buf[i].addr = line.address if line.il_instruction is not None: line_buf[i].instrIndex = line.il_instruction.instr_index else: line_buf[i].instrIndex = 0xffffffffffffffff color = line.highlight if not isinstance(color, HighlightStandardColor) and not isinstance( color, highlight.HighlightColor): raise ValueError( "Specified color is not one of HighlightStandardColor, highlight.HighlightColor" ) 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 = function.InstructionTextToken.get_instruction_lines( line.tokens) core.BNSetFlowGraphNodeLines(self.handle, line_buf, len(lines))
def get_tokens_after_name(self, base_confidence=max_confidence): count = ctypes.c_ulonglong() platform = None 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) return result