diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/architecture.py | 18 | ||||
| -rw-r--r-- | python/basicblock.py | 160 | ||||
| -rw-r--r-- | python/binaryview.py | 685 | ||||
| -rw-r--r-- | python/debuginfo.py | 135 | ||||
| -rw-r--r-- | python/lowlevelil.py | 129 |
5 files changed, 640 insertions, 487 deletions
diff --git a/python/architecture.py b/python/architecture.py index f77778bc..46f21f88 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -499,9 +499,11 @@ class Architecture(metaclass=_ArchitectureMetaClass): regs = core.BNGetFullWidthArchitectureRegisters(self.handle, count) assert regs is not None, "core.BNGetFullWidthArchitectureRegisters returned None" result = [] - for i in range(0, count.value): - result.append(core.BNGetArchitectureRegisterName(self.handle, regs[i])) - core.BNFreeRegisterList(regs) + try: + for i in range(0, count.value): + result.append(core.BNGetArchitectureRegisterName(self.handle, regs[i])) + finally: + core.BNFreeRegisterList(regs) return result @property @@ -511,10 +513,12 @@ class Architecture(metaclass=_ArchitectureMetaClass): cc = core.BNGetArchitectureCallingConventions(self.handle, count) assert cc is not None, "core.BNGetArchitectureCallingConventions returned None" result = {} - for i in range(0, count.value): - obj = callingconvention.CallingConvention(handle=core.BNNewCallingConventionReference(cc[i])) - result[obj.name] = obj - core.BNFreeCallingConventionList(cc, count) + try: + for i in range(0, count.value): + obj = callingconvention.CallingConvention(handle=core.BNNewCallingConventionReference(cc[i])) + result[obj.name] = obj + finally: + core.BNFreeCallingConventionList(cc, count) return result @property diff --git a/python/basicblock.py b/python/basicblock.py index 6d67c91b..3e54b867 100644 --- a/python/basicblock.py +++ b/python/basicblock.py @@ -227,14 +227,16 @@ class BasicBlock: edges = core.BNGetBasicBlockOutgoingEdges(self.handle, count) assert edges is not None, "core.BNGetBasicBlockOutgoingEdges returned None" result = [] - for i in range(0, count.value): - branch_type = BranchType(edges[i].type) - handle = core.BNNewBasicBlockReference(edges[i].target) - assert handle is not None - target = self._create_instance(handle, self.view) - result.append(BasicBlockEdge(branch_type, self, target, edges[i].backEdge, edges[i].fallThrough)) - core.BNFreeBasicBlockEdgeList(edges, count.value) - return result + try: + for i in range(0, count.value): + branch_type = BranchType(edges[i].type) + handle = core.BNNewBasicBlockReference(edges[i].target) + assert handle is not None + target = self._create_instance(handle, self.view) + result.append(BasicBlockEdge(branch_type, self, target, edges[i].backEdge, edges[i].fallThrough)) + return result + finally: + core.BNFreeBasicBlockEdgeList(edges, count.value) @property def incoming_edges(self) -> List[BasicBlockEdge]: @@ -246,14 +248,16 @@ class BasicBlock: edges = core.BNGetBasicBlockIncomingEdges(self.handle, count) assert edges is not None, "core.BNGetBasicBlockIncomingEdges returned None" result = [] - for i in range(0, count.value): - branch_type = BranchType(edges[i].type) - handle = core.BNNewBasicBlockReference(edges[i].target) - assert handle is not None - target = self._create_instance(handle, self.view) - result.append(BasicBlockEdge(branch_type, target, self, edges[i].backEdge, edges[i].fallThrough)) - core.BNFreeBasicBlockEdgeList(edges, count.value) - return result + try: + for i in range(0, count.value): + branch_type = BranchType(edges[i].type) + handle = core.BNNewBasicBlockReference(edges[i].target) + assert handle is not None + target = self._create_instance(handle, self.view) + result.append(BasicBlockEdge(branch_type, target, self, edges[i].backEdge, edges[i].fallThrough)) + return result + finally: + core.BNFreeBasicBlockEdgeList(edges, count.value) @property def has_undetermined_outgoing_edges(self) -> bool: @@ -284,12 +288,14 @@ class BasicBlock: blocks = core.BNGetBasicBlockDominators(self.handle, count, False) assert blocks is not None, "core.BNGetBasicBlockDominators returned None" result = [] - for i in range(0, count.value): - handle = core.BNNewBasicBlockReference(blocks[i]) - assert handle is not None - result.append(self._create_instance(handle, self.view)) - core.BNFreeBasicBlockList(blocks, count.value) - return result + try: + for i in range(0, count.value): + handle = core.BNNewBasicBlockReference(blocks[i]) + assert handle is not None + result.append(self._create_instance(handle, self.view)) + return result + finally: + core.BNFreeBasicBlockList(blocks, count.value) @property def post_dominators(self) -> List['BasicBlock']: @@ -300,12 +306,14 @@ class BasicBlock: blocks = core.BNGetBasicBlockDominators(self.handle, count, True) assert blocks is not None, "core.BNGetBasicBlockDominators returned None" result = [] - for i in range(0, count.value): - handle = core.BNNewBasicBlockReference(blocks[i]) - assert handle is not None, "core.BNNewBasicBlockReference returned None" - result.append(self._create_instance(handle, self.view)) - core.BNFreeBasicBlockList(blocks, count.value) - return result + try: + for i in range(0, count.value): + handle = core.BNNewBasicBlockReference(blocks[i]) + assert handle is not None, "core.BNNewBasicBlockReference returned None" + result.append(self._create_instance(handle, self.view)) + return result + finally: + core.BNFreeBasicBlockList(blocks, count.value) @property def strict_dominators(self) -> List['BasicBlock']: @@ -316,12 +324,14 @@ class BasicBlock: blocks = core.BNGetBasicBlockStrictDominators(self.handle, count, False) assert blocks is not None, "core.BNGetBasicBlockStrictDominators returned None" result = [] - for i in range(0, count.value): - handle = core.BNNewBasicBlockReference(blocks[i]) - assert handle is not None - result.append(self._create_instance(handle, self.view)) - core.BNFreeBasicBlockList(blocks, count.value) - return result + try: + for i in range(0, count.value): + handle = core.BNNewBasicBlockReference(blocks[i]) + assert handle is not None + result.append(self._create_instance(handle, self.view)) + return result + finally: + core.BNFreeBasicBlockList(blocks, count.value) @property def immediate_dominator(self) -> Optional['BasicBlock']: @@ -355,12 +365,14 @@ class BasicBlock: blocks = core.BNGetBasicBlockDominatorTreeChildren(self.handle, count, False) assert blocks is not None, "core.BNGetBasicBlockDominatorTreeChildren returned None" result = [] - for i in range(0, count.value): - handle = core.BNNewBasicBlockReference(blocks[i]) - assert handle is not None - result.append(self._create_instance(handle, self.view)) - core.BNFreeBasicBlockList(blocks, count.value) - return result + try: + for i in range(0, count.value): + handle = core.BNNewBasicBlockReference(blocks[i]) + assert handle is not None + result.append(self._create_instance(handle, self.view)) + return result + finally: + core.BNFreeBasicBlockList(blocks, count.value) @property def post_dominator_tree_children(self) -> List['BasicBlock']: @@ -372,12 +384,14 @@ class BasicBlock: blocks = core.BNGetBasicBlockDominatorTreeChildren(self.handle, count, True) assert blocks is not None, "core.BNGetBasicBlockDominatorTreeChildren returned None" result = [] - for i in range(0, count.value): - handle = core.BNNewBasicBlockReference(blocks[i]) - assert handle is not None - result.append(self._create_instance(handle, self.view)) - core.BNFreeBasicBlockList(blocks, count.value) - return result + try: + for i in range(0, count.value): + handle = core.BNNewBasicBlockReference(blocks[i]) + assert handle is not None + result.append(self._create_instance(handle, self.view)) + return result + finally: + core.BNFreeBasicBlockList(blocks, count.value) @property def dominance_frontier(self) -> List['BasicBlock']: @@ -389,12 +403,14 @@ class BasicBlock: blocks = core.BNGetBasicBlockDominanceFrontier(self.handle, count, False) assert blocks is not None, "core.BNGetBasicBlockDominanceFrontier returned None" result = [] - for i in range(0, count.value): - handle = core.BNNewBasicBlockReference(blocks[i]) - assert handle is not None - result.append(self._create_instance(handle, self.view)) - core.BNFreeBasicBlockList(blocks, count.value) - return result + try: + for i in range(0, count.value): + handle = core.BNNewBasicBlockReference(blocks[i]) + assert handle is not None + result.append(self._create_instance(handle, self.view)) + return result + finally: + core.BNFreeBasicBlockList(blocks, count.value) @property def post_dominance_frontier(self) -> List['BasicBlock']: @@ -405,12 +421,14 @@ class BasicBlock: blocks = core.BNGetBasicBlockDominanceFrontier(self.handle, count, True) assert blocks is not None, "core.BNGetBasicBlockDominanceFrontier returned None" result = [] - for i in range(0, count.value): - handle = core.BNNewBasicBlockReference(blocks[i]) - assert handle is not None - result.append(self._create_instance(handle, self.view)) - core.BNFreeBasicBlockList(blocks, count.value) - return result + try: + for i in range(0, count.value): + handle = core.BNNewBasicBlockReference(blocks[i]) + assert handle is not None + result.append(self._create_instance(handle, self.view)) + return result + finally: + core.BNFreeBasicBlockList(blocks, count.value) @property def annotations(self) -> List[List['binaryninja.function.InstructionTextToken']]: @@ -502,19 +520,21 @@ class BasicBlock: lines = core.BNGetBasicBlockDisassemblyText(self.handle, settings_obj, count) assert lines is not None, "core.BNGetBasicBlockDisassemblyText returned None" 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] # type: ignore - else: - il_instr = None - color = binaryninja.highlight.HighlightColor._from_core_struct(lines[i].highlight) - tokens = binaryninja.function.InstructionTextToken._from_core_struct(lines[i].tokens, lines[i].count) - result.append(binaryninja.function.DisassemblyTextLine(tokens, addr, il_instr, color)) - core.BNFreeDisassemblyTextLines(lines, count.value) - return result + try: + 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] # type: ignore + else: + il_instr = None + color = _highlight.HighlightColor._from_core_struct(lines[i].highlight) + tokens = _function.InstructionTextToken._from_core_struct(lines[i].tokens, lines[i].count) + result.append(_function.DisassemblyTextLine(tokens, addr, il_instr, color)) + return result + finally: + core.BNFreeDisassemblyTextLines(lines, count.value) - def set_auto_highlight(self, color:'binaryninja.highlight.HighlightColor') -> None: + def set_auto_highlight(self, color:'_highlight.HighlightColor') -> None: """ ``set_auto_highlight`` highlights the current BasicBlock with the supplied color. diff --git a/python/binaryview.py b/python/binaryview.py index 8984154a..6e39b6fe 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -1863,27 +1863,31 @@ class BinaryView: syms = core.BNGetSymbols(self.handle, count, None) assert syms is not None, "core.BNGetSymbols returned None" result = defaultdict(list) - for i in range(0, count.value): - sym = _types.Symbol(None, None, None, handle=core.BNNewSymbolReference(syms[i])) - result[sym.raw_name].append(sym) - core.BNFreeSymbolList(syms, count.value) - return result + try: + for i in range(0, count.value): + sym = _types.Symbol(None, None, None, handle=core.BNNewSymbolReference(syms[i])) + result[sym.raw_name].append(sym) + return result + finally: + core.BNFreeSymbolList(syms, count.value) @staticmethod def internal_namespace() -> '_types.NameSpace': """Internal namespace for the current BinaryView""" ns = core.BNGetInternalNameSpace() - result = _types.NameSpace._from_core_struct(ns) - core.BNFreeNameSpace(ns) - return result + try: + return _types.NameSpace._from_core_struct(ns) + finally: + core.BNFreeNameSpace(ns) @staticmethod def external_namespace() -> '_types.NameSpace': """External namespace for the current BinaryView""" ns = core.BNGetExternalNameSpace() - result = _types.NameSpace._from_core_struct(ns) - core.BNFreeNameSpace(ns) - return result + try: + return _types.NameSpace._from_core_struct(ns) + finally: + core.BNFreeNameSpace(ns) @property def namespaces(self) -> List['_types.NameSpace']: @@ -1892,10 +1896,12 @@ class BinaryView: nameSpaceList = core.BNGetNameSpaces(self.handle, count) assert nameSpaceList is not None, "core.BNGetNameSpaces returned None" result = [] - for i in range(count.value): - result.append(_types.NameSpace._from_core_struct(nameSpaceList[i])) - core.BNFreeNameSpaceList(nameSpaceList, count.value) - return result + try: + for i in range(count.value): + result.append(_types.NameSpace._from_core_struct(nameSpaceList[i])) + return result + finally: + core.BNFreeNameSpaceList(nameSpaceList, count.value) @property def view_type(self) -> str: @@ -1910,10 +1916,12 @@ class BinaryView: result = [] if types is None: return result - for i in range(0, count.value): - result.append(BinaryViewType(types[i])) - core.BNFreeBinaryViewTypeList(types) - return result + try: + for i in range(0, count.value): + result.append(BinaryViewType(types[i])) + return result + finally: + core.BNFreeBinaryViewTypeList(types) @property def strings(self) -> List[str]: @@ -1944,13 +1952,14 @@ class BinaryView: assert info_ref is not None, "core.BNGetAnalysisInfo returned None" info = info_ref[0] active_info_list:List[ActiveAnalysisInfo] = [] - for i in range(0, info.count): - func = _function.Function(self, core.BNNewFunctionReference(info.activeInfo[i].func)) - active_info = ActiveAnalysisInfo(func, info.activeInfo[i].analysisTime, info.activeInfo[i].updateCount, info.activeInfo[i].submitCount) - active_info_list.append(active_info) - result = AnalysisInfo(info.state, info.analysisTime, active_info_list) - core.BNFreeAnalysisInfo(info_ref) - return result + try: + for i in range(0, info.count): + func = _function.Function(self, core.BNNewFunctionReference(info.activeInfo[i].func)) + active_info = ActiveAnalysisInfo(func, info.activeInfo[i].analysisTime, info.activeInfo[i].updateCount, info.activeInfo[i].submitCount) + active_info_list.append(active_info) + return AnalysisInfo(info.state, info.analysisTime, active_info_list) + finally: + core.BNFreeAnalysisInfo(info_ref) @property def analysis_progress(self) -> AnalysisProgress: @@ -1970,10 +1979,12 @@ class BinaryView: var_list = core.BNGetDataVariables(self.handle, count) assert var_list is not None, "core.BNGetDataVariables returned None" result = {} - for i in range(0, count.value): - result[var_list[i].address] = DataVariable.from_core_struct(var_list[i], self) - core.BNFreeDataVariables(var_list, count.value) - return result + try: + for i in range(0, count.value): + result[var_list[i].address] = DataVariable.from_core_struct(var_list[i], self) + return result + finally: + core.BNFreeDataVariables(var_list, count.value) @property def types(self) -> Mapping['_types.QualifiedName', '_types.Type']: @@ -1982,11 +1993,13 @@ class BinaryView: type_list = core.BNGetAnalysisTypeList(self.handle, count) assert type_list is not None, "core.BNGetAnalysisTypeList returned None" result = {} - for i in range(0, count.value): - name = _types.QualifiedName._from_core_struct(type_list[i].name) - result[name] = _types.Type.create(core.BNNewTypeReference(type_list[i].type), platform = self.platform) - core.BNFreeTypeList(type_list, count.value) - return result + try: + for i in range(0, count.value): + name = _types.QualifiedName._from_core_struct(type_list[i].name) + result[name] = _types.Type.create(core.BNNewTypeReference(type_list[i].type), platform = self.platform) + return result + finally: + core.BNFreeTypeList(type_list, count.value) @property def type_names(self) -> List['_types.Type']: @@ -1995,10 +2008,12 @@ class BinaryView: name_list = core.BNGetAnalysisTypeNames(self.handle, count, "") assert name_list is not None, "core.BNGetAnalysisTypeNames returned None" result = [] - for i in range(0, count.value): - result.append(_types.QualifiedName._from_core_struct(name_list[i])) - core.BNFreeTypeNameList(name_list, count.value) - return result + try: + for i in range(0, count.value): + result.append(_types.QualifiedName._from_core_struct(name_list[i])) + return result + finally: + core.BNFreeTypeNameList(name_list, count.value) @property @@ -2008,10 +2023,12 @@ class BinaryView: libraries = core.BNGetBinaryViewTypeLibraries(self.handle, count) assert libraries is not None, "core.BNGetBinaryViewTypeLibraries returned None" result = [] - for i in range(0, count.value): - result.append(typelibrary.TypeLibrary(core.BNNewTypeLibraryReference(libraries[i]))) - core.BNFreeTypeLibraryList(libraries, count.value) - return result + try: + for i in range(0, count.value): + result.append(typelibrary.TypeLibrary(core.BNNewTypeLibraryReference(libraries[i]))) + return result + finally: + core.BNFreeTypeLibraryList(libraries, count.value) @property @@ -2021,12 +2038,14 @@ class BinaryView: segment_list = core.BNGetSegments(self.handle, count) assert segment_list is not None, "core.BNGetSegments returned None" result = [] - for i in range(0, count.value): - segment_handle = core.BNNewSegmentReference(segment_list[i]) - assert segment_handle is not None, "core.BNNewSegmentReference returned None" - result.append(Segment(segment_handle)) - core.BNFreeSegmentList(segment_list, count.value) - return result + try: + for i in range(0, count.value): + segment_handle = core.BNNewSegmentReference(segment_list[i]) + assert segment_handle is not None, "core.BNNewSegmentReference returned None" + result.append(Segment(segment_handle)) + return result + finally: + core.BNFreeSegmentList(segment_list, count.value) @property def sections(self): @@ -2035,12 +2054,14 @@ class BinaryView: section_list = core.BNGetSections(self.handle, count) assert section_list is not None, "core.BNGetSections returned None" result = {} - for i in range(0, count.value): - section_handle = core.BNNewSectionReference(section_list[i]) - assert section_handle is not None, "core.BNNewSectionReference returned None" - result[core.BNSectionGetName(section_list[i])] = Section(section_handle) - core.BNFreeSectionList(section_list, count.value) - return result + try: + for i in range(0, count.value): + section_handle = core.BNNewSectionReference(section_list[i]) + assert section_handle is not None, "core.BNNewSectionReference returned None" + result[core.BNSectionGetName(section_list[i])] = Section(section_handle) + return result + finally: + core.BNFreeSectionList(section_list, count.value) @property def allocated_ranges(self): @@ -2049,10 +2070,12 @@ class BinaryView: range_list = core.BNGetAllocatedRanges(self.handle, count) assert range_list is not None, "core.BNGetAllocatedRanges returned None" result = [] - for i in range(0, count.value): - result.append(variable.AddressRange(range_list[i].start, range_list[i].end)) - core.BNFreeAddressRanges(range_list) - return result + try: + for i in range(0, count.value): + result.append(variable.AddressRange(range_list[i].start, range_list[i].end)) + return result + finally: + core.BNFreeAddressRanges(range_list) @property def session_data(self): @@ -2097,10 +2120,12 @@ class BinaryView: ranges = core.BNGetRelocationRanges(self.handle, count) assert ranges is not None, "core.BNGetRelocationRanges returned None" result = [] - for i in range(0, count.value): - result.append((ranges[i].start, ranges[i].end)) - core.BNFreeRelocationRanges(ranges, count) - return result + try: + for i in range(0, count.value): + result.append((ranges[i].start, ranges[i].end)) + return result + finally: + core.BNFreeRelocationRanges(ranges, count) def relocation_ranges_at(self, addr): """List of relocation range tuples for a given address""" @@ -2109,10 +2134,12 @@ class BinaryView: ranges = core.BNGetRelocationRangesAtAddress(self.handle, addr, count) assert ranges is not None, "core.BNGetRelocationRangesAtAddress returned None" result = [] - for i in range(0, count.value): - result.append((ranges[i].start, ranges[i].end)) - core.BNFreeRelocationRanges(ranges, count) - return result + try: + for i in range(0, count.value): + result.append((ranges[i].start, ranges[i].end)) + return result + finally: + core.BNFreeRelocationRanges(ranges, count) @property def new_auto_function_analysis_suppressed(self): @@ -3227,12 +3254,14 @@ class BinaryView: funcs = core.BNGetAnalysisFunctionsContainingAddress(self.handle, addr, count) assert funcs is not None, "core.BNGetAnalysisFunctionsContainingAddress returned None" result = [] - for i in range(0, count.value): - result.append(_function.Function(self, core.BNNewFunctionReference(funcs[i]))) - core.BNFreeFunctionList(funcs, count.value) - if plat is not None: - result = [func for func in result if func.platform == plat] - return result + try: + for i in range(0, count.value): + result.append(_function.Function(self, core.BNNewFunctionReference(funcs[i]))) + if plat is not None: + result = [func for func in result if func.platform == plat] + return result + finally: + core.BNFreeFunctionList(funcs, count.value) def get_functions_by_name(self, name, plat=None, ordered_filter=None): """``get_functions_by_name`` returns a list of Function objects @@ -3305,10 +3334,12 @@ class BinaryView: funcs = core.BNGetAnalysisFunctionsForAddress(self.handle, addr, count) assert funcs is not None, "core.BNGetAnalysisFunctionsForAddress returned None" result = [] - for i in range(0, count.value): - result.append(_function.Function(self, core.BNNewFunctionReference(funcs[i]))) - core.BNFreeFunctionList(funcs, count.value) - return result + try: + for i in range(0, count.value): + result.append(_function.Function(self, core.BNNewFunctionReference(funcs[i]))) + return result + finally: + core.BNFreeFunctionList(funcs, count.value) def get_recent_function_at(self, addr): func = core.BNGetRecentAnalysisFunctionForAddress(self.handle, addr) @@ -3328,12 +3359,14 @@ class BinaryView: blocks = core.BNGetBasicBlocksForAddress(self.handle, addr, count) assert blocks is not None, "core.BNGetBasicBlocksForAddress returned None" result = [] - for i in range(0, count.value): - block_handle = core.BNNewBasicBlockReference(blocks[i]) - assert block_handle is not None, "core.BNNewBasicBlockReference is None" - result.append(basicblock.BasicBlock(block_handle, self)) - core.BNFreeBasicBlockList(blocks, count.value) - return result + try: + for i in range(0, count.value): + block_handle = core.BNNewBasicBlockReference(blocks[i]) + assert block_handle is not None, "core.BNNewBasicBlockReference is None" + result.append(basicblock.BasicBlock(block_handle, self)) + return result + finally: + core.BNFreeBasicBlockList(blocks, count.value) def get_basic_blocks_starting_at(self, addr): """ @@ -3347,12 +3380,14 @@ class BinaryView: blocks = core.BNGetBasicBlocksStartingAtAddress(self.handle, addr, count) assert blocks is not None, "core.BNGetBasicBlocksStartingAtAddress returned None" result = [] - for i in range(0, count.value): - block_handle = core.BNNewBasicBlockReference(blocks[i]) - assert block_handle is not None, "core.BNNewBasicBlockReference returned None" - result.append(basicblock.BasicBlock(block_handle, self)) - core.BNFreeBasicBlockList(blocks, count.value) - return result + try: + for i in range(0, count.value): + block_handle = core.BNNewBasicBlockReference(blocks[i]) + assert block_handle is not None, "core.BNNewBasicBlockReference returned None" + result.append(basicblock.BasicBlock(block_handle, self)) + return result + finally: + core.BNFreeBasicBlockList(blocks, count.value) def get_recent_basic_block_at(self, addr): block = core.BNGetRecentBasicBlockForAddress(self.handle, addr) @@ -3623,10 +3658,12 @@ class BinaryView: assert refs is not None, "core.BNGetDataReferencesForTypeField returned None" result = [] - for i in range(0, count.value): - result.append(refs[i]) - core.BNFreeDataReferences(refs, count.value) - return result + try: + for i in range(0, count.value): + result.append(refs[i]) + return result + finally: + core.BNFreeDataReferences(refs, count.value) def get_type_refs_for_type(self, name): @@ -3649,11 +3686,13 @@ class BinaryView: assert refs is not None, "core.BNGetTypeReferencesForType returned None" 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 + try: + 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) + return result + finally: + core.BNFreeTypeReferences(refs, count.value) def get_type_refs_for_type_field(self, name, offset): @@ -3677,11 +3716,13 @@ class BinaryView: assert refs is not None, "core.BNGetTypeReferencesForTypeField returned None" 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 + try: + 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) + return result + finally: + core.BNFreeTypeReferences(refs, count.value) def get_code_refs_for_type_from(self, addr, func = None, arch = None, length = None): """ @@ -3709,10 +3750,12 @@ class BinaryView: else: refs = core.BNGetCodeReferencesForTypeFromInRange(self.handle, ref_src, length, count) assert refs is not None, "core.BNGetCodeReferencesForTypeFromInRange returned None" - 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) + try: + 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) + finally: + core.BNFreeTypeReferences(refs, count.value) return result def get_code_refs_for_type_fields_from(self, addr, func = None, arch = None, length = None): @@ -3741,10 +3784,12 @@ class BinaryView: else: refs = core.BNGetCodeReferencesForTypeFieldsFromInRange(self.handle, ref_src, length, count) assert refs is not None, "core.BNGetCodeReferencesForTypeFieldsFromInRange returned None" - 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) + try: + 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) + finally: + core.BNFreeTypeReferences(refs, count.value) return result def add_user_data_ref(self, from_addr, to_addr): @@ -3793,11 +3838,12 @@ class BinaryView: assert refs is not None, "core.BNGetAllFieldsReferenced returned None" result = [] - for i in range(0, count.value): - result.append(refs[i]) - - core.BNFreeDataReferences(refs, count.value) - return result + try: + for i in range(0, count.value): + result.append(refs[i]) + return result + finally: + core.BNFreeDataReferences(refs, count.value) def get_all_sizes_referenced(self, name): """ @@ -3818,15 +3864,15 @@ class BinaryView: name = _types.QualifiedName(name)._get_core_struct() refs = core.BNGetAllSizesReferenced(self.handle, name, count) assert refs is not None, "core.BNGetAllSizesReferenced returned None" - - result = {} - for i in range(0, count.value): - result[refs[i].offset] = [] - for j in range(0, refs[i].count): - result[refs[i].offset].append(refs[i].sizes[j]) - - core.BNFreeTypeFieldReferenceSizeInfo(refs, count.value) - return result + result:Mapping[int, List[int]] = {} + try: + for i in range(0, count.value): + result[refs[i].offset] = [] + for j in range(0, refs[i].count): + result[refs[i].offset].append(refs[i].sizes[j]) + return result + finally: + core.BNFreeTypeFieldReferenceSizeInfo(refs, count.value) def get_all_types_referenced(self, name): """ @@ -3849,16 +3895,17 @@ class BinaryView: refs = core.BNGetAllTypesReferenced(self.handle, name, count) assert refs is not None, "core.BNGetAllTypesReferenced returned None" - result = {} - for i in range(0, count.value): - result[refs[i].offset] = [] - for j in range(0, refs[i].count): - typeObj = _types.Type.create(core.BNNewTypeReference(refs[i].types[j].type), - self.platform, refs[i].types[j].confidence) - result[refs[i].offset].append(typeObj) - - core.BNFreeTypeFieldReferenceTypeInfo(refs, count.value) - return result + result:Mapping[int, List['_types.Type']] = {} + try: + for i in range(0, count.value): + result[refs[i].offset] = [] + for j in range(0, refs[i].count): + typeObj = _types.Type.create(core.BNNewTypeReference(refs[i].types[j].type), + self.platform, refs[i].types[j].confidence) + result[refs[i].offset].append(typeObj) + return result + finally: + core.BNFreeTypeFieldReferenceTypeInfo(refs, count.value) def get_sizes_referenced(self, name, offset): """ @@ -3881,11 +3928,12 @@ class BinaryView: assert refs is not None, "core.BNGetSizesReferenced returned None" result = [] - for i in range(0, count.value): - result.append(refs[i]) - - core.BNFreeTypeFieldReferenceSizes(refs, count.value) - return result + try: + for i in range(0, count.value): + result.append(refs[i]) + return result + finally: + core.BNFreeTypeFieldReferenceSizes(refs, count.value) def get_types_referenced(self, name:'_types.QualifiedName', offset:int) -> List['_types.Type']: """ @@ -3990,9 +4038,11 @@ class BinaryView: count = ctypes.c_ulonglong(0) refs = core.BNGetCallees(self.handle, ref_src, count) assert refs is not None, "core.BNGetCallees returned None" - for i in range(0, count.value): - result.append(refs[i]) - core.BNFreeAddressList(refs) + try: + for i in range(0, count.value): + result.append(refs[i]) + finally: + core.BNFreeAddressList(refs) return result def get_symbol_at(self, addr, namespace=None): @@ -4074,11 +4124,13 @@ class BinaryView: syms = core.BNGetSymbolsByName(self.handle, name, count, namespace) assert syms is not None, "core.BNGetSymbolsByName returned None" result = [] - for i in range(0, count.value): - result.append(_types.Symbol(None, None, None, handle = core.BNNewSymbolReference(syms[i]))) - core.BNFreeSymbolList(syms, count.value) - result = sorted(filter(lambda sym: sym.type in ordered_filter, result), key=lambda sym: ordered_filter.index(sym.type)) - return result + try: + for i in range(0, count.value): + result.append(_types.Symbol(None, None, None, handle = core.BNNewSymbolReference(syms[i]))) + result = sorted(filter(lambda sym: sym.type in ordered_filter, result), key=lambda sym: ordered_filter.index(sym.type)) + return result + finally: + core.BNFreeSymbolList(syms, count.value) def get_symbols(self, start=None, length=None, namespace=None): """ @@ -4106,10 +4158,12 @@ class BinaryView: syms = core.BNGetSymbolsInRange(self.handle, start, length, count, namespace) assert syms is not None, "core.BNGetSymbolsInRange returned None" result = [] - for i in range(0, count.value): - result.append(_types.Symbol(None, None, None, handle = core.BNNewSymbolReference(syms[i]))) - core.BNFreeSymbolList(syms, count.value) - return result + try: + for i in range(0, count.value): + result.append(_types.Symbol(None, None, None, handle = core.BNNewSymbolReference(syms[i]))) + return result + finally: + core.BNFreeSymbolList(syms, count.value) def get_symbols_of_type(self, sym_type, start=None, length=None, namespace=None): """ @@ -4141,10 +4195,12 @@ class BinaryView: syms = core.BNGetSymbolsOfTypeInRange(self.handle, sym_type, start, length, count) assert syms is not None, "core.BNGetSymbolsOfTypeInRange returned None" result = [] - for i in range(0, count.value): - result.append(_types.Symbol(None, None, None, handle = core.BNNewSymbolReference(syms[i]))) - core.BNFreeSymbolList(syms, count.value) - return result + try: + for i in range(0, count.value): + result.append(_types.Symbol(None, None, None, handle = core.BNNewSymbolReference(syms[i]))) + return result + finally: + core.BNFreeSymbolList(syms, count.value) def define_auto_symbol(self, sym): """ @@ -4267,20 +4323,16 @@ class BinaryView: count = ctypes.c_ulonglong(0) types = core.BNGetTagTypes(self.handle, count) assert types is not None, "core.BNGetTagTypes returned None" - result = {} - for i in range(0, count.value): - tag_handle = core.BNNewTagTypeReference(types[i]) - assert tag_handle is not None, "core.BNNewTagTypeReference returned None" - tag = TagType(tag_handle) - if tag.name in result: - if type(result[tag.name]) == list: - result[tag.name].append(tag) - else: - result[tag.name] = [result[tag.name], tag] - else: - result[tag.name] = tag - core.BNFreeTagTypeList(types, count.value) - return result + result:Mapping[str, List['TagType']] = defaultdict(list) + try: + for i in range(0, count.value): + tag_handle = core.BNNewTagTypeReference(types[i]) + assert tag_handle is not None, "core.BNNewTagTypeReference returned None" + tag = TagType(tag_handle) + result[tag.name].append(tag) + return result + finally: + core.BNFreeTagTypeList(types, count.value) def get_tag_type(self, name): """ @@ -4368,13 +4420,15 @@ class BinaryView: tags = core.BNGetDataTagReferences(self.handle, count) assert tags is not None, "core.BNGetDataTagReferences returned None" result = [] - for i in range(0, count.value): - tag_handle = core.BNNewTagReference(tags[i].tag) - assert tag_handle is not None, "core.BNNewTagReference is not None" - tag = Tag(tag_handle) - result.append((tags[i].addr, tag)) - core.BNFreeTagReferences(tags, count.value) - return result + try: + for i in range(0, count.value): + tag_handle = core.BNNewTagReference(tags[i].tag) + assert tag_handle is not None, "core.BNNewTagReference is not None" + tag = Tag(tag_handle) + result.append((tags[i].addr, tag)) + return result + finally: + core.BNFreeTagReferences(tags, count.value) @property def auto_data_tags(self): @@ -4387,11 +4441,17 @@ class BinaryView: count = ctypes.c_ulonglong() refs = core.BNGetAutoDataTagReferences(self.handle, count) result = [] - for i in range(0, count.value): - tag = Tag(core.BNNewTagReference(refs[i].tag)) - result.append((refs[i].addr, tag)) - core.BNFreeTagReferences(refs, count.value) - return result + try: + for i in range(0, count.value): + handle = refs[i].tag + assert handle is not None, "BNGetAutoDataTagReferences returned handle set to None" + tag_ref = core.BNNewTagReference(handle) + assert tag_ref is not None, "BNNewTagReference returned None" + tag = Tag(tag_ref) + result.append((refs[i].addr, tag)) + return result + finally: + core.BNFreeTagReferences(refs, count.value) @property def user_data_tags(self): @@ -4404,11 +4464,17 @@ class BinaryView: count = ctypes.c_ulonglong() refs = core.BNGetUserDataTagReferences(self.handle, count) result = [] - for i in range(0, count.value): - tag = Tag(core.BNNewTagReference(refs[i].tag)) - result.append((refs[i].addr, tag)) - core.BNFreeTagReferences(refs, count.value) - return result + try: + for i in range(0, count.value): + tag_handle = refs[i].tag + assert tag_handle is not None, "BNGetUserDataTagReferences returned tag with handle set to None" + tag_ref = core.BNNewTagReference(tag_handle) + assert tag_ref is not None, "BNNewTagReference returned None" + tag = Tag(tag_ref) + result.append((refs[i].addr, tag)) + return result + finally: + core.BNFreeTagReferences(refs, count.value) def get_data_tags_at(self, addr): """ @@ -4422,12 +4488,14 @@ class BinaryView: tags = core.BNGetDataTags(self.handle, addr, count) assert tags is not None, "core.BNGetDataTags returned None" result = [] - for i in range(0, count.value): - tag_handle = core.BNNewTagReference(tags[i]) - assert tag_handle is not None, "core.BNNewTagReference is not None" - result.append(Tag(tag_handle)) - core.BNFreeTagList(tags, count.value) - return result + try: + for i in range(0, count.value): + tag_handle = core.BNNewTagReference(tags[i]) + assert tag_handle is not None, "core.BNNewTagReference is not None" + result.append(Tag(tag_handle)) + return result + finally: + core.BNFreeTagList(tags, count.value) def get_auto_data_tags_at(self, addr): """ @@ -4440,10 +4508,14 @@ class BinaryView: count = ctypes.c_ulonglong() tags = core.BNGetAutoDataTags(self.handle, addr, count) result = [] - for i in range(0, count.value): - result.append(Tag(core.BNNewTagReference(tags[i]))) - core.BNFreeTagList(tags, count.value) - return result + try: + for i in range(0, count.value): + tag_ref = core.BNNewTagReference(tags[i]) + assert tag_ref is not None, "BNNewTagReference returned None" + result.append(Tag(tag_ref)) + return result + finally: + core.BNFreeTagList(tags, count.value) def get_user_data_tags_at(self, addr): """ @@ -4456,10 +4528,14 @@ class BinaryView: count = ctypes.c_ulonglong() tags = core.BNGetUserDataTags(self.handle, addr, count) result = [] - for i in range(0, count.value): - result.append(Tag(core.BNNewTagReference(tags[i]))) - core.BNFreeTagList(tags, count.value) - return result + try: + for i in range(0, count.value): + tag_ref = core.BNNewTagReference(tags[i]) + assert tag_ref is not None, "BNNewTagReference returned None" + result.append(Tag(tag_ref)) + return result + finally: + core.BNFreeTagList(tags, count.value) def get_data_tags_of_type(self, addr, tag_type): """ @@ -4473,10 +4549,14 @@ class BinaryView: count = ctypes.c_ulonglong() tags = core.BNGetDataTagsOfType(self.handle, addr, tag_type.handle, count) result = [] - for i in range(0, count.value): - result.append(Tag(core.BNNewTagReference(tags[i]))) - core.BNFreeTagList(tags, count.value) - return result + try: + for i in range(0, count.value): + tag_ref = core.BNNewTagReference(tags[i]) + assert tag_ref is not None, "BNNewTagReference returned None" + result.append(Tag(tag_ref)) + return result + finally: + core.BNFreeTagList(tags, count.value) def get_auto_data_tags_of_type(self, addr, tag_type): """ @@ -4491,12 +4571,14 @@ class BinaryView: tags = core.BNGetAutoDataTagsOfType(self.handle, addr, tag_type.handle, count) assert tags is not None, "core.BNGetAutoDataTagsOfType returned None" result = [] - for i in range(0, count.value): - tag_handle = core.BNNewTagReference(tags[i]) - assert tag_handle is not None, "core.BNNewTagReference returned None" - result.append(Tag(tag_handle)) - core.BNFreeTagList(tags, count.value) - return result + try: + for i in range(0, count.value): + tag_handle = core.BNNewTagReference(tags[i]) + assert tag_handle is not None, "core.BNNewTagReference returned None" + result.append(Tag(tag_handle)) + return result + finally: + core.BNFreeTagList(tags, count.value) def get_user_data_tags_of_type(self, addr, tag_type): """ @@ -4510,10 +4592,14 @@ class BinaryView: count = ctypes.c_ulonglong() tags = core.BNGetUserDataTagsOfType(self.handle, addr, tag_type.handle, count) result = [] - for i in range(0, count.value): - result.append(Tag(core.BNNewTagReference(tags[i]))) - core.BNFreeTagList(tags, count.value) - return result + try: + for i in range(0, count.value): + tag_ref = core.BNNewTagReference(tags[i]) + assert tag_ref is not None, "BNNewTagReference returned None" + result.append(Tag(tag_ref)) + return result + finally: + core.BNFreeTagList(tags, count.value) def get_data_tags_in_range(self, address_range): """ @@ -4527,11 +4613,15 @@ class BinaryView: count = ctypes.c_ulonglong() refs = core.BNGetDataTagsInRange(self.handle, address_range.start, address_range.end, count) result = [] - for i in range(0, count.value): - tag = Tag(core.BNNewTagReference(refs[i].tag)) - result.append((refs[i].addr, tag)) - core.BNFreeTagReferences(refs, count.value) - return result + try: + for i in range(0, count.value): + tag_ref = core.BNNewTagReference(refs[i].tag) + assert tag_ref is not None, "BNNewTagReference returned None" + tag = Tag(tag_ref) + result.append((refs[i].addr, tag)) + return result + finally: + core.BNFreeTagReferences(refs, count.value) def get_auto_data_tags_in_range(self, address_range): """ @@ -4545,11 +4635,15 @@ class BinaryView: count = ctypes.c_ulonglong() refs = core.BNGetAutoDataTagsInRange(self.handle, address_range.start, address_range.end, count) result = [] - for i in range(0, count.value): - tag = Tag(core.BNNewTagReference(refs[i].tag)) - result.append((refs[i].addr, tag)) - core.BNFreeTagReferences(refs, count.value) - return result + try: + for i in range(count.value): + tag_ref = core.BNNewTagReference(refs[i].tag) + assert tag_ref is not None, "BNNewTagReference returned None" + tag = Tag(tag_ref) + result.append((refs[i].addr, tag)) + return result + finally: + core.BNFreeTagReferences(refs, count.value) def get_user_data_tags_in_range(self, address_range): """ @@ -4563,11 +4657,15 @@ class BinaryView: count = ctypes.c_ulonglong() refs = core.BNGetUserDataTagsInRange(self.handle, address_range.start, address_range.end, count) result = [] - for i in range(0, count.value): - tag = Tag(core.BNNewTagReference(refs[i].tag)) - result.append((refs[i].addr, tag)) - core.BNFreeTagReferences(refs, count.value) - return result + try: + for i in range(count.value): + tag_ref = core.BNNewTagReference(refs[i].tag) + assert tag_ref is not None, "BNNewTagReference returned None" + tag = Tag(tag_ref) + result.append((refs[i].addr, tag)) + return result + finally: + core.BNFreeTagReferences(refs, count.value) def add_user_data_tag(self, addr, tag): """ @@ -5061,10 +5159,12 @@ class BinaryView: strings = core.BNGetStringsInRange(self.handle, start, length, count) assert strings is not None, "core.BNGetStringsInRange returned None" result = [] - for i in range(0, count.value): - result.append(StringReference(self, StringType(strings[i].type), strings[i].start, strings[i].length)) - core.BNFreeStringReferenceList(strings) - return result + try: + for i in range(0, count.value): + result.append(StringReference(self, StringType(strings[i].type), strings[i].start, strings[i].length)) + return result + finally: + core.BNFreeStringReferenceList(strings) def get_string_at(self, addr, partial=False): """ @@ -5512,18 +5612,21 @@ class BinaryView: if not isinstance(text, str): raise AttributeError("Source must be a string") result = core.BNQualifiedNameAndType() - errors = ctypes.c_char_p() - type_list = core.BNQualifiedNameList() - type_list.count = 0 - if not core.BNParseTypeString(self.handle, text, result, errors, type_list): - assert errors.value is not None, "core.BNParseTypeString returned 'errors' set to None" - error_str = errors.value.decode("utf-8") - core.free_string(errors) - raise SyntaxError(error_str) - type_obj = _types.Type.create(core.BNNewTypeReference(result.type), platform = self.platform) - name = _types.QualifiedName._from_core_struct(result.name) - core.BNFreeQualifiedNameAndType(result) - return type_obj, name + assert result is not None, "core.BNQualifiedNameAndType returned None" + try: + errors = ctypes.c_char_p() + type_list = core.BNQualifiedNameList() + type_list.count = 0 + if not core.BNParseTypeString(self.handle, text, result, errors, type_list): + assert errors.value is not None, "core.BNParseTypeString returned 'errors' set to None" + error_str = errors.value.decode("utf-8") + core.free_string(errors) + raise SyntaxError(error_str) + type_obj = _types.Type.create(core.BNNewTypeReference(result.type), platform = self.platform) + name = _types.QualifiedName._from_core_struct(result.name) + return type_obj, name + finally: + core.BNFreeQualifiedNameAndType(result) def parse_types_from_string(self, text): """ @@ -5545,29 +5648,31 @@ class BinaryView: raise AttributeError("Source must be a string") parse = core.BNTypeParserResult() - errors = ctypes.c_char_p() - type_list = core.BNQualifiedNameList() - type_list.count = 0 - if not core.BNParseTypesString(self.handle, text, parse, errors, type_list): - assert errors.value is not None, "core.BNParseTypesString returned errors set to None" - error_str = errors.value.decode("utf-8") - core.free_string(errors) - raise SyntaxError(error_str) + try: + errors = ctypes.c_char_p() + type_list = core.BNQualifiedNameList() + type_list.count = 0 + if not core.BNParseTypesString(self.handle, text, parse, errors, type_list): + assert errors.value is not None, "core.BNParseTypesString returned errors set to None" + error_str = errors.value.decode("utf-8") + core.free_string(errors) + raise SyntaxError(error_str) - type_dict:Mapping[_types.QualifiedName, _types.Type] = {} - variables:Mapping[_types.QualifiedName, _types.Type] = {} - functions:Mapping[_types.QualifiedName, _types.Type] = {} - for i in range(0, parse.typeCount): - name = _types.QualifiedName._from_core_struct(parse.types[i].name) - type_dict[name] = _types.Type.create(core.BNNewTypeReference(parse.types[i].type), platform = self.platform) - for i in range(0, parse.variableCount): - name = _types.QualifiedName._from_core_struct(parse.variables[i].name) - variables[name] = _types.Type.create(core.BNNewTypeReference(parse.variables[i].type), platform = self.platform) - for i in range(0, parse.functionCount): - name = _types.QualifiedName._from_core_struct(parse.functions[i].name) - functions[name] = _types.Type.create(core.BNNewTypeReference(parse.functions[i].type), platform = self.platform) - core.BNFreeTypeParserResult(parse) - return _types.TypeParserResult(type_dict, variables, functions) + type_dict:Mapping[_types.QualifiedName, _types.Type] = {} + variables:Mapping[_types.QualifiedName, _types.Type] = {} + functions:Mapping[_types.QualifiedName, _types.Type] = {} + for i in range(0, parse.typeCount): + name = _types.QualifiedName._from_core_struct(parse.types[i].name) + type_dict[name] = _types.Type.create(core.BNNewTypeReference(parse.types[i].type), platform = self.platform) + for i in range(0, parse.variableCount): + name = _types.QualifiedName._from_core_struct(parse.variables[i].name) + variables[name] = _types.Type.create(core.BNNewTypeReference(parse.variables[i].type), platform = self.platform) + for i in range(0, parse.functionCount): + name = _types.QualifiedName._from_core_struct(parse.functions[i].name) + functions[name] = _types.Type.create(core.BNNewTypeReference(parse.functions[i].type), platform = self.platform) + return _types.TypeParserResult(type_dict, variables, functions) + finally: + core.BNFreeTypeParserResult(parse) def parse_possiblevalueset(self, value, state, here=0): """ @@ -6459,12 +6564,14 @@ class BinaryView: section_list = core.BNGetSectionsAt(self.handle, addr, count) assert section_list is not None, "core.BNGetSectionsAt returned None" result = [] - for i in range(0, count.value): - section_handle = core.BNNewSectionReference(section_list[i]) - assert section_handle is not None, "core.BNNewSectionReference returned None" - result.append(Section(section_handle)) - core.BNFreeSectionList(section_list, count.value) - return result + try: + for i in range(0, count.value): + section_handle = core.BNNewSectionReference(section_list[i]) + assert section_handle is not None, "core.BNNewSectionReference returned None" + result.append(Section(section_handle)) + return result + finally: + core.BNFreeSectionList(section_list, count.value) def get_section_by_name(self, name): section = core.BNGetSectionByName(self.handle, name) @@ -6482,10 +6589,12 @@ class BinaryView: outgoing_names = core.BNGetUniqueSectionNames(self.handle, incoming_names, len(name_list)) assert outgoing_names is not None, "core.BNGetUniqueSectionNames returned None" result = [] - for i in range(0, len(name_list)): - result.append(str(outgoing_names[i])) - core.BNFreeStringList(outgoing_names, len(name_list)) - return result + try: + for i in range(0, len(name_list)): + result.append(str(outgoing_names[i])) + return result + finally: + core.BNFreeStringList(outgoing_names, len(name_list)) @property def address_comments(self): @@ -6502,10 +6611,12 @@ class BinaryView: addrs = core.BNGetGlobalCommentedAddresses(self.handle, count) assert addrs is not None, "core.BNGetGlobalCommentedAddresses returned None" result = {} - for i in range(0, count.value): - result[addrs[i]] = self.get_comment_at(addrs[i]) - core.BNFreeAddressList(addrs) - return result + try: + for i in range(0, count.value): + result[addrs[i]] = self.get_comment_at(addrs[i]) + return result + finally: + core.BNFreeAddressList(addrs) def get_comment_at(self, addr): """ @@ -6632,10 +6743,12 @@ class BinaryView: count = ctypes.c_ulonglong(0) names = core.BNBinaryViewGetLoadSettingsTypeNames(self.handle, count) assert names is not None, "core.BNBinaryViewGetLoadSettingsTypeNames returned None" - for i in range(count.value): - result.append(names[i]) - core.BNFreeStringList(names, count) - return result + try: + for i in range(count.value): + result.append(names[i]) + return result + finally: + core.BNFreeStringList(names, count) def get_load_settings(self, type_name): """ diff --git a/python/debuginfo.py b/python/debuginfo.py index 15ac4efb..b3b80614 100644 --- a/python/debuginfo.py +++ b/python/debuginfo.py @@ -21,14 +21,15 @@ import ctypes from typing import Optional, List, Iterator, Callable, Tuple import traceback +from dataclasses import dataclass # Binary Ninja components import binaryninja -from binaryninja import _binaryninjacore as core -from binaryninja import callingconvention -from binaryninja import platform -from binaryninja import types -from binaryninja import log +from . import _binaryninjacore as core +from . import callingconvention +from . import platform +from . import types +from . import log _debug_info_parsers = {} @@ -41,9 +42,12 @@ class _DebugInfoParserMetaClass(type): binaryninja._init_plugins() count = ctypes.c_ulonglong() parsers = core.BNGetDebugInfoParsers(count) + assert parsers is not None, "core.BNGetDebugInfoParsers returned None" result = [] for i in range(0, count.value): - result.append(DebugInfoParser(core.BNNewDebugInfoParserReference(parsers[i]))) + parser = core.BNNewDebugInfoParserReference(parsers[i]) + assert parser is not None, "core.BNNewDebugInfoParserReference returned None" + result.append(DebugInfoParser(parser)) core.BNFreeDebugInfoParserList(parsers, count.value) return result @@ -52,9 +56,12 @@ class _DebugInfoParserMetaClass(type): binaryninja._init_plugins() count = ctypes.c_ulonglong() parsers = core.BNGetDebugInfoParsers(count) + assert parsers is not None, "core.BNGetDebugInfoParsers returned None" try: for i in range(0, count.value): - yield DebugInfoParser(core.BNNewDebugInfoParserReference(parsers[i])) + parser = core.BNNewDebugInfoParserReference(parsers[i]) + assert parser is not None, "core.BNNewDebugInfoParserReference returned None" + yield DebugInfoParser(parser) finally: core.BNFreeDebugInfoParserList(parsers, count.value) @@ -64,7 +71,9 @@ class _DebugInfoParserMetaClass(type): parser = core.BNGetDebugInfoParserByName(str(value)) if parser is None: raise KeyError(f"'{str(value)}' is not a valid debug-info parser") - return DebugInfoParser(core.BNNewDebugInfoParserReference(parser)) + parser_ref = core.BNNewDebugInfoParserReference(parser) + assert parser_ref is not None, "core.BNNewDebugInfoParserReference returned None" + return DebugInfoParser(parser_ref) @staticmethod def get_parsers_for_view(view: binaryninja.binaryview.BinaryView) -> List["DebugInfoParser"]: @@ -73,10 +82,15 @@ class _DebugInfoParserMetaClass(type): count = ctypes.c_ulonglong() parsers = core.BNGetDebugInfoParsersForView(view.handle, count) + assert parsers is not None, "core.BNGetDebugInfoParsersForView returned None" result = [] - for i in range(0, count.value): - result.append(DebugInfoParser(core.BNNewDebugInfoParserReference(parsers[i]))) - core.BNFreeDebugInfoParserList(parsers, count.value) + try: + for i in range(0, count.value): + parser_ref = core.BNNewDebugInfoParserReference(parsers[i]) + assert parser_ref is not None, "core.BNNewDebugInfoParserReference returned None" + result.append(DebugInfoParser(parser_ref)) + finally: + core.BNFreeDebugInfoParserList(parsers, count.value) return result @staticmethod @@ -87,13 +101,16 @@ class _DebugInfoParserMetaClass(type): return callback(view_obj) except: log.log_error(traceback.format_exc()) + return False @staticmethod def _parse_info(debug_info: core.BNDebugInfo, view: core.BNBinaryView, callback: Callable[["DebugInfo", binaryninja.binaryview.BinaryView], None]) -> None: try: file_metadata = binaryninja.filemetadata.FileMetadata(handle = core.BNGetFileForView(view)) view_obj = binaryninja.binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(view)) - callback(DebugInfo(core.BNNewDebugInfoReference(debug_info)), view_obj) + parser_ref = core.BNNewDebugInfoReference(debug_info) + assert parser_ref is not None, "core.BNNewDebugInfoReference returned None" + callback(DebugInfo(parser_ref), view_obj) except: log.log_error(traceback.format_exc()) @@ -108,8 +125,11 @@ class _DebugInfoParserMetaClass(type): # Don't let our callbacks get garbage collected global _debug_info_parsers _debug_info_parsers[len(_debug_info_parsers)] = (is_valid_cb, parse_info_cb) - - return DebugInfoParser(core.BNNewDebugInfoParserReference(core.BNRegisterDebugInfoParser(name, is_valid_cb, parse_info_cb, None))) + parser = core.BNRegisterDebugInfoParser(name, is_valid_cb, parse_info_cb, None) + assert parser is not None, "core.BNRegisterDebugInfoParser is not None" + parser_ref = core.BNNewDebugInfoParserReference(parser) + assert parser_ref is not None, "core.BNNewDebugInfoParserReference returned None" + return DebugInfoParser(parser_ref) class DebugInfoParser(object, metaclass=_DebugInfoParserMetaClass): @@ -189,11 +209,18 @@ class DebugInfoParser(object, metaclass=_DebugInfoParserMetaClass): def parse_debug_info(self, view: binaryninja.binaryview.BinaryView, debug_info: Optional["DebugInfo"] = None) -> "DebugInfo": """Returns a ``DebugInfo`` object populated with debug info by this debug-info parser. Only provide a ``DebugInfo`` object if you wish to append to the existing debug info""" if isinstance(debug_info, DebugInfo): - return DebugInfo(core.BNNewDebugInfoReference(core.BNParseDebugInfo(self.handle, view.handle, debug_info.handle))) + parser = core.BNParseDebugInfo(self.handle, view.handle, debug_info.handle) + assert parser is not None, "core.BNParseDebugInfo returned None" + parser_ref = core.BNNewDebugInfoReference(parser) + assert parser_ref is not None, "core.BNNewDebugInfoReference returned None" + return DebugInfo(parser_ref) else: - return DebugInfo(core.BNParseDebugInfo(self.handle, view.handle, None)) + parser = core.BNParseDebugInfo(self.handle, view.handle, None) + assert parser is not None, "core.BNParseDebugInfo returned None" + return DebugInfo(parser) +@dataclass(frozen=True) class DebugFunctionInfo(object): """ ``DebugFunctionInfo`` collates ground-truth function-external attributes for use in BinaryNinja's internal analysis. @@ -202,64 +229,27 @@ class DebugFunctionInfo(object): Functions will not be created if an address is not provided, but will be able to be queried from debug info for later user analysis. """ - def __init__(self, address: Optional[int] = 0, short_name: Optional[str] = None, full_name: Optional[str] = None, raw_name: Optional[str] = None, return_type: Optional[types.Type] = None, parameters: Optional[List[Tuple[str, types.Type]]] = None, variable_parameters: Optional[bool] = False, calling_convention: Optional[callingconvention.CallingConvention] = None, platform: Optional[platform.Platform] = None) -> None: - self._short_name = short_name - self._full_name = full_name - self._raw_name = raw_name - self._address = address - self._return_type = return_type - self._parameters = parameters - self._variable_parameters = variable_parameters - self._calling_convention = calling_convention - self._platform = platform + short_name:Optional[str] + full_name:Optional[str] + raw_name:Optional[str] + address:Optional[int] + return_type:Optional[types.Type] + parameters:Optional[List[Tuple[str, types.Type]]] + variable_parameters:Optional[bool] + calling_convention:Optional[callingconvention.CallingConvention] + platform:Optional[platform.Platform] def __repr__(self) -> str: - suffix = f"@{hex(self._address)}>" if self._address != 0 else ">" - if self._short_name is not None: - return f"<debug-info function: {self._short_name}{suffix}" - elif self._full_name is not None: - return f"<debug-info function: {self._full_name}{suffix}" - elif self._raw_name is not None: - return f"<debug-info function: {self._raw_name}{suffix}" + suffix = f"@{self.address:#x}>" if self.address != 0 else ">" + if self.short_name is not None: + return f"<debug-info function: {self.short_name}{suffix}" + elif self.full_name is not None: + return f"<debug-info function: {self.full_name}{suffix}" + elif self.raw_name is not None: + return f"<debug-info function: {self.raw_name}{suffix}" else: return f"<debug-info function{suffix}" - @property - def short_name(self) -> Optional[str]: - return self._short_name - - @property - def full_name(self) -> Optional[str]: - return self._full_name - - @property - def raw_name(self) -> Optional[str]: - return self._raw_name - - @property - def address(self) -> Optional[int]: - return self._address - - @property - def return_type(self) -> Optional[int]: - return self._return_type - - @property - def parameters(self) -> Optional[List[Tuple[str, types.Type]]]: - return self._parameters - - @property - def variable_parameters(self) -> Optional[bool]: - return self._variable_parameters - - @property - def calling_convention(self) -> Optional[callingconvention.CallingConvention]: - return self._calling_convention - - @property - def platform(self) -> Optional[platform.Platform]: - return self._platform - class DebugInfo(object): """ @@ -287,6 +277,7 @@ class DebugInfo(object): """Returns a generator of all types provided by a named DebugInfoParser""" count = ctypes.c_ulonglong(0) name_and_types = core.BNGetDebugTypes(self.handle, name, count) + assert name_and_types is not None, "core.BNGetDebugTypes returned None" try: for i in range(0, count.value): yield (name_and_types[i].name, types.Type(core.BNNewTypeReference(name_and_types[i].type))) @@ -302,6 +293,7 @@ class DebugInfo(object): """Returns a generator of all functions provided by a named DebugInfoParser""" count = ctypes.c_ulonglong(0) functions = core.BNGetDebugFunctions(self.handle, name, count) + assert functions is not None, "core.BNGetDebugFunctions returned None" try: for i in range(0, count.value): @@ -347,6 +339,7 @@ class DebugInfo(object): """Returns a generator of all data variables provided by a named DebugInfoParser""" count = ctypes.c_ulonglong(0) data_variables = core.BNGetDebugDataVariables(self.handle, name, count) + assert data_variables is not None, "core.BNGetDebugDataVariables returned None" try: for i in range(0, count.value): yield binaryninja.binaryview.DataVariableAndName( @@ -413,8 +406,8 @@ class DebugInfo(object): func_info.parameterTypes = None func_info.parameterCount = parameter_count else: - func_info.parameterNames = (ctypes.c_char_p * parameter_count)(*map(lambda pair: binaryninja.cstr(pair[0]), new_func.parameters)) - func_info.parameterTypes = (ctypes.POINTER(core.BNType) * parameter_count)(*map(lambda pair: pair[1].handle, new_func.parameters)) + func_info.parameterNames = (ctypes.c_char_p * parameter_count)(*map(lambda pair: binaryninja.cstr(pair[0]), new_func.parameters)) # type: ignore + func_info.parameterTypes = (ctypes.POINTER(core.BNType) * parameter_count)(*map(lambda pair: pair[1].handle, new_func.parameters)) # type: ignore func_info.parameterCount = parameter_count return core.BNAddDebugFunction(self.handle, func_info) diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 28be0df6..4c785e22 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -2607,46 +2607,53 @@ class LowLevelILFunction: self._source_function = value @property - def il_form(self) -> "binaryninja.enums.FunctionGraphType": - if len(self.basic_blocks) < 1: + def il_form(self) -> FunctionGraphType: + if len(list(self.basic_blocks)) < 1: return FunctionGraphType.InvalidILViewType - return FunctionGraphType(core.BNGetBasicBlockFunctionGraphType(self.basic_blocks[0].handle)) + return FunctionGraphType(core.BNGetBasicBlockFunctionGraphType(list(self.basic_blocks)[0].handle)) @property def registers(self) -> List[ILRegister]: """ List of registers used in this IL """ count = ctypes.c_ulonglong() + assert self.handle is not None, "LLIL Function handle is None" registers = core.BNGetLowLevelRegisters(self.handle, count) - + assert registers is not None, "core.BNGetLowLevelRegisters returned None" result = [] - for var_i in range(count.value): - result.append(ILRegister(self.arch, registers[var_i])) - core.BNFreeLLILVariablesList(registers) - return result + try: + for var_i in range(count.value): + result.append(ILRegister(self.arch, registers[var_i])) + return result + finally: + core.BNFreeLLILVariablesList(registers) @property def register_stacks(self) -> List[ILRegisterStack]: """ List of register stacks used in this IL """ count = ctypes.c_ulonglong() registerStacks = core.BNGetLowLevelRegisterStacks(self.handle, count) - + assert registerStacks is not None, "core.BNGetLowLevelRegisterStacks returned None" result = [] - for var_i in range(count.value): - result.append(ILRegisterStack(self.arch, registerStacks[var_i])) - core.BNFreeLLILVariablesList(registerStacks) - return result + try: + for var_i in range(count.value): + result.append(ILRegisterStack(self.arch, registerStacks[var_i])) + return result + finally: + core.BNFreeLLILVariablesList(registerStacks) @property def flags(self) -> List[ILFlag]: """ List of flags used in this IL """ count = ctypes.c_ulonglong() flags = core.BNGetLowLevelFlags(self.handle, count) - + assert flags is not None, "core.BNGetLowLevelFlags returned None" result = [] - for var_i in range(count.value): - result.append(ILFlag(self.arch, flags[var_i])) - core.BNFreeLLILVariablesList(flags) - return result + try: + for var_i in range(count.value): + result.append(ILFlag(self.arch, flags[var_i])) + return result + finally: + core.BNFreeLLILVariablesList(flags) @property def ssa_registers(self) -> List[SSARegister]: @@ -2655,18 +2662,24 @@ class LowLevelILFunction: return [] register_count = ctypes.c_ulonglong() + assert self.handle is not None, "LLIL Function handle is None" registers = core.BNGetLowLevelRegisters(self.handle, register_count) + assert registers is not None, "core.BNGetLowLevelRegisters returned None" result = [] - for var_i in range(register_count.value): - version_count = ctypes.c_ulonglong() - versions = core.BNGetLowLevelRegisterSSAVersions(self.handle, registers[var_i], version_count) - - for version_i in range(version_count.value): - result.append(SSARegister(ILRegister(self.arch, registers[var_i]), versions[version_i])) - core.BNFreeLLILVariableVersionList(versions) + try: + for var_i in range(register_count.value): + version_count = ctypes.c_ulonglong() + versions = core.BNGetLowLevelRegisterSSAVersions(self.handle, registers[var_i], version_count) + assert versions is not None, "core.BNGetLowLevelRegisterSSAVersions returned None" + try: + for version_i in range(version_count.value): + result.append(SSARegister(ILRegister(self.arch, registers[var_i]), versions[version_i])) + finally: + core.BNFreeLLILVariableVersionList(versions) - core.BNFreeLLILVariablesList(registers) - return result + return result + finally: + core.BNFreeLLILVariablesList(registers) @property def ssa_register_stacks(self) -> List[SSARegisterStack]: @@ -2676,16 +2689,20 @@ class LowLevelILFunction: register_stack_count = ctypes.c_ulonglong() register_stacks = core.BNGetLowLevelRegisterStacks(self.handle, register_stack_count) + assert register_stacks is not None, "core.BNGetLowLevelRegisterStacks returned None" result = [] - for var_i in range(register_stack_count.value): - version_count = ctypes.c_ulonglong() - versions = core.BNGetLowLevelRegisterStackSSAVersions(self.handle, register_stacks[var_i], version_count) - - for version_i in range(version_count.value): - result.append(SSARegisterStack(ILRegisterStack(self.arch, register_stacks[var_i]), versions[version_i])) - core.BNFreeLLILVariableVersionList(versions) - - core.BNFreeLLILVariablesList(register_stacks) + try: + for var_i in range(register_stack_count.value): + version_count = ctypes.c_ulonglong() + versions = core.BNGetLowLevelRegisterStackSSAVersions(self.handle, register_stacks[var_i], version_count) + assert versions is not None, "core.BNGetLowLevelRegisterStackSSAVersions returned None" + try: + for version_i in range(version_count.value): + result.append(SSARegisterStack(ILRegisterStack(self.arch, register_stacks[var_i]), versions[version_i])) + finally: + core.BNFreeLLILVariableVersionList(versions) + finally: + core.BNFreeLLILVariablesList(register_stacks) return result @property @@ -2696,16 +2713,20 @@ class LowLevelILFunction: flag_count = ctypes.c_ulonglong() flags = core.BNGetLowLevelFlags(self.handle, flag_count) + assert flags is not None, "core.BNGetLowLevelFlags returned None" result = [] - for var_i in range(flag_count.value): - version_count = ctypes.c_ulonglong() - versions = core.BNGetLowLevelFlagSSAVersions(self.handle, flags[var_i], version_count) - - for version_i in range(version_count.value): - result.append(SSAFlag(ILFlag(self.arch, flags[var_i]), versions[version_i])) - core.BNFreeLLILVariableVersionList(versions) - - core.BNFreeLLILVariablesList(flags) + try: + for var_i in range(flag_count.value): + version_count = ctypes.c_ulonglong() + versions = core.BNGetLowLevelFlagSSAVersions(self.handle, flags[var_i], version_count) + assert versions is not None, "core.BNGetLowLevelFlagSSAVersions returned None" + try: + for version_i in range(version_count.value): + result.append(SSAFlag(ILFlag(self.arch, flags[var_i]), versions[version_i])) + finally: + core.BNFreeLLILVariableVersionList(versions) + finally: + core.BNFreeLLILVariablesList(flags) return result @property @@ -2713,12 +2734,14 @@ class LowLevelILFunction: """ List of memory versions used in this IL """ count = ctypes.c_ulonglong() memory_versions = core.BNGetLowLevelMemoryVersions(self.handle, count) - + assert memory_versions is not None, "core.BNGetLowLevelMemoryVersions returned None" result = [] - for version_i in range(count.value): - result.append(memory_versions[version_i]) - core.BNFreeLLILVariableVersionList(memory_versions) - return result + try: + for version_i in range(count.value): + result.append(memory_versions[version_i]) + return result + finally: + core.BNFreeLLILVariableVersionList(memory_versions) @property def vars(self) -> List[Union[ILRegister, ILRegisterStack, ILFlag]]: @@ -2727,14 +2750,14 @@ class LowLevelILFunction: return [] if self.il_form in [FunctionGraphType.LiftedILFunctionGraph, FunctionGraphType.LowLevelILFunctionGraph, FunctionGraphType.LowLevelILSSAFormFunctionGraph]: - return self.registers + self.register_stacks + self.flags + return self.registers + self.register_stacks + self.flags # type: ignore return [] @property - def ssa_vars(self) -> List["binaryninja.mediumlevelil.SSAVariable"]: + def ssa_vars(self) -> List[Union['mediumlevelil.SSAVariable', SSARegisterStack, SSAFlag]]: """This is the union `LowLevelILFunction.ssa_registers`, `LowLevelILFunction.ssa_register_stacks`, and `LowLevelILFunction.ssa_flags`""" if self.il_form == FunctionGraphType.LowLevelILSSAFormFunctionGraph: - return self.ssa_registers + self.ssa_register_stacks + self.ssa_flags + return self.ssa_registers + self.ssa_register_stacks + self.ssa_flags # type: ignore return [] def get_instruction_start(self, addr:int, arch:Optional['architecture.Architecture']=None) -> Optional[int]: |
