def init_and_prepare_from_file(self, file_): """This method initialise an ElfFile from a given File object.""" ident = ElfIdentification() ident.fromdata(file_.get_data(0, ident.get_size())) if file_.size() < ident.get_size(): self.wordsize = 0 self.sections = [] self.segments = [] return self.wordsize = ident.wordsize self.endianess = ident.endianess header_data = file_.get_data(0, ELF_HEADER_CLASSES[self.wordsize].size()) hdr = ELF_HEADER_CLASSES[self.wordsize]() hdr.fromdata(header_data) self._initialise_header_information(hdr) self._initialise_sections(hdr, file_) self._initialise_symbol_tables(file_) self._initialise_relocs(file_) self._initialise_section_names() self._initialise_segments(hdr, file_) # FIXME: Mothra bug2591 # This code removes any zero-sized sections. # Perhaps not the right place to do it, but works around linkder # scripts that generate zero-sized sections. Note this may only # be a problem due to stupid scatter-load handling. self.sections = [s for s in self.sections if s.get_size() or not s.name] for segment in self.segments: if segment.has_sections(): segment.sections = [s for s in segment.sections if s.get_size() or not s.name]
def init_and_prepare_from_file(self, f): """This method initialise an ElfFile from a given File object.""" ident = ElfIdentification() ident.fromdata(f.get_data(0, ident.get_size())) self.wordsize = ident.wordsize self.endianess = ident.endianess header_data = f.get_data(0, ELF_HEADER_CLASSES[self.wordsize].size()) hdr = ELF_HEADER_CLASSES[self.wordsize]() hdr.fromdata(header_data) self._initialise_header_information(hdr) self._initialise_sections(hdr, f) self._initialise_symbol_table(self.wordsize, self.endianess) self._initialise_segments(hdr, f) # FIXME: Mothra bug2591 # This code removes any zero-sized sections. # Perhaps not the right place to do it, but works around linkder # scripts that generate zero-sized sections. Note this may only # be a problem due to stupid scatter-load handling. self.sections = [ s for s in self.sections if s.get_size() or not s.name ] for segment in self.segments: if segment.has_sections(): segment.sections = [ s for s in segment.sections if s.get_size() or not s.name ]
def test_expected(self): for file_name in elf_ph_expected: f = File(file_name, "rb") ident = ElfIdentification() ident.fromdata(f.get_data(0, 16)) if ident.wordsize == 32: data = f.get_data(0, Elf32Header.size()) header = Elf32Header() PhClass = Elf32ProgramHeader header.fromdata(data) elif ident.wordsize == 64: data = f.get_data(0, Elf64Header.size()) header = Elf64Header() header.fromdata(data) PhClass = Elf64ProgramHeader else: raise "Problem" self.assertEqual(header.e_phnum, len(elf_ph_expected[file_name])) entsize = header.e_phentsize wordsize = ident.wordsize hdr = ELF_HEADER_CLASSES[wordsize]() for i in range(header.e_phnum): ph_expect = elf_ph_expected[file_name][i] ph_data = f.get_data(header.e_phoff + (i * entsize), entsize) ph = PhClass(header.ident.endianess) ph.fromdata(ph_data, hdr) self.assertEqual(ph.todata(), ph_data) self.assertEqual(ph.p_type, ph_expect[0]) self.assertEqual(ph.p_offset, ph_expect[1]) self.assertEqual(ph.p_vaddr, ph_expect[2]) self.assertEqual(ph.p_paddr, ph_expect[3]) self.assertEqual(ph.p_filesz, ph_expect[4]) self.assertEqual(ph.p_memsz, ph_expect[5]) self.assertEqual(ph.p_flags, ph_expect[6]) self.assertEqual(ph.p_align, ph_expect[7])
def test_setwordsize(self): ident = ElfIdentification() ident.wordsize = 32 self.assertEqual(ident.wordsize, 32) ident.wordsize = 64 self.assertEqual(ident.wordsize, 64) ident.wordsize = 32 self.assertEqual(ident.wordsize, 32) def set_invalid_wordsize(ident): ident.wordsize = 10 self.assertRaises(elf.structures.ElfFormatError, set_invalid_wordsize, ident)
def test_setendianess(self): ident = ElfIdentification() ident.endianess = '>' self.assertEqual(ident.endianess, '>') ident.endianess = '<' self.assertEqual(ident.endianess, '<') ident.endianess = '>' self.assertEqual(ident.endianess, '>') def set_invalid_endianess(ident): ident.endianess = 'q' self.assertRaises(elf.structures.ElfFormatError, set_invalid_endianess, ident)
def setUp(self): self.elf_headers = {} for file_name in elf_files: f = File(file_name, "rb") ident = ElfIdentification() ident.fromdata(f.get_data(0, 16)) if ident.wordsize == 32: data = f.get_data(0, Elf32Header.size()) header = Elf32Header() header.fromdata(data) elif ident.wordsize == 64: data = f.get_data(0, Elf64Header.size()) header = Elf64Header() header.fromdata(data) else: raise "Problem" self.elf_headers[file_name] = (header, data) self.bogus_data_size = f.get_data(0, Elf32Header.size() - 1)
def test_expected(self): for file_name in elf_sh_expected: f = File(file_name, "rb") ident = ElfIdentification() ident.fromdata(f.get_data(0, 16)) wordsize = ident.wordsize hdr = ELF_HEADER_CLASSES[wordsize]() if ident.wordsize == 32: data = f.get_data(0, Elf32Header.size()) header = Elf32Header() ShClass = Elf32SectionHeader header.fromdata(data) elif ident.wordsize == 64: data = f.get_data(0, Elf64Header.size()) header = Elf64Header() header.fromdata(data) ShClass = Elf64SectionHeader else: raise "Problem" self.assertEqual(header.e_shnum, len(elf_sh_expected[file_name])) entsize = header.e_shentsize for i in range(header.e_shnum): sh_expect = elf_sh_expected[file_name][i] sh_data = f.get_data(header.e_shoff + (i * entsize), entsize) sh = ShClass(header.ident.endianess) sh.fromdata(sh_data, hdr) self.assertEqual(sh.todata(), sh_data) self.assertEqual(sh.sh_name, sh_expect[0]) self.assertEqual(sh.sh_type, sh_expect[1]) self.assertEqual(sh.sh_addr, sh_expect[2]) self.assertEqual(sh.sh_offset, sh_expect[3]) self.assertEqual(sh.sh_size, sh_expect[4]) self.assertEqual(sh.sh_entsize, sh_expect[5]) self.assertEqual(sh.sh_flags, sh_expect[6]) self.assertEqual(sh.sh_link, sh_expect[7]) self.assertEqual(sh.sh_info, sh_expect[8]) self.assertEqual(sh.sh_addralign, sh_expect[9])
def setUp(self): f = File("data/arm_exec", "rb") self.valid_ident_data = f.get_data(0, 16) self.valid_32_little = copy_array(self.valid_ident_data) self.valid_32_little_ident = ElfIdentification() self.valid_32_little_ident.fromdata(self.valid_32_little) self.valid_64_little = copy_array(self.valid_ident_data) self.valid_64_little[ElfIdentification.EI_CLASS] = ELFCLASS64 self.valid_64_little_ident = ElfIdentification() self.valid_64_little_ident.fromdata(self.valid_64_little) self.valid_32_big = copy_array(self.valid_ident_data) self.valid_32_big[ElfIdentification.EI_DATA] = ELFDATA2MSB self.valid_32_big_ident = ElfIdentification() self.valid_32_big_ident.fromdata(self.valid_32_big) self.valid_64_big = copy_array(self.valid_ident_data) self.valid_64_big[ElfIdentification.EI_CLASS] = ELFCLASS64 self.valid_64_big[ElfIdentification.EI_DATA] = ELFDATA2MSB self.valid_64_big_ident = ElfIdentification() self.valid_64_big_ident.fromdata(self.valid_64_big) self.bogus_size = f.get_data(0, 10) self.bogus_magic = copy_array(self.valid_ident_data) self.bogus_magic[0] = 0 self.bogus_data = copy_array(self.valid_ident_data) self.bogus_data[ElfIdentification.EI_DATA] = 0 self.bogus_class = copy_array(self.valid_ident_data) self.bogus_class[ElfIdentification.EI_CLASS] = 0 self.unknown_class = copy_array(self.valid_ident_data) self.unknown_class[ElfIdentification.EI_CLASS] = 200 self.unknown_class_ident = ElfIdentification() self.unknown_class_ident.fromdata(self.unknown_class) self.unknown_data = copy_array(self.valid_ident_data) self.unknown_data[ElfIdentification.EI_DATA] = 200 self.unknown_data_ident = ElfIdentification() self.unknown_data_ident.fromdata(self.unknown_data)
def test_against_readelf(self): if not have_readelf: return for file_name in elf_ph_expected: f = File(file_name, "rb") ident = ElfIdentification() ident.fromdata(f.get_data(0, 16)) wordsize = ident.wordsize hdr = ELF_HEADER_CLASSES[wordsize]() lines = os.popen("readelf -l %s" % file_name).readlines() good_lines = [] if ident.wordsize == 32: data = f.get_data(0, Elf32Header.size()) header = Elf32Header() PhClass = Elf32ProgramHeader header.fromdata(data) got_start = False for line in lines: if got_start: if line.strip() == "": break good_lines.append(line) else: # Looking for start if line.startswith(" Type"): got_start = True elif ident.wordsize == 64: data = f.get_data(0, Elf64Header.size()) header = Elf64Header() header.fromdata(data) PhClass = Elf64ProgramHeader got_start = False for line in lines: if got_start: if line.strip() == "": break if not line.strip().startswith("["): good_lines.append(line) else: # Looking for start if line.strip().startswith("FileSiz"): got_start = True merged_lines = [] i = 0 while i < len(good_lines): merged_lines.append(good_lines[i] + good_lines[i+1]) i += 2 good_lines = merged_lines entsize = header.e_phentsize for i in range(header.e_phnum): ph_data = f.get_data(header.e_phoff + (i * entsize), entsize) ph = PhClass(header.ident.endianess) ph.fromdata(ph_data, hdr) out = StringIO.StringIO() ph.output(out) out.getvalue() self.assertEqual(out.getvalue(), good_lines[i])
def test_bogus_class(self): ident = ElfIdentification() self.assertRaises(elf.structures.ElfFormatError, ident.fromdata, self.bogus_class)
def test_get_set_abiversion(self): ident = ElfIdentification() self.assertEquals(ident.ei_abiversion, 0) ident.ei_abiversion = 12 self.assertEquals(ident.ei_abiversion, 12)
def test_get_set_osabi(self): ident = ElfIdentification() self.assertEquals(ident.ei_osabi, ELFOSABI_NONE) ident.ei_osabi = ELFOSABI_ARM self.assertEquals(ident.ei_osabi, ELFOSABI_ARM)
def test_get_size(self): self.assertEqual(ElfIdentification.get_size(), 16)
class TestElfIdentification(unittest.TestCase): def setUp(self): f = File("data/arm_exec", "rb") self.valid_ident_data = f.get_data(0, 16) self.valid_32_little = copy_array(self.valid_ident_data) self.valid_32_little_ident = ElfIdentification() self.valid_32_little_ident.fromdata(self.valid_32_little) self.valid_64_little = copy_array(self.valid_ident_data) self.valid_64_little[ElfIdentification.EI_CLASS] = ELFCLASS64 self.valid_64_little_ident = ElfIdentification() self.valid_64_little_ident.fromdata(self.valid_64_little) self.valid_32_big = copy_array(self.valid_ident_data) self.valid_32_big[ElfIdentification.EI_DATA] = ELFDATA2MSB self.valid_32_big_ident = ElfIdentification() self.valid_32_big_ident.fromdata(self.valid_32_big) self.valid_64_big = copy_array(self.valid_ident_data) self.valid_64_big[ElfIdentification.EI_CLASS] = ELFCLASS64 self.valid_64_big[ElfIdentification.EI_DATA] = ELFDATA2MSB self.valid_64_big_ident = ElfIdentification() self.valid_64_big_ident.fromdata(self.valid_64_big) self.bogus_size = f.get_data(0, 10) self.bogus_magic = copy_array(self.valid_ident_data) self.bogus_magic[0] = 0 self.bogus_data = copy_array(self.valid_ident_data) self.bogus_data[ElfIdentification.EI_DATA] = 0 self.bogus_class = copy_array(self.valid_ident_data) self.bogus_class[ElfIdentification.EI_CLASS] = 0 self.unknown_class = copy_array(self.valid_ident_data) self.unknown_class[ElfIdentification.EI_CLASS] = 200 self.unknown_class_ident = ElfIdentification() self.unknown_class_ident.fromdata(self.unknown_class) self.unknown_data = copy_array(self.valid_ident_data) self.unknown_data[ElfIdentification.EI_DATA] = 200 self.unknown_data_ident = ElfIdentification() self.unknown_data_ident.fromdata(self.unknown_data) def test_get_size(self): self.assertEqual(ElfIdentification.get_size(), 16) def test_bogus_size(self): ident = ElfIdentification() self.assertRaises(elf.structures.ElfFormatError, ident.fromdata, self.bogus_size) def test_bogus_magic(self): ident = ElfIdentification() self.assertRaises(elf.structures.ElfFormatError, ident.fromdata, self.bogus_magic) def test_bogus_data(self): ident = ElfIdentification() self.assertRaises(elf.structures.ElfFormatError, ident.fromdata, self.bogus_data) def test_bogus_class(self): ident = ElfIdentification() self.assertRaises(elf.structures.ElfFormatError, ident.fromdata, self.bogus_class) def test_getwordsize(self): self.assertEqual(self.valid_32_little_ident.wordsize, 32) self.assertEqual(self.valid_64_little_ident.wordsize, 64) self.assertEqual(self.valid_32_big_ident.wordsize, 32) self.assertEqual(self.valid_64_big_ident.wordsize, 64) def get_invalid_wordsize(ident): x = ident.wordsize self.assertRaises(elf.structures.ElfFormatError, get_invalid_wordsize, self.unknown_class_ident) def test_setwordsize(self): ident = ElfIdentification() ident.wordsize = 32 self.assertEqual(ident.wordsize, 32) ident.wordsize = 64 self.assertEqual(ident.wordsize, 64) ident.wordsize = 32 self.assertEqual(ident.wordsize, 32) def set_invalid_wordsize(ident): ident.wordsize = 10 self.assertRaises(elf.structures.ElfFormatError, set_invalid_wordsize, ident) def test_getendianess(self): self.assertEqual(self.valid_32_little_ident.endianess, '<') self.assertEqual(self.valid_64_little_ident.endianess, '<') self.assertEqual(self.valid_32_big_ident.endianess, '>') self.assertEqual(self.valid_64_big_ident.endianess, '>') def get_invalid_endianess(ident): x = ident.endianess self.assertRaises(elf.structures.ElfFormatError, get_invalid_endianess, self.unknown_data_ident) def test_setendianess(self): ident = ElfIdentification() ident.endianess = '>' self.assertEqual(ident.endianess, '>') ident.endianess = '<' self.assertEqual(ident.endianess, '<') ident.endianess = '>' self.assertEqual(ident.endianess, '>') def set_invalid_endianess(ident): ident.endianess = 'q' self.assertRaises(elf.structures.ElfFormatError, set_invalid_endianess, ident) def test_get_set_osabi(self): ident = ElfIdentification() self.assertEquals(ident.ei_osabi, ELFOSABI_NONE) ident.ei_osabi = ELFOSABI_ARM self.assertEquals(ident.ei_osabi, ELFOSABI_ARM) def test_get_set_abiversion(self): ident = ElfIdentification() self.assertEquals(ident.ei_abiversion, 0) ident.ei_abiversion = 12 self.assertEquals(ident.ei_abiversion, 12) def test_version(self): self.assertEqual(self.valid_32_little_ident.ei_version, 1) self.assertEqual(self.valid_64_little_ident.ei_version, 1) self.assertEqual(self.valid_32_big_ident.ei_version, 1) self.assertEqual(self.valid_64_big_ident.ei_version, 1)
def test_against_readelf(self): if not have_readelf: return for file_name in elf_sh_files: f = File(file_name, "rb") ident = ElfIdentification() ident.fromdata(f.get_data(0, 16)) wordsize = ident.wordsize hdr = ELF_HEADER_CLASSES[wordsize]() lines = os.popen("readelf -S %s" % file_name).readlines() good_lines = [] if ident.wordsize == 32: data = f.get_data(0, Elf32Header.size()) header = Elf32Header() ShClass = Elf32SectionHeader header.fromdata(data) got_start = False for line in lines: if got_start: if line.strip().startswith("Key to Flags"): break good_lines.append(line) else: # Looking for start if line.strip().startswith("[Nr]"): got_start = True elif ident.wordsize == 64: data = f.get_data(0, Elf64Header.size()) header = Elf64Header() header.fromdata(data) ShClass = Elf64SectionHeader got_start = False for line in lines: if got_start: if line.strip().startswith("Key"): break good_lines.append(line) else: # Looking for start if line.strip().startswith("Siz"): got_start = True merged_lines = [] i = 0 while i < len(good_lines): merged_lines.append(good_lines[i] + good_lines[i + 1]) i += 2 good_lines = merged_lines good_lines = [line[25:] for line in good_lines] entsize = header.e_shentsize for i in range(header.e_shnum): sh_data = f.get_data(header.e_shoff + (i * entsize), entsize) sh = ShClass(header.ident.endianess) sh.fromdata(sh_data, hdr) out = StringIO.StringIO() sh.output(out) out.getvalue() self.assertEqual(out.getvalue(), good_lines[i])
def test_against_readelf(self): if not have_readelf: return for file_name in elf_sh_files: f = File(file_name, "rb") ident = ElfIdentification() ident.fromdata(f.get_data(0, 16)) wordsize = ident.wordsize hdr = ELF_HEADER_CLASSES[wordsize]() lines = os.popen("readelf -S %s" % file_name).readlines() good_lines = [] if ident.wordsize == 32: data = f.get_data(0, Elf32Header.size()) header = Elf32Header() ShClass = Elf32SectionHeader header.fromdata(data) got_start = False for line in lines: if got_start: if line.strip().startswith("Key to Flags"): break good_lines.append(line) else: # Looking for start if line.strip().startswith("[Nr]"): got_start = True elif ident.wordsize == 64: data = f.get_data(0, Elf64Header.size()) header = Elf64Header() header.fromdata(data) ShClass = Elf64SectionHeader got_start = False for line in lines: if got_start: if line.strip().startswith("Key"): break good_lines.append(line) else: # Looking for start if line.strip().startswith("Siz"): got_start = True merged_lines = [] i = 0 while i < len(good_lines): merged_lines.append(good_lines[i] + good_lines[i+1]) i += 2 good_lines = merged_lines good_lines = [line[25:] for line in good_lines] entsize = header.e_shentsize for i in range(header.e_shnum): sh_data = f.get_data(header.e_shoff + (i * entsize), entsize) sh = ShClass(header.ident.endianess) sh.fromdata(sh_data, hdr) out = StringIO.StringIO() sh.output(out) out.getvalue() self.assertEqual(out.getvalue(), good_lines[i])
def test_against_readelf(self): if not have_readelf: return for file_name in elf_ph_expected: f = File(file_name, "rb") ident = ElfIdentification() ident.fromdata(f.get_data(0, 16)) wordsize = ident.wordsize hdr = ELF_HEADER_CLASSES[wordsize]() lines = os.popen("readelf -l %s" % file_name).readlines() good_lines = [] if ident.wordsize == 32: data = f.get_data(0, Elf32Header.size()) header = Elf32Header() PhClass = Elf32ProgramHeader header.fromdata(data) got_start = False for line in lines: if got_start: if line.strip() == "": break good_lines.append(line) else: # Looking for start if line.startswith(" Type"): got_start = True elif ident.wordsize == 64: data = f.get_data(0, Elf64Header.size()) header = Elf64Header() header.fromdata(data) PhClass = Elf64ProgramHeader got_start = False for line in lines: if got_start: if line.strip() == "": break if not line.strip().startswith("["): good_lines.append(line) else: # Looking for start if line.strip().startswith("FileSiz"): got_start = True merged_lines = [] i = 0 while i < len(good_lines): merged_lines.append(good_lines[i] + good_lines[i + 1]) i += 2 good_lines = merged_lines entsize = header.e_phentsize for i in range(header.e_phnum): ph_data = f.get_data(header.e_phoff + (i * entsize), entsize) ph = PhClass(header.ident.endianess) ph.fromdata(ph_data, hdr) out = StringIO.StringIO() ph.output(out) out.getvalue() self.assertEqual(out.getvalue(), good_lines[i])