Exemple #1
0
    def test_setdata(self):
        ef = DataElfSegment()
        data = ByteArray("foo")
        ef.set_data(data)
        self.assertEqual(ef.get_file_data(), data)

        ef = SectionedElfSegment(sections=[])
        self.assertRaises(InvalidArgument, ef.set_data, data)
Exemple #2
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)
Exemple #3
0
    def test_get_program_header(self):
        data = ByteArray()
        data.memsz = 0
        seg = DataElfSegment(data=data)
        self.assertRaises(Unprepared, seg.get_program_header, "<", 32)
        seg.prepare(0)
        self.assertRaises(InvalidArgument, seg.get_program_header, "<", 33)
        self.assertRaises(InvalidArgument, seg.get_program_header, "ads", 32)

        ph = seg.get_program_header("<", 32)
        self.assertEquals(ph.todata(), Elf32ProgramHeader("<").todata())
Exemple #4
0
    def test_get_program_header(self):
        data = ByteArray()
        data.memsz = 0
        seg = DataElfSegment(None, data = data)
        self.assertRaises(Unprepared, seg.get_program_header, '<', 32)
        seg.prepare(0)
        self.assertRaises(InvalidArgument, seg.get_program_header, '<', 33)
        self.assertRaises(InvalidArgument, seg.get_program_header, 'ads', 32)

        ph = seg.get_program_header('<', 32)
        self.assertEquals(ph.todata(), Elf32ProgramHeader('<').todata())
Exemple #5
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)
Exemple #6
0
    def test_get_file_data(self):
        ef = SectionedElfSegment(sections=[])
        self.assertRaises(InvalidArgument, ef.get_file_data)

        data = ByteArray("pants")
        ef = DataElfSegment(data=data)
        self.assertEqual(ef.get_file_data(), data)
Exemple #7
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
Exemple #8
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)
Exemple #9
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)
Exemple #10
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)
Exemple #11
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)
Exemple #12
0
    def test_add_section(self):
        seg = DataElfSegment()
        data = ByteArray("foo")
        seg.set_data(data)
        section = UnpreparedElfSection()
        self.assertRaises(InvalidArgument, seg.add_section, section)

        seg = SectionedElfSegment()
        seg.add_section(section)
        self.assertEqual(section in seg.sections, True)
Exemple #13
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)
Exemple #14
0
    def test_setdata(self):
        ef = DataElfSegment()
        data = ByteArray("foo")
        ef.set_data(data)
        self.assertEqual(ef.get_file_data(), data)

        ef = SectionedElfSegment(sections=[])
        self.assertRaises(InvalidArgument, ef.set_data, data)
Exemple #15
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)
Exemple #16
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)
Exemple #17
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)
Exemple #18
0
    def test_add_section(self):
        seg = DataElfSegment()
        data = ByteArray("foo")
        seg.set_data(data)
        section = UnpreparedElfSection()
        self.assertRaises(InvalidArgument, seg.add_section, section)

        seg = SectionedElfSegment()
        seg.add_section(section)
        self.assertEqual(section in seg.sections, True)
Exemple #19
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)
Exemple #20
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()
Exemple #21
0
 def test_add_segment(self):
     ef = UnpreparedElfFile()
     seg = DataElfSegment(None, data=ByteArray("pants"))
     ef.add_segment(seg)
     self.assertEqual(ef.segments[-1], seg)
Exemple #22
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)
Exemple #23
0
 def test_remove_nobits(self):
     seg = DataElfSegment()
     self.assertRaises(InvalidArgument, seg.remove_nobits)
Exemple #24
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)
Exemple #25
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()