Esempio n. 1
0
    def _add_subtree(self, parent_id, br):
        def get_values(sr):
            if hasattr(sr.data, 'name'):
                desc = sr.data.name
            else:
                desc = str(sr.data)
            (start, stop) = sr.abs_range()
            return desc, format(start, ','), format(stop, ',')

        pi = ProgressIndicator('show byte ranges...', 1)
        for idx in xrange(len(br.subranges)):
            subrange = br.subranges[idx]
            child_id = parent_id + '.%d' % idx
            if not self.byte_range_tree.tree.exists(child_id):
                child_id = self.byte_range_tree.add(
                    parent_id, idx, values=get_values(subrange))
            if len(subrange.subranges) > 0:
                # if there are subsubranges, just insert 1st row so that the open icon is shown
                if not self.byte_range_tree.tree.exists(child_id + '.0'):
                    subsubrange = subrange.subranges[0]
                    self.byte_range_tree.add(child_id,
                                             0,
                                             values=get_values(subsubrange))
            pi.click()
        pi.done()
Esempio n. 2
0
    def _add_subtree(self, parent_id, br):
        def get_values(sr):
            if hasattr(sr.data, 'name'):
                desc = sr.data.name
            else:
                desc = str(sr.data)
            (start, stop) = sr.abs_range()
            return desc, format(start, ','), format(stop, ',')

        pi = ProgressIndicator('show byte ranges...', 1)
        for idx in xrange(len(br.subranges)):
            subrange = br.subranges[idx]
            child_id = parent_id + '.%d' % idx
            if not self.byte_range_tree.tree.exists(child_id):
                child_id = self.byte_range_tree.add(parent_id, idx, values=get_values(subrange))
            if len(subrange.subranges) > 0:
                # if there are subsubranges, just insert 1st row so that the open icon is shown
                if not self.byte_range_tree.tree.exists(child_id + '.0'):
                    subsubrange = subrange.subranges[0]
                    self.byte_range_tree.add(child_id, 0, values=get_values(subsubrange))
            pi.click()
        pi.done()
Esempio n. 3
0
    def parse(self, symtab_command):
        if symtab_command is None:
            return
        self.initialize(0, len(self.byte_range))
        if ProgressIndicator.ENABLED:
            progress = ProgressIndicator('parsing symbol table...', 4096)
        else:
            progress = None

        # Add nlist entries and string table section.
        sym_tab = SymbolTable(symtab_command.nsyms)
        sym_str_tab = SymbolStringTable()
        sym_br = self.add_section(symtab_command.symoff,
                                  symtab_command.nsyms * self.nlist_size,
                                  data=sym_tab)
        self.add_section(symtab_command.stroff,
                         symtab_command.strsize,
                         data=sym_str_tab)
        str_bytes_ = self.byte_range.bytes(
            symtab_command.stroff,
            symtab_command.stroff + symtab_command.strsize)

        # Parse all nlist entries
        for idx in xrange(symtab_command.nsyms):
            if progress is not None:
                progress.click()
            start = idx * self.nlist_size
            stop = start + self.nlist_size
            bytes_ = sym_br.bytes(start, stop)
            nlist = self.nlist_class(bytes_)
            # The original code was:
            #
            # sym_br.add_subrange(start, self.nlist_size, data=nlist)
            #
            # The problem is that for a real iOS app, there can be hundreds of thousands if not
            # millions of symbols and these Nlist and BytesRange objects consume a lot of memory.
            # (Each python object with attribute seems to consume at least 300B.)
            #
            # The solution is to deviate the framework and save the values of these nlist headers
            # into a big list.
            sym_tab.add(nlist)
            if nlist.n_strx == 0:
                # From nlist.h:
                #
                # Symbols with a index into the string table of zero (n_un.n_strx == 0) are
                # defined to have a null, "", name.  Therefore all string indexes to non null
                # names must not have a zero string index.  This is bit historical information
                # that has never been well documented.
                pass
            else:
                (sym_name,
                 total_len) = self._find_string(str_bytes_, nlist.n_strx)
                # Original code is:
                #
                # str_br.add_subrange(nlist.n_strx, total_len, data=SymtabString(nlist.n_strx, sym_name))
                #
                # Again, we avoid creating the byte range in order to reduce memory consumption.
                sym_str_tab.add(nlist.n_strx, sym_name)
        sym_tab.correlate_string_table(sym_str_tab)
        if progress is not None:
            progress.done()