view python/elffile.py @ 122:aaa4939a7942

Improved repostats
author Windel Bouwman
date Sat, 12 Jan 2013 12:49:27 +0100
parents db8aafe00d27
children bbf4c9b138d4
line wrap: on
line source

import struct

classes = {1:'ELF32', 2:'ELF64'}

class ElfFile:
   def __init__(self, f):
      self.f = f
      self.parse()
   def parse(self):
      self.parseHeader()
      self.parseSections()
      self.parsePrograms()
   @property
   def ElfClass(self):
      return classes[self.ei_class]
   def parseHeader(self):
      # Parse identifier
      e_ident = self.f.read(16)
      ELFMAGIC = bytes([0x7f]) + b'ELF'
      assert e_ident[0:4] == ELFMAGIC
      self.ei_class = e_ident[4]
      print('ELF class: ', self.ElfClass)
      assert self.ei_class in classes.keys()
      self.ei_data = e_ident[5]
      print('ei_data:', self.ei_data)
      ei_version = e_ident[6]
      assert ei_version == 1

      # rest of the ELF header:
      e_type = self.readHalf()
      e_machine = self.readHalf()
      e_version = self.readWord()
      e_entry = self.readAddr()
      e_phoff = self.readOff()
      e_shoff = self.readOff()
      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()
      
      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)
   def readFmt(self, fmt):
      size = struct.calcsize(fmt)
      return struct.unpack(fmt, self.f.read(size))
   def readHalf(self):
      return self.readFmt('<H')[0]
   def readWord(self):
      return self.readFmt('<I')[0]
   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]
   readOff = readAddr

   def printProgramHeaders(self):
      pass