Python idc.SegName() Examples
The following are 30
code examples of idc.SegName().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
idc
, or try the search function
.
Example #1
Source File: dump_section_list.py From python-idb with Apache License 2.0 | 8 votes |
def print_section_list(): for s in idautils.Segments(): seg = idaapi.getseg(s) print("%s" % idc.SegName(s)) print(" - start address: 0x%x" % seg.startEA) print(" - sclass: 0x%x" % seg.sclass) print(" - orgbase: 0x%x" % seg.orgbase) print(" - flags: 0x%x" % seg.flags) print(" - align: 0x%x" % seg.align) print(" - comb: 0x%x" % seg.comb) print(" - perm: 0x%x" % seg.perm) print(" - bitness: 0x%x" % seg.bitness) print(" - sel: 0x%x" % seg.sel) # print(' - defsr: 0x%x' % seg.defsr) print(" - type: 0x%x" % seg.type) print(" - color: 0x%x" % seg.color)
Example #2
Source File: configuration_file.py From idasec with GNU Lesser General Public License v2.1 | 6 votes |
def create_call_map(self, ftype): assert_ida_available() import idc import idautils seg_mapping = {idc.SegName(x): (idc.SegStart(x), idc.SegEnd(x)) for x in idautils.Segments()} imports = seg_mapping[".idata"] if ftype == PE else seg_mapping['.plt'] start, stop = seg_mapping[".text"] current = start while current <= stop: inst = current if idc.GetMnem(inst) in ["call", "jmp"]: value = idc.GetOperandValue(inst, 0) name = idc.GetOpnd(inst, 0) if imports[0] <= value <= imports[1]: entry = self.config.call_map.add() entry.address = inst entry.name = name current = idc.NextHead(current, stop)
Example #3
Source File: generic_analysis.py From idasec with GNU Lesser General Public License v2.1 | 6 votes |
def post_analysis_stuff(self, results): if results.has_formula(): self.action_selector.addItem(self.parent.HIGHLIGHT_CODE) self.action_selector.addItem(self.parent.GRAPH_DEPENDENCY) self.formula_area.setText(self.parent.results.formula) if results.has_values(): self.action_selector.addItem(self.parent.DISASS_UNKNOWN_TARGET) self.action_selector.setEnabled(True) self.action_button.setEnabled(True) report = HTMLReport() report.add_title("Results", size=3) report.add_table_header(["address", "assertion", "status", "values"]) addr = make_cell("%x" % results.target) status = make_cell(results.get_status(), color=results.color, bold=True) vals = "" for value in results.values: flag = idc.GetFlags(value) typ = self.type_to_string(flag) vals += "%x type:%s seg:%s fun:%s<br/>" % (value, typ, idc.SegName(value), idc.GetFunctionName(value)) report.add_table_line([addr, make_cell(cgi.escape(results.query)), status, make_cell(vals)]) report.end_table() data = report.generate() self.result_area.setHtml(data)
Example #4
Source File: segment.py From ida_kernelcache with MIT License | 6 votes |
def kernelcache_kext(ea): """Return the name of the kext to which the given linear address belongs. Only works if segments have been renamed using initialize_segments(). NOTE: Kexts are not well distinguished on the new iOS 12 merged kernelcache format. Do not rely on this function. """ # TODO: This doesn't work on 12-merged kernelcaches! name = idc.SegName(ea) or '' if ':' in name: return idc.SegName(ea).split(':', 1)[0] if _kext_regions: for start, end, kext in _kext_regions: if start <= ea < end: return kext return None
Example #5
Source File: segment.py From ida_kernelcache with MIT License | 6 votes |
def initialize_segments(): """Rename the kernelcache segments in IDA according to the __PRELINK_INFO data. Rename the kernelcache segments based on the contents of the __PRELINK_INFO dictionary. Segments are renamed according to the scheme '[<kext>:]<segment>.<section>', where '<kext>' is the bundle identifier if the segment is part of a kernel extension. The special region containing the Mach-O header is renamed '[<kext>:]<segment>.HEADER'. """ # First rename the kernel segments. _log(1, 'Renaming kernel segments') kernel_skip = ['__PRELINK_TEXT', '__PLK_TEXT_EXEC', '__PRELINK_DATA', '__PLK_DATA_CONST'] _initialize_segments_in_kext(None, kernel.base, skip=kernel_skip) # Process each kext identified by the __PRELINK_INFO. In the new kernelcache format 12-merged, # the _PrelinkExecutableLoadAddr key is missing for all kexts, so no extra segment renaming # takes place. prelink_info_dicts = kernel.prelink_info['_PrelinkInfoDictionary'] for kext_prelink_info in prelink_info_dicts: kext = kext_prelink_info.get('CFBundleIdentifier', None) mach_header = kext_prelink_info.get('_PrelinkExecutableLoadAddr', None) if kext is not None and mach_header is not None: orig_kext = idc.SegName(mach_header).split(':', 1)[0] if '.kpi.' not in kext and orig_kext != kext: _log(0, 'Renaming kext {} -> {}', orig_kext, kext) _log(1, 'Renaming segments in {}', kext) _initialize_segments_in_kext(kext, mach_header)
Example #6
Source File: stub.py From ida_kernelcache with MIT License | 6 votes |
def initialize_stub_symbols(make_thunk=True): """Populate IDA with information about the stubs in an iOS kernelcache. Search through the kernelcache for stubs (__stubs sections) and rename each stub function according to the target function it calls. Arm64 only. Options: make_thunk: Set the thunk attribute for each stub function. Default is True. """ next_stub = internal.make_name_generator(kernelcache_stub_suffix) for ea in idautils.Segments(): segname = idc.SegName(ea) if not segname.endswith('__stubs'): continue _log(3, 'Processing segment {}', segname) _process_stubs_section(ea, make_thunk, next_stub)
Example #7
Source File: get_cfg.py From mcsema with Apache License 2.0 | 6 votes |
def is_ELF_got_pointer(ea): """Returns `True` if this is a pointer to a pointer stored in the `.got` section of an ELF binary. For example, `__gmon_start___ptr` is a pointer in the `.got` that will be fixed up to contain the address of the external function `__gmon_start__`. We don't want to treat `__gmon_start___ptr` as external because it is really a sort of local variable that will will resolve with a data cross-reference.""" seg_name = idc.SegName(ea).lower() if ".got" not in seg_name: return False name = get_symbol_name(ea) target_ea = get_reference_target(ea) target_name = get_true_external_name(get_symbol_name(target_ea)) if target_name not in name: return False return is_referenced_by(target_ea, ea)
Example #8
Source File: offset.py From ida_kernelcache with MIT License | 6 votes |
def initialize_data_offsets(): """Convert offsets in data segments into offsets in IDA. Segment names must be initialized with segments.initialize_segments() first. """ # Normally, for user-space programs, this operation would be dangerous because there's a good # chance that a valid userspace address would happen to show up in regular program data that is # not actually an address. However, since kernel addresses are numerically much larger, the # chance of this happening is much less. for seg in idautils.Segments(): name = idc.SegName(seg) if not (name.endswith('__DATA_CONST.__const') or name.endswith('__got') or name.endswith('__DATA.__data')): continue for word, ea in idau.ReadWords(seg, idc.SegEnd(seg), addresses=True): if idau.is_mapped(word, value=False): idc.OpOff(ea, 0, 0)
Example #9
Source File: dsc_fix.py From dsc_fix with GNU General Public License v3.0 | 5 votes |
def label_and_fix_branch_islands(dsc_file, adrfind, jmp_to_code): """ labels, comments and fixes code flow on branch islands """ jmpaddrs = sorted(set(jmp_to_code.keys())) dsc_file.seek(0) header = dsc_header(dsc_file) dsc_file.seek(header.images_offset) i = 0 jmpaddrslen = len(jmpaddrs) for addr in jmpaddrs: print "status: 0x%X %d/%d" % (addr, i, jmpaddrslen) res = adrfind.find(addr) if not res: print "[!] coudln't find addr for addr:", addr dylib_path, dsc_offset, macho_offset = res exportname = adrfind.get_export_name_for_addr(addr) if _IN_IDA: eas = jmp_to_code[addr] for ea in eas: idc.MakeRptCmt(ea, "%s'%s" % (dylib_path, exportname)) if "branch_islands" in idc.SegName(ea): make_name(ea, exportname) # patch them to "RET" so they would return memcpy(ea, "\xC0\x03\x5F\xD6") make_islands_xrefs_force_bl_call(ea) else: print "[+] \\\\ %s" % exportname i += 1
Example #10
Source File: luac_proc.py From lua_re with GNU Affero General Public License v3.0 | 5 votes |
def init_seginfo(self): #print("seg len:%d\n" % len(list(idautils.Segments()))) for seg in idautils.Segments(): segname = idc.SegName(seg) if segname.startswith('func_'): self.segstarts[idc.SegStart(seg)] = segname self.segends[idc.SegEnd(seg)] = segname #print("segname:%s\n" % segname) #print("add_func() called ret:%d" % add_func(idc.SegStart(seg), idc.SegEnd(seg)))
Example #11
Source File: dsc_fix.py From dsc_fix with GNU General Public License v3.0 | 5 votes |
def make_islands_xrefs_force_bl_call(ea, verbose=True): """ makes all BL references to a branch islands as call """ segname = idc.SegName(ea) if verbose: print "[+] forcing bl call on: %s [0x%X]" % (segname, ea) if "branch_islands" in segname: idc.SetFunctionFlags(ea, idc.GetFunctionFlags(ea) & (0xffffffff - 1)) for x in idautils.XrefsTo(ea): make_islands_xrefs_force_bl_call(x.frm) return idc.ArmForceBLCall(ea)
Example #12
Source File: __init__.py From flare-ida with Apache License 2.0 | 5 votes |
def append_segment(segment_name): """ Add a new segment to the IDB file and return its starting address. Information about function arguments will be stored here. Only works if the segment name is not used yet. This does not affect the original binary. Arguments: segment_name -- the name of the segment to be added """ for segment in idautils.Segments(): if idc.SegName(segment) == segment_name: g_logger.warning('Segment ' + segment_name + ' already exists') return idc.SegStart(segment) new_segment_start = get_end_of_last_segment() g_logger.debug('Adding new segment at 0x%08x' % new_segment_start) if not idc.AddSeg(new_segment_start, (new_segment_start+NEW_SEGMENT_SIZE), 0, 1, 0, idaapi.scPub) == 1: raise FailedToAppendSegmentException('Could not add segment') # set new segment's attributes if not idc.RenameSeg(new_segment_start, segment_name): raise FailedToAppendSegmentException('Could not rename segment') if not idc.SetSegClass(new_segment_start, 'DATA'): raise FailedToAppendSegmentException('Could not set segment class') if not idc.SegAlign(new_segment_start, idc.saRelPara): raise FailedToAppendSegmentException('Could not align segment') if not idc.SetSegAddressing(new_segment_start, 1): # 1 -- 32 bit raise FailedToAppendSegmentException( 'Could not set segment addressing') return new_segment_start
Example #13
Source File: objc2_xrefs_helper.py From flare-ida with Apache License 2.0 | 5 votes |
def find_all_segments(self,segment_names): segments={name:None for name in segment_names} for seg_va in Segments(): seg_name=SegName(seg_va) if seg_name in segment_names: segments[seg_name]=(seg_va,SegEnd(seg_va)) return segments
Example #14
Source File: yara_fn.py From python-idb with Apache License 2.0 | 5 votes |
def get_segments(): """ fetch the segments in the current executable. """ for segstart in idautils.Segments(): segend = idaapi.getseg(segstart).endEA segsize = segend - segstart segname = str(idc.SegName(segstart)).rstrip("\x00") segbuf = get_segment_buffer(segstart) yield Segment(segstart, segend, segname, segbuf)
Example #15
Source File: offset.py From ida_kernelcache with MIT License | 5 votes |
def initialize_offset_symbols(): """Populate IDA with information about the offsets in an iOS kernelcache. Search through the kernelcache for global offset tables (__got sections), convert each offset into an offset type in IDA, and rename each offset according to its target. This function does nothing in the newer 12-merged format kernelcache. """ next_offset = internal.make_name_generator(kernelcache_offset_suffix) for ea in idautils.Segments(): segname = idc.SegName(ea) if not segname.endswith('__got'): continue _log(2, 'Processing segment {}', segname) _process_offsets_section(ea, next_offset)
Example #16
Source File: collect_classes.py From ida_kernelcache with MIT License | 5 votes |
def _collect_metaclasses(): """Collect OSMetaClass information from all kexts in the kernelcache.""" # Collect associations from class names to metaclass instances and vice versa. metaclass_to_classname_builder = _OneToOneMapFactory() metaclass_to_class_size = dict() metaclass_to_meta_superclass = dict() def found_metaclass(metaclass, classname, class_size, meta_superclass): metaclass_to_classname_builder.add_link(metaclass, classname) metaclass_to_class_size[metaclass] = class_size metaclass_to_meta_superclass[metaclass] = meta_superclass for ea in idautils.Segments(): segname = idc.SegName(ea) if not _should_process_segment(ea, segname): continue _log(2, 'Processing segment {}', segname) _process_mod_init_func_section_for_metaclasses(ea, found_metaclass) # Filter out any class name (and its associated metaclasses) that has multiple metaclasses. # This can happen when multiple kexts define a class but only one gets loaded. def bad_classname(classname, metaclasses): _log(0, 'Class {} has multiple metaclasses: {}', classname, ', '.join(['{:#x}'.format(mc) for mc in metaclasses])) # Filter out any metaclass (and its associated class names) that has multiple class names. I # have no idea why this would happen. def bad_metaclass(metaclass, classnames): _log(0, 'Metaclass {:#x} has multiple classes: {}', metaclass, ', '.join(classnames)) # Return the final dictionary of metaclass info. metaclass_to_classname = metaclass_to_classname_builder.build(bad_metaclass, bad_classname) metaclass_info = dict() for metaclass, classname in metaclass_to_classname.items(): meta_superclass = metaclass_to_meta_superclass[metaclass] superclass_name = metaclass_to_classname.get(meta_superclass, None) metaclass_info[metaclass] = classes.ClassInfo(classname, metaclass, None, None, metaclass_to_class_size[metaclass], superclass_name, meta_superclass) return metaclass_info
Example #17
Source File: collect_classes.py From ida_kernelcache with MIT License | 5 votes |
def _process_mod_init_func_for_metaclasses(func, found_metaclass): """Process a function from the __mod_init_func section for OSMetaClass information.""" _log(4, 'Processing function {}', idc.GetFunctionName(func)) def on_BL(addr, reg): X0, X1, X3 = reg['X0'], reg['X1'], reg['X3'] if not (X0 and X1 and X3): return _log(5, 'Have call to {:#x}({:#x}, {:#x}, ?, {:#x})', addr, X0, X1, X3) # OSMetaClass::OSMetaClass(this, className, superclass, classSize) if not idc.SegName(X1).endswith("__TEXT.__cstring") or not idc.SegName(X0): return found_metaclass(X0, idc.GetString(X1), X3, reg['X2'] or None) _emulate_arm64(func, idc.FindFuncEnd(func), on_BL=on_BL)
Example #18
Source File: IDAConnector.py From DIE with MIT License | 5 votes |
def is_system_lib(ea): """ Returns true if a segment belongs to a system library, in which case we don't want to recursively hook calls. Covers Windows, Linux, Mac, Android, iOS @param ea: an effective address within a function """ name = idc.SegName(ea) if not name: return False # the below is for Windows kernel debugging if name == 'nt': return True sysfolders = [re.compile("\\\\windows\\\\", re.I), re.compile("\\\\Program Files ", re.I), re.compile("/usr/", re.I), \ re.compile("/system/", re.I), re.compile("/lib/", re.I)] m = idc.GetFirstModule() while m: path = idc.GetModuleName(m) if re.search(name, path): if any(regex.search(path) for regex in sysfolders): return True else: return False m = idc.GetNextModule(m) return False
Example #19
Source File: get_cfg.py From mcsema with Apache License 2.0 | 5 votes |
def recover_region(M, region_name, region_ea, region_end_ea, exported_vars): """Recover the data and cross-references from a segment. The data of a segment is stored verbatim within the protobuf, and accompanied by a series of variable and cross-reference entries.""" seg_name = idc.SegName(region_ea) DEBUG("Recovering region {} [{:x}, {:x}) in segment {}".format( region_name, region_ea, region_end_ea, seg_name)) seg = idaapi.getseg(region_ea) # An item spans two regions. This may mean that there's a reference into # the middle of an item. This happens with strings. item_size = idc.ItemSize(region_end_ea - 1) if 1 < item_size: DEBUG(" ERROR: Segment should probably include {} more bytes".format( item_size - 1)) S = M.segments.add() S.ea = region_ea S.data = read_bytes_slowly(region_ea, region_end_ea) S.read_only = (seg.perm & idaapi.SEGPERM_WRITE) == 0 S.is_external = is_external_segment_by_flags(region_ea) S.is_thread_local = is_tls_segment(region_ea) S.name = seg_name.format('utf-8') S.is_exported = region_ea in exported_vars if region_name != seg_name: S.variable_name = region_name.format('utf-8') DEBUG_PUSH() recover_region_cross_references(M, S, region_ea, region_end_ea) recover_region_variables(M, S, region_ea, region_end_ea, exported_vars) DEBUG_POP()
Example #20
Source File: exception.py From mcsema with Apache License 2.0 | 5 votes |
def recover_exception_table(): """ Recover the CIE and FDE entries from the segment .eh_frame """ seg_eas = [ea for ea in idautils.Segments() if not is_invalid_ea(ea)] for seg_ea in seg_eas: seg_name = idc.SegName(seg_ea) if seg_name in [".eh_frame", "__eh_frame"]: recover_frame_entries(seg_ea) break recover_rtti()
Example #21
Source File: exception.py From mcsema with Apache License 2.0 | 5 votes |
def recover_frame_entries(seg_ea): if seg_ea == idc.BADADDR: return DEBUG("Recover entries from section : {}".format(idc.SegName(seg_ea))) ea = idc.SegStart(seg_ea) end_ea = idc.SegEnd(seg_ea) while ea != idc.BADADDR and ea < end_ea: ea = format_entries(ea)
Example #22
Source File: util.py From mcsema with Apache License 2.0 | 5 votes |
def is_destructor_segment(ea): """Returns `True` if the segment containing `ea` belongs to global destructor section""" seg_ea = idc.SegStart(ea) seg_name = idc.SegName(seg_ea).lower() if seg_name in [".fini_array", ".dtor"]: return True return False
Example #23
Source File: util.py From mcsema with Apache License 2.0 | 5 votes |
def is_constructor_segment(ea): """Returns `True` if the segment containing `ea` belongs to global constructor section""" seg_ea = idc.SegStart(ea) seg_name = idc.SegName(seg_ea).lower() if seg_name in [".init_array", ".ctor"]: return True return False
Example #24
Source File: util.py From mcsema with Apache License 2.0 | 5 votes |
def is_external_segment(ea): """Returns `True` if the segment containing `ea` looks to be solely containing external references.""" global _NOT_EXTERNAL_SEGMENTS seg_ea = idc.SegStart(ea) if seg_ea in _NOT_EXTERNAL_SEGMENTS: return False if seg_ea in _EXTERNAL_SEGMENTS: return True if is_external_segment_by_flags(ea): _EXTERNAL_SEGMENTS.add(seg_ea) return True ext_types = [] seg_name = idc.SegName(seg_ea).lower() if IS_ELF: if ".got" in seg_name or ".plt" in seg_name: _EXTERNAL_SEGMENTS.add(seg_ea) return True elif IS_PE: if ".idata" == seg_name: # Import table. _EXTERNAL_SEGMENTS.add(seg_ea) return True _NOT_EXTERNAL_SEGMENTS.add(seg_ea) return False
Example #25
Source File: util.py From mcsema with Apache License 2.0 | 5 votes |
def segment_contains_external_function_pointers(seg_ea): """Returns `True` if a segment contains pointers to external functions.""" try: seg_name = idc.SegName(seg_ea) return seg_name.lower() in (".idata", ".plt.got") except: return False
Example #26
Source File: util.py From mcsema with Apache License 2.0 | 5 votes |
def is_tls_segment(ea): try: seg_name = idc.SegName(ea) return seg_name in (".tbss", ".tdata", ".tls") except: return False # Returns `True` if `ea` looks like a thread-local thing.
Example #27
Source File: yara_fn.py From idawilli with Apache License 2.0 | 5 votes |
def get_segments(): ''' fetch the segments in the current executable. ''' for segstart in idautils.Segments(): segend = idaapi.getseg(segstart).end_ea segsize = segend - segstart segname = str(idc.SegName(segstart)).rstrip('\x00') segbuf = get_segment_buffer(segstart) yield Segment(segstart, segend, segname, segbuf)
Example #28
Source File: idasec_core.py From idasec with GNU Lesser General Public License v2.1 | 5 votes |
def update_mapping(self): pass self.fun_mapping = {idc.GetFunctionName(x): (idaapi.get_func(x).startEA, idaapi.get_func(x).endEA-1) for x in idautils.Functions()} self.seg_mapping = {idc.SegName(x): (idc.SegStart(x), idc.SegEnd(x)) for x in idautils.Segments()}
Example #29
Source File: get_cfg.py From mcsema with Apache License 2.0 | 4 votes |
def is_ELF_thunk_by_structure(ea): """Try to manually identify an ELF thunk by its structure.""" global _INVALID_THUNK_ADDR if ".plt" not in idc.SegName(ea).lower(): return _INVALID_THUNK_ADDR # Scan through looking for a branch, either direct or indirect. inst = None for i in range(4): # 1 is good enough for x86, 4 for aarch64. inst, _ = decode_instruction(ea) if not inst: return _INVALID_THUNK_ADDR # elif is_direct_jump(inst): # ea = get_direct_branch_target(inst) # inst = None elif is_indirect_jump(inst) or is_direct_jump(inst): ea = inst.ea break else: ea = inst.ea + inst.size inst = None if not inst: return _INVALID_THUNK_ADDR target_ea = get_reference_target(inst.ea) if ".got.plt" == idc.SegName(target_ea).lower(): target_ea = get_reference_target(target_ea) # For AArch64, the thunk structure is something like: # .plt:000400470 .atoi # .plt:000400470 ADRP X16, #off_411000@PAGE # .plt:000400474 LDR X17, [X16,#off_411000@PAGEOFF] # .plt:000400478 ADD X16, X16, #off_411000@PAGEOFF # .plt:00040047C BR X17 ; atoi # # With: # # extern:000411070 ; int atoi(const char *nptr) # extern:000411070 IMPORT atoi # For x86, the thunk structure is something like: # # .plt:00041F10 _qsort proc near # .plt:00041F10 jmp cs:off_31F388 # .plt:00041F10 _qsort endp # # With: # # .got.plt:0031F388 off_31F388 dq offset qsort # # With # extern:0031F388 ; void qsort(void *base, ...) # extern:0031F388 extrn qsort:near if is_invalid_ea(target_ea): return _INVALID_THUNK_ADDR return True, target_ea
Example #30
Source File: segment.py From ida_kernelcache with MIT License | 4 votes |
def _initialize_segments_in_kext(kext, mach_header, skip=[]): """Rename the segments in the specified kext.""" def log_seg(segname, segstart, segend): _log(3, '+ segment {: <20} {:x} - {:x} ({:x})', segname, segstart, segend, segend - segstart) def log_sect(sectname, sectstart, sectend): _log(3, ' section {: <20} {:x} - {:x} ({:x})', sectname, sectstart, sectend, sectend - sectstart) def log_gap(gapno, start, end, mapped): mapped = 'mapped' if mapped else 'unmapped' _log(3, ' gap {: <20} {:x} - {:x} ({:x}, {})', gapno, start, end, end - start, mapped) def process_region(segname, name, start, end): assert end >= start if segname in skip: _log(2, 'Skipping segment {}', segname) return newname = '{}.{}'.format(segname, name) if kext: newname = '{}:{}'.format(kext, newname) if start == end: _log(2, 'Skipping empty region {} at {:x}', newname, start) return ida_segstart = idc.SegStart(start) if ida_segstart == idc.BADADDR: _log(0, "IDA doesn't think this is a real segment: {:x} - {:x}", start, end) return ida_segend = idc.SegEnd(ida_segstart) if start != ida_segstart or end != ida_segend: _log(0, 'IDA thinks segment {} {:x} - {:x} should be {:x} - {:x}', newname, start, end, ida_segstart, ida_segend) return _log(2, 'Rename {:x} - {:x}: {} -> {}', start, end, idc.SegName(start), newname) idc.SegRename(start, newname) def process_gap(segname, gapno, start, end): mapped = idau.is_mapped(start) log_gap(gapno, start, end, mapped) if mapped: name = 'HEADER' if start == mach_header else '__gap_' + str(gapno) process_region(segname, name, start, end) for segname, segstart, segend, sects in _macho_segments_and_sections(mach_header): log_seg(segname, segstart, segend) lastend = segstart gapno = 0 for sectname, sectstart, sectend in sects: if lastend < sectstart: process_gap(segname, gapno, lastend, sectstart) gapno += 1 log_sect(sectname, sectstart, sectend) process_region(segname, sectname, sectstart, sectend) lastend = sectend if lastend < segend: process_gap(segname, gapno, lastend, segend) gapno += 1