diff options
Diffstat (limited to 'python/binaryview.py')
| -rw-r--r-- | python/binaryview.py | 252 |
1 files changed, 246 insertions, 6 deletions
diff --git a/python/binaryview.py b/python/binaryview.py index 193cf8b4..cbfc47ef 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -3207,18 +3207,21 @@ class BinaryView(object): return None return DataVariable(var.address, types.Type(var.type, platform = self.platform, confidence = var.typeConfidence), var.autoDiscovered, self) - def get_functions_containing(self, addr): + def get_functions_containing(self, addr, plat=None): """ ``get_functions_containing`` returns a list of functions which contain the given address. :param int addr: virtual address to query. :rtype: list of Function objects """ - basic_blocks = self.get_basic_blocks_at(addr) - + count = ctypes.c_ulonglong(0) + funcs = core.BNGetAnalysisFunctionsContainingAddress(self.handle, addr, count) result = [] - for block in basic_blocks: - result.append(block.function) + for i in range(0, count.value): + result.append(binaryninja.function.Function(self, core.BNNewFunctionReference(funcs[i]))) + core.BNFreeFunctionList(funcs, count.value) + if not plat is None: + result = [func for func in result in func.platform == plat] return result def get_function_at(self, addr, plat=None): @@ -3359,6 +3362,7 @@ class BinaryView(object): :param int addr: virtual address to query for references :param int length: optional length of query + :param Architecture arch: optional architecture of query :return: list of integers :rtype: list(integer) """ @@ -3439,6 +3443,242 @@ class BinaryView(object): return result + def get_code_refs_for_type(self, name): + """ + ``get_code_refs_for_type`` returns a list of ReferenceSource objects (xrefs or cross-references) that reference the provided QualifiedName. + + :param QualifiedName name: name of type to query for references + :return: List of References for the given type + :rtype: list(ReferenceSource) + :Example: + + >>> bv.get_code_refs_for_type('A') + [<ref: x86@0x4165ff>] + >>> + + """ + count = ctypes.c_ulonglong(0) + name = types.QualifiedName(name)._get_core_struct() + refs = core.BNGetCodeReferencesForType(self.handle, name, count) + + result = [] + for i in range(0, count.value): + if refs[i].func: + func = binaryninja.function.Function(self, core.BNNewFunctionReference(refs[i].func)) + else: + func = None + if refs[i].arch: + arch = binaryninja.architecture.CoreArchitecture._from_cache(refs[i].arch) + else: + arch = None + addr = refs[i].addr + result.append(binaryninja.architecture.ReferenceSource(func, arch, addr)) + core.BNFreeCodeReferences(refs, count.value) + return result + + + def get_code_refs_for_type_field(self, name, offset): + """ + ``get_code_refs_for_type`` returns a list of ReferenceSource objects (xrefs or cross-references) that reference the provided type field. + + :param QualifiedName name: name of type to query for references + :param int offset: offset of the field, relative to the type + :return: List of References for the given type + :rtype: list(ReferenceSource) + :Example: + + >>> bv.get_code_refs_for_type_field('A', 0x8) + [<ref: x86@0x4165ff>] + >>> + + """ + count = ctypes.c_ulonglong(0) + name = types.QualifiedName(name)._get_core_struct() + refs = core.BNGetCodeReferencesForTypeField(self.handle, name, offset, count) + + result = [] + for i in range(0, count.value): + if refs[i].func: + func = binaryninja.function.Function(self, core.BNNewFunctionReference(refs[i].func)) + else: + func = None + if refs[i].arch: + arch = binaryninja.architecture.CoreArchitecture._from_cache(refs[i].arch) + else: + arch = None + addr = refs[i].addr + result.append(binaryninja.architecture.ReferenceSource(func, arch, addr)) + core.BNFreeCodeReferences(refs, count.value) + return result + + + def get_data_refs_for_type(self, name): + """ + ``get_data_refs_for_type`` returns a list of virtual addresses of data which references the type ``name``. + Note, the returned addresses are the actual start of the queried type. For example, suppose there is a DataVariable + at 0x1000 that has type A, and type A contians type B at offset 0x10. Then `get_data_refs_for_type('B')` will + return 0x1010 for it. + + :param QualifiedName name: name of type to query for references + :return: list of integers + :rtype: list(integer) + :Example: + + >>> bv.get_data_refs_for_type('A') + [4203812] + >>> + """ + count = ctypes.c_ulonglong(0) + name = types.QualifiedName(name)._get_core_struct() + refs = core.BNGetDataReferencesForType(self.handle, name, count) + + result = [] + for i in range(0, count.value): + result.append(refs[i]) + core.BNFreeDataReferences(refs, count.value) + return result + + + def get_data_refs_for_type_field(self, name, offset): + """ + ``get_data_refs_for_type_field`` returns a list of virtual addresses of data which references the type ``name``. + Note, the returned addresses are the actual start of the queried type field. For example, suppose there is a + DataVariable at 0x1000 that has type A, and type A contians type B at offset 0x10. + Then `get_data_refs_for_type_field('B', 0x8)` will return 0x1018 for it. + + :param QualifiedName name: name of type to query for references + :param int offset: offset of the field, relative to the type + :return: list of integers + :rtype: list(integer) + :Example: + + >>> bv.get_data_refs_for_type_field('A', 0x8) + [4203812] + >>> + """ + count = ctypes.c_ulonglong(0) + name = types.QualifiedName(name)._get_core_struct() + refs = core.BNGetDataReferencesForTypeField(self.handle, name, offset, count) + + result = [] + for i in range(0, count.value): + result.append(refs[i]) + core.BNFreeDataReferences(refs, count.value) + return result + + + def get_type_refs_for_type(self, name): + """ + ``get_type_refs_for_type`` returns a list of TypeReferenceSource objects (xrefs or cross-references) that reference the provided QualifiedName. + + :param QualifiedName name: name of type to query for references + :return: List of references for the given type + :rtype: list(TypeReferenceSource) + :Example: + + >>> bv.get_type_refs_for_type('A') + ['<type D, offset 0x8, direct>', '<type C, offset 0x10, indirect>'] + >>> + + """ + count = ctypes.c_ulonglong(0) + name = types.QualifiedName(name)._get_core_struct() + refs = core.BNGetTypeReferencesForType(self.handle, name, count) + + result = [] + for i in range(0, count.value): + type_field = types.TypeReferenceSource(types.QualifiedName._from_core_struct(refs[i].name), refs[i].offset, refs[i].type) + result.append(type_field) + core.BNFreeTypeReferences(refs, count.value) + return result + + + def get_type_refs_for_type_field(self, name, offset): + """ + ``get_type_refs_for_type`` returns a list of TypeReferenceSource objects (xrefs or cross-references) that reference the provided type field. + + :param QualifiedName name: name of type to query for references + :param int offset: offset of the field, relative to the type + :return: List of references for the given type + :rtype: list(TypeReferenceSource) + :Example: + + >>> bv.get_type_refs_for_type_field('A', 0x8) + ['<type D, offset 0x8, direct>', '<type C, offset 0x10, indirect>'] + >>> + + """ + count = ctypes.c_ulonglong(0) + name = types.QualifiedName(name)._get_core_struct() + refs = core.BNGetTypeReferencesForTypeField(self.handle, name, offset, count) + + result = [] + for i in range(0, count.value): + type_field = types.TypeReferenceSource(types.QualifiedName._from_core_struct(refs[i].name), refs[i].offset, refs[i].type) + result.append(type_field) + core.BNFreeTypeReferences(refs, count.value) + return result + + def get_code_refs_for_type_from(self, addr, func = None, arch = None, length = None): + """ + ``get_code_refs_for_type_from`` returns a list of types referenced by code in the function ``func``, + of the architecture ``arch``, and at the address ``addr``. If no function is specified, references from + all functions and containing the address will be returned. If no architecture is specified, the + architecture of the function will be used. + + :param int addr: virtual address to query for references + :param int length: optional length of query + :return: list of references + :rtype: list(TypeReferenceSource) + """ + result = [] + funcs = self.get_functions_containing(addr) if func is None else [func] + if not funcs: + return [] + for src_func in funcs: + src_arch = src_func.arch if arch is None else arch + ref_src = core.BNReferenceSource(src_func.handle, src_arch.handle, addr) + count = ctypes.c_ulonglong(0) + if length is None: + refs = core.BNGetCodeReferencesForTypeFrom(self.handle, ref_src, count) + else: + refs = core.BNGetCodeReferencesForTypeFromInRange(self.handle, ref_src, length, count) + for i in range(0, count.value): + type_field = types.TypeReferenceSource(types.QualifiedName._from_core_struct(refs[i].name), refs[i].offset, refs[i].type) + result.append(type_field) + core.BNFreeTypeReferences(refs, count.value) + return result + + def get_code_refs_for_type_fields_from(self, addr, func = None, arch = None, length = None): + """ + ``get_code_refs_for_type_fields_from`` returns a list of type fields referenced by code in the function ``func``, + of the architecture ``arch``, and at the address ``addr``. If no function is specified, references from + all functions and containing the address will be returned. If no architecture is specified, the + architecture of the function will be used. + + :param int addr: virtual address to query for references + :param int length: optional length of query + :return: list of references + :rtype: list(TypeReferenceSource) + """ + result = [] + funcs = self.get_functions_containing(addr) if func is None else [func] + if not funcs: + return [] + for src_func in funcs: + src_arch = src_func.arch if arch is None else arch + ref_src = core.BNReferenceSource(src_func.handle, src_arch.handle, addr) + count = ctypes.c_ulonglong(0) + if length is None: + refs = core.BNGetCodeReferencesForTypeFieldsFrom(self.handle, ref_src, count) + else: + refs = core.BNGetCodeReferencesForTypeFieldsFromInRange(self.handle, ref_src, length, count) + for i in range(0, count.value): + type_field = types.TypeReferenceSource(types.QualifiedName._from_core_struct(refs[i].name), refs[i].offset, refs[i].type) + result.append(type_field) + core.BNFreeTypeReferences(refs, count.value) + return result + def add_user_data_ref(self, from_addr, to_addr): """ ``add_user_data_ref`` adds a user-specified data cross-reference (xref) from the address ``from_addr`` to the address ``to_addr``. @@ -5467,7 +5707,7 @@ class BinaryView(object): For annotating code, it is recommended to use comments attached to functions rather than address comments attached to the BinaryView. On the other hand, BinaryView comments can be attached to data whereas function comments cannot. - To create a function-level comment, use :func:`~binaryninja.function.Function.add_user_code_ref`. + To create a function-level comment, use :func:`~binaryninja.function.Function.set_comment_at`. """ count = ctypes.c_ulonglong() addrs = core.BNGetGlobalCommentedAddresses(self.handle, count) |
