Mercurial > lcfOS
changeset 126:bbf4c9b138d4
Changes to elf reading
author | Windel Bouwman |
---|---|
date | Sun, 13 Jan 2013 12:14:27 +0100 |
parents | 1ee5f36b34ed |
children | ec1f2cc04d95 |
files | python/elffile.py python/readelf.py |
diffstat | 2 files changed, 62 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/python/elffile.py Sun Jan 13 10:42:03 2013 +0100 +++ b/python/elffile.py Sun Jan 13 12:14:27 2013 +0100 @@ -1,6 +1,5 @@ import struct - -classes = {1:'ELF32', 2:'ELF64'} +import collections class ElfFile: def __init__(self, f): @@ -8,8 +7,6 @@ self.parse() def parse(self): self.parseHeader() - self.parseSections() - self.parsePrograms() @property def ElfClass(self): return classes[self.ei_class] @@ -19,6 +16,8 @@ ELFMAGIC = bytes([0x7f]) + b'ELF' assert e_ident[0:4] == ELFMAGIC self.ei_class = e_ident[4] + # Change the class of this object in some strange way: + self.__class__ = classes[self.ei_class] print('ELF class: ', self.ElfClass) assert self.ei_class in classes.keys() self.ei_data = e_ident[5] @@ -31,22 +30,20 @@ e_machine = self.readHalf() e_version = self.readWord() e_entry = self.readAddr() - e_phoff = self.readOff() - e_shoff = self.readOff() - e_flags = self.readWord() + self.e_phoff = self.readOff() + self.e_shoff = self.readOff() + self.e_flags = self.readWord() e_ehsize = self.readHalf() - e_phentsize = self.readHalf() - e_phnum = self.readHalf() - e_shentsize = self.readHalf() - e_shnum = self.readHalf() - e_shstrndx = self.readHalf() + self.e_phentsize = self.readHalf() + self.e_phnum = self.readHalf() + self.e_shentsize = self.readHalf() + self.e_shnum = self.readHalf() + self.e_shstrndx = self.readHalf() - if self.ei_class == 1: - assert e_ehsize == 52 - elif self.ei_class == 2: - assert e_ehsize == 64 - print('program header size', e_phentsize, e_phnum) - print('section header size', e_shentsize, e_shnum, e_shstrndx) + assert e_ehsize == self.HEADERSIZE + print('program header size', self.e_phentsize, self.e_phnum) + print('section header size', self.e_shentsize, self.e_shnum) + print('string index:', self.e_shstrndx) def readFmt(self, fmt): size = struct.calcsize(fmt) return struct.unpack(fmt, self.f.read(size)) @@ -54,15 +51,49 @@ return self.readFmt('<H')[0] def readWord(self): return self.readFmt('<I')[0] + def parsePrograms(self): + # Skip to start of program headers: + self.f.seek(self.e_phoff) + pheaders = [] + for i in range(self.e_phnum): + pheaders.append(self.parseProgramHeader()) + return pheaders + +ProgramHeader = collections.namedtuple('ProgramHeader', ['p_type', + 'p_flags', 'p_offset', 'p_vaddr', 'p_paddr', 'p_filesz', 'p_memsz']) + +class Elf32File(ElfFile): + HEADERSIZE=52 def readAddr(self): - if self.ei_class == 1: - fmt = '<I' - elif self.ei_class == 2: - fmt = '<Q' - else: - raise Exception() - return self.readFmt(fmt)[0] + return self.readFmt('<I')[0] readOff = readAddr + def parseProgramHeader(self): + p_type = self.readWord() + p_offset = self.readOff() + p_vaddr = self.readAddr() + p_paddr = self.readAddr() + p_filesz = self.readWord() + p_memsz = self.readWord() + p_flags = self.readWord() + p_align = self.readWord() + return ProgramHeader(p_type, p_flags, p_offset, p_vaddr, p_paddr, p_filesz, p_memsz) + +class Elf64File(ElfFile): + HEADERSIZE=64 + def readAddr(self): + return self.readFmt('<Q')[0] + readOff = readAddr + readXword = readAddr + def parseProgramHeader(self): + p_type = self.readWord() + p_flags = self.readWord() + p_offset = self.readOff() + p_vaddr = self.readAddr() + p_paddr = self.readAddr() + p_filesz = self.readXword() + p_memsz = self.readXword() + p_align = self.readXword() + return ProgramHeader(p_type, p_flags, p_offset, p_vaddr, p_paddr) - def printProgramHeaders(self): - pass +classes = {1:Elf32File, 2:Elf64File} +
--- a/python/readelf.py Sun Jan 13 10:42:03 2013 +0100 +++ b/python/readelf.py Sun Jan 13 12:14:27 2013 +0100 @@ -13,5 +13,8 @@ if args.list_program_headers: print('program headers') - ef.printProgramHeaders() + phs = ef.parsePrograms() + print(phs) + for ph in phs: + print('type=0x{0:X} vaddr=0x{1:X} filesz=0x{2:X}'.format(ph.p_type, ph.p_vaddr, ph.p_filesz))