Пример #1
0
    def _get_segments(self):
        elf_file = UnpreparedElfFile()
        sections = [UnpreparedElfSection(elf_file, "test1", data=ByteArray("test1 data")),
                    UnpreparedElfSection(elf_file, "test2", data=ByteArray("test2 data"))]

        empty_sec_seg = SectionedElfSegment(None)
        full_sec_seg = SectionedElfSegment(elf_file, sections=sections)
        
        head_seg = HeaderElfSegment(None)
        prep_head_seg = HeaderElfSegment(None)
        prep_head_seg.prepare(37, PROG_HEADER_SIZE)
        
        data = ByteArray("pants")
        full_data_seg = DataElfSegment(None, vaddr=DATA_BASE, paddr=PHYS_BASE, data=data)
        nobits_data_seg = DataElfSegment(None, vaddr=DATA_BASE, paddr=PHYS_BASE, data=data, memsz=10)

        return empty_sec_seg, full_sec_seg, head_seg, prep_head_seg, full_data_seg, nobits_data_seg
Пример #2
0
 def test_prepare(self):
     ef = UnpreparedElfFile()
     segment = SectionedElfSegment(None, align=0x1)
     new_sect = UnpreparedElfSection(None, "pants")
     ef.add_section(new_sect)
     segment.add_section(new_sect)
     ef.add_segment(segment)
     ef.add_segment(HeaderElfSegment(None))
     ef = ef.prepare(32, '<')
Пример #3
0
    def test_has_sections(self):
        seg = DataElfSegment()
        self.assertEquals(seg.has_sections(), False)

        seg = SectionedElfSegment(sections=[])
        self.assertEquals(seg.has_sections(), True)

        seg = HeaderElfSegment()
        self.assertEquals(seg.has_sections(), False)
Пример #4
0
    def test_getmemsz(self):
        seg = DataElfSegment()
        self.assertRaises(InvalidArgument, seg.get_memsz)
        data = ByteArray()
        data.memsz = 10
        seg.set_data(data)
        self.assertEquals(seg.get_memsz(), 10)

        seg = HeaderElfSegment()
        self.assertRaises(Unprepared, seg.get_memsz)
Пример #5
0
    def test_get_section(self):
        ef = SectionedElfSegment(sections=[])
        self.assertEquals(ef.get_sections(), [])

        data = ByteArray("pants")
        ef = DataElfSegment(data=data)
        self.assertRaises(InvalidArgument, ef.get_sections)

        seg = HeaderElfSegment()
        self.assertRaises(InvalidArgument, seg.get_sections)
Пример #6
0
    def test_add_section(self):
        ef = UnpreparedElfFile()
        sect = UnpreparedElfSection()
        ef.add_section(sect)
        self.assertEqual(ef.sections[-1], sect)

        seg = HeaderElfSegment()
        self.assertRaises(InvalidArgument, seg.add_section, sect)

        seg = DataElfSegment()
        self.assertRaises(InvalidArgument, seg.add_section, sect)
Пример #7
0
    def test_getfilesz(self):
        seg = DataElfSegment()
        self.assertRaises(InvalidArgument, seg.get_filesz)
        data = ByteArray("1234567890")
        data.memsz = 10
        seg.set_data(data)
        self.assertEquals(seg.get_filesz(), 10)
        seg = HeaderElfSegment()
        self.assertRaises(Unprepared, seg.get_filesz)

        seg = SectionedElfSegment()
        self.assertEqual(seg.get_filesz(), 0)
Пример #8
0
    def test_prepare(self):
        ef = DataElfSegment()
        ef.prepare(37)
        self.assertEqual(ef.prepared, True)
        self.assertEqual(ef.offset, 37)
        self.assertRaises(InvalidArgument, ef.prepare, 12)

        ef = DataElfSegment()
        self.assertRaises(InvalidArgument, ef.prepare, 37, 12)

        ef = HeaderElfSegment()
        self.assertRaises(InvalidArgument, ef.prepare, 12)
        ef.prepare(37, 12)
        self.assertEqual(ef.get_memsz(), 12)
        self.assertEqual(ef.offset, 37)
Пример #9
0
    def test_remove_section(self):
        seg = SectionedElfSegment()
        section = UnpreparedElfSection()
        self.assertRaises(InvalidArgument, seg.remove_section, section)
        seg.add_section(section)
        self.assertEqual(section in seg.sections, True)
        seg.remove_section(section)
        self.assertEqual(section in seg.sections, False)

        self.assertRaises(InvalidArgument, seg.remove_section, section)

        seg = DataElfSegment()
        data = ByteArray("foo")
        seg.set_data(data)
        self.assertRaises(InvalidArgument, seg.remove_section, None)

        seg = HeaderElfSegment()
        self.assertRaises(InvalidArgument, seg.remove_section, None)
Пример #10
0
    def test_copy(self):
        seg = DataElfSegment()
        new_seg = seg.copy()

        seg = SectionedElfSegment()
        seg.sections = [UnpreparedElfSection("test")]
        new_seg = seg.copy()

        seg = DataElfSegment()
        seg._data = ByteArray()
        new_seg = seg.copy()

        seg = DataElfSegment()
        seg.prepare(34)
        new_seg = seg.copy()

        seg = HeaderElfSegment()
        new_Seg = seg.copy()
