Beispiel #1
0
 def symbol(self, matched_idx):
     assert 0 <= matched_idx < self.num_matched
     table_idx = 0
     section_desc = ''
     for mapping in self._filter_mappings:
         mapping_size = len(mapping)
         if matched_idx >= mapping_size:
             matched_idx -= mapping_size
             table_idx += 1
             continue
         (index, n_strx, n_type, n_sect, n_desc, n_value, symbol_name) = \
             self._symbol_tables[table_idx].symbols[mapping[matched_idx]]
         nlist = Nlist64(index=index,
                         n_strx=n_strx,
                         n_type=n_type,
                         n_sect=n_sect,
                         n_desc=n_desc,
                         n_value=n_value)
         if nlist.n_sect != 0:
             this_section = self._sections[nlist.n_sect]
             section_desc = '%s, %s' % \
                            (NullTerminatedStringField.get_string(this_section.segname),
                             NullTerminatedStringField.get_string(this_section.sectname))
         return nlist, symbol_name, section_desc
     assert False  # should never get here
Beispiel #2
0
 def __init__(self, seg_name, sect_name, bytes_):
     self.seg_name = None
     self.sect_name = None
     seg_name = NullTerminatedStringField.get_string(seg_name)
     sect_name = NullTerminatedStringField.get_string(sect_name)
     super(SectionBlock, self).__init__('Section: %s %s' % (seg_name, sect_name),
                                        seg_name=seg_name, sect_name=sect_name)
     self.parse_bytes(bytes_)
Beispiel #3
0
 def __init__(self, seg_name, sect_name, bytes_):
     self.seg_name = None
     self.sect_name = None
     seg_name = NullTerminatedStringField.get_string(seg_name)
     sect_name = NullTerminatedStringField.get_string(sect_name)
     super(SectionBlock,
           self).__init__('Section: %s %s' % (seg_name, sect_name),
                          seg_name=seg_name,
                          sect_name=sect_name)
     self.parse_bytes(bytes_)
Beispiel #4
0
    def parse(self, section_desc):
        section = section_desc.section
        self.initialize(section.offset, section.size)

        # Get the segment and section names
        seg_name = NullTerminatedStringField.get_string(section.segname)
        sect_name = NullTerminatedStringField.get_string(section.sectname)
        bytes_ = self.get_bytes()
        if seg_name == '__TEXT':
            data_section = TextSection(sect_name, bytes_)
        elif seg_name == '__DATA':
            data_section = DataSection(sect_name, bytes_)
        else:
            data_section = SectionBlock(seg_name, sect_name, bytes_)

        # If the section is inside a encrypted region (specificed by LC_ENCRYPTION_INFO),
        # we cannot parse it because we don't have the decryption key. So, we just
        # create a block without trying to parse its content.
        if self.mach_o.is_section_encrypted(section):
            data_section.name += ' [ENCRYPTED]'
            self.add_subrange(data_section, section.size)
            return

        if section.offset == 0:
            # .bss and .common sections only exist in VM but not in the file. So, they have an offset of 0
            # which aliases with the mach header. We do not add any subrange for these sections since
            # there is no data to parse / display.

            # TODO - in some iOS binraries, offset is set to 0 for many sections that should have data
            # Need to study them more to determine if offset is just not set proerly and we can
            # compute the offset from the first data section and the VM address.
            return
        elif section_desc.is_cstring():
            data_section = CstringSection(bytes_)
            cstring_br = self.add_subrange(data_section, section.size)
            for (offset, string) in data_section.items():
                unescaped_string = Unescape.convert(string)
                cstring_br.add_subrange(offset,
                                        len(string) + 1,
                                        data=Cstring(unescaped_string))
        elif section_desc.is_objc_methname():
            data_section = ObjCMethodNameSection(bytes_)
            obj_methname_br = self.add_subrange(data_section, section.size)
            for (offset, string) in data_section.items():
                unescaped_string = Unescape.convert(string)
                obj_methname_br.add_subrange(
                    offset,
                    len(string) + 1,
                    data=ObjCMethodName(unescaped_string))
        else:
            self.add_subrange(data_section, section.size)
Beispiel #5
0
 def __init__(self, sect_name, bytes_):
     sect_name = NullTerminatedStringField.get_string(sect_name)
     super(TextSection, self).__init__('__TEXT', sect_name, bytes_)
     self.name = 'TextSection: %s' % sect_name
Beispiel #6
0
 def __init__(self, sect_name, bytes_):
     sect_name = NullTerminatedStringField.get_string(sect_name)
     super(DataSection, self).__init__('__DATA', sect_name, bytes_)
     self.name = 'DataSection: %s' % sect_name
Beispiel #7
0
 def __init__(self, seg_name):
     self.seg_name = None
     seg_name = NullTerminatedStringField.get_string(seg_name)
     super(SegmentBlock, self).__init__('Segment: %s' % seg_name, color='cyan', bold=True, seg_name=seg_name)
Beispiel #8
0
 def __init__(self, sect_name, bytes_):
     sect_name = NullTerminatedStringField.get_string(sect_name)
     super(TextSection, self).__init__('__TEXT', sect_name, bytes_)
     self.name = 'TextSection: %s' % sect_name
Beispiel #9
0
 def __init__(self, sect_name, bytes_):
     sect_name = NullTerminatedStringField.get_string(sect_name)
     super(DataSection, self).__init__('__DATA', sect_name, bytes_)
     self.name = 'DataSection: %s' % sect_name