#!/usr/bin/env python import struct # ELF object file reader # (C) 2003 cliechti@gmx.net # Python license # size alignment # Elf32_Addr 4 4 Unsigned program address # Elf32_Half 2 2 Unsigned medium integer # Elf32_Off 4 4 Unsigned file offset # Elf32_Sword 4 4 Signed large integer # Elf32_Word 4 4 Unsigned large integer # unsignedchar 1 1 Unsigned small integer #define EI_NIDENT 16 #~ typedef struct{ #~ unsigned char e_ident[EI_NIDENT]; #~ Elf32_Half e_type; #~ Elf32_Half e_machine; #~ Elf32_Word e_version; #~ Elf32_Addr e_entry; #~ Elf32_Off e_phoff; #~ Elf32_Off e_shoff; #~ Elf32_Word e_flags; #~ Elf32_Half e_ehsize; #~ Elf32_Half e_phentsize; #~ Elf32_Half e_phnum; #~ Elf32_Half e_shentsize; #~ Elf32_Half e_shnum; #~ Elf32_Half e_shstrndx; #~ } Elf32_Ehdr; #Section Header #~ typedef struct { #~ Elf32_Word sh_name; #~ Elf32_Word sh_type; #~ Elf32_Word sh_flags; #~ Elf32_Addr sh_addr; #~ Elf32_Off sh_offset; #~ Elf32_Word sh_size; #~ Elf32_Word sh_link; #~ Elf32_Word sh_info; #~ Elf32_Word sh_addralign; #~ Elf32_Word sh_entsize; #~ } Elf32_Shdr; #~ typedef struct { #~ Elf32_Word p_type; #~ Elf32_Off p_offset; #~ Elf32_Addr p_vaddr; #~ Elf32_Addr p_paddr; #~ Elf32_Word p_filesz; #~ Elf32_Word p_memsz; #~ Elf32_Word p_flags; #~ Elf32_Word p_align; #~ } Elf32_Phdr; class ELFException(Exception): pass class ELFSection: """read and store a section""" Elf32_Shdr = "= section.sh_addr + section.sh_size) \ and (not (section.sh_flags & ELFSection.SHF_ALLOC and section.sh_type != ELFSection.SHT_NOBITS) \ or (p.p_offset <= section.sh_offset \ and (p.p_offset + p.p_filesz >= section.sh_offset + section.sh_size)))): return section.sh_addr + p.p_paddr - p.p_vaddr return section.sh_addr def getSections(self): """get sections relevant for the application""" res = [] for section in self.sections: if section.sh_flags & ELFSection.SHF_ALLOC and section.sh_type != ELFSection.SHT_NOBITS: res.append(section) return res def __str__(self): """pretty print for debug...""" return "%s(self.e_type=%r, self.e_machine=%r, self.e_version=%r, sections=%r)" % ( self.__class__.__name__, self.e_type, self.e_machine, self.e_version, [section.name for section in self.sections]) if __name__ == '__main__': print "This is only a module test!" elf = ELFObject() elf.fromFile(open("test.elf")) if elf.e_type != ELFObject.ET_EXEC: raise Exception("No executable") print elf #~ print repr(elf.getSection('.text').data) #~ print [(s.name, hex(s.sh_addr)) for s in elf.getSections()] print "-"*20 for p in elf.sections: print p print "-"*20 for p in elf.getSections(): print p print "-"*20 for p in elf.getProgrammableSections(): print p