Пример #11
0
    def test_copy_into(self):
        elf_from = UnpreparedElfFile()
        elf_to = UnpreparedElfFile()
        seg = DataElfSegment(elf_from, ByteArray("pants"))
        new_seg = seg.copy_into(elf_to)

        seg = SectionedElfSegment(elf_from)
        seg.sections = [UnpreparedElfSection(elf_from, "test")]
        new_seg = seg.copy_into(elf_to)

        seg = DataElfSegment(elf_from, ByteArray("pants"))
        seg._data = ByteArray()
        new_seg = seg.copy_into(elf_to)

        seg = DataElfSegment(elf_from, ByteArray("pants"))
        seg.prepare(34)
        new_seg = seg.copy_into(elf_to)

        seg = HeaderElfSegment(elf_from)
        new_seg = seg.copy_into(elf_to)
Пример #12
0
    def _initialise_segments(self, hdr, f, prepare):
        """Initialise instance from program headers."""
        # Now load all the program headers
        #
        # "The time has come," the developer said, "to talk of many
        # things: Of section to segment mapping and scatter load, of
        # cabbages and kings, and why the RVCT linker is on drugs and
        # whether pigs have wings."
        #
        # There are two ways of determining which sections belong in a
        # segment:
        #
        # 1) In most cases a section is in a segment if its virtual
        #    address range falls in the virtual address range of the
        #    segment.  These segments tend to contain multiple
        #    PROGBITS sections and may end with a NOBITS section.
        #
        # 2) In the case of segments build with RVCT's scatter load
        #    support the virtual address of the included sections can
        #    be anywhere in memory.  In this case a section is in the
        #    segment if its data file offset falls in the offset range
        #    of the segment.  These segments can contain multiple
        #    PROGBITS and NOBITS sections in any order.  The file size
        #    of the segment is the filesize of all of the PROGBITS
        #    sections.  The memory size of the segment is the sum of
        #    the size of all of the sections, not the difference
        #    between the lowest and highest virtual addresses.
        #
        # Some other things about ELF files that you need to know:
        #
        # a) Segments can overlap, and sections can appear in multiple
        #    segments.
        #
        # b) Some sections do not appear in any segments.  These tend
        #    to be the symbol table and other debugging data.
        #
        # c) The offsets of NOBITS sections tend to be the same as the
        #    offset for the next PROGBITS section, even if it is in
        #    the next segment.  However, sometimes NOBITS sections
        #    appear at the beginning of a segment.
        #
        # d) The address offset from the start of a segment and the
        #    file offset from the start of the segment are not
        #    necessarily the same.
        #
        # Therefore, to map sections to segments involves two passes:
        #
        # 1) Find all of the sections that fall in the segment virtual
        #    address range.
        #
        # 2) Find all of the remaining sections that fall in the file
        #    offset range.  If any are found then mark the segment as
        #    a scatter-load segment.
        #
        # The file size and memory size of a segment depends on
        # whether or not it is a scatter load segment.  For scatter
        # load files, the section that has the latest offset from the
        # beginning of the section is used, while for non-scatter-load
        # segments, the section with the largest virtual address is
        # used.
        #
        # File offsets cannot be used for both types of segments
        # because broken linkers can produce sections with
        # inconsistant virtual address to file offset mappings and
        # this will make elfweaver produce segments with incorrect
        # file sizes or memory sizes.
        #
        # "O Readers," said the developer, "You've had a pleasant run!
        # Shall we start the code again?" But answer came there none--
        # And this was scarcely odd, because no-one would read this far
        # for fun.

        phoff = hdr.e_phoff
        self._ph_offset = phoff
        self.segments = []

        # Short circuit the return.
        if hdr.e_phoff == 0:
            return

        ph_list = self._get_headers(hdr, f, ELF_PH_CLASSES, hdr.e_phoff,
                                    hdr.e_phentsize, hdr.e_phnum)
        phentsize = hdr.e_phentsize

        sheaders = self._get_section_headers(hdr, f)
        for ph in ph_list:
            # Map segments to sections, pass 1.
            if ph.p_type != PT_PHDR:
                sects = []
                for (section, sh) in zip(self.sections, sheaders):
                    # See if the section's virtual address range falls within
                    # the virtual address range of the segment.
                    low = ph.p_vaddr
                    high = low + ph.p_memsz
                    addr = section.address
                    if low <= addr < high and addr + section.get_size() <= high:
                        section.set_in_segment_offset(sh.sh_offset -
                                                      ph.p_offset)
                        sects.append(section)

                if sects == []:
                    data = f.get_data(ph.p_offset, ph.p_filesz)
                    data.memsz = ph.p_memsz
                    es = DataElfSegment(ph=ph, data=data)
                else:
                    es = SectionedElfSegment(ph=ph, sections=sects)
            else:
                es = HeaderElfSegment(ph=ph)
            self.segments.append(es)

        # Map segments to sections, pass 2
        for ph, es in zip(ph_list, self.segments):
            if ph.p_type != PT_PHDR:
                for (section, sh) in zip(self.sections, sheaders):
                    # Scatter-load sections do not appear in
                    # multiple segments, so skip sections that
                    # are already in some segment.
                    if section.is_in_segment():
                        continue
                    # See if the section's file offset range
                    # falls within the file offset range of
                    # the segment.  Remember that the trailing
                    # BSS section can have the offset of the
                    # next section
                    if ph.p_offset <= sh.sh_offset <= ph.p_offset + ph.p_filesz and \
                           ((section.type == SHT_NOBITS and sh.sh_offset != ph.p_offset) or \
                            (section.type != SHT_NOBITS and section.get_size() > 0 and \
                             sh.sh_offset + section.get_size() <= ph.p_offset + ph.p_filesz)):
                        section.set_in_segment_offset(sh.sh_offset -
                                                      ph.p_offset)
                        es.add_section(section)
                        es.set_scatter_load()
                prog_header_size = None
            else:
                prog_header_size = phentsize * hdr.e_phnum

            # Now mark the segment as prepared.
            if prepare:
                es.prepare(ph.p_offset, prog_header_size)