118
|
1 import struct
|
|
2
|
|
3 classes = {1:'ELF32', 2:'ELF64'}
|
|
4
|
|
5 class ElfFile:
|
|
6 def __init__(self, f):
|
|
7 self.f = f
|
|
8 self.parse()
|
|
9 def parse(self):
|
|
10 self.parseHeader()
|
|
11 self.parseSections()
|
|
12 self.parsePrograms()
|
|
13 @property
|
|
14 def ElfClass(self):
|
|
15 return classes[self.ei_class]
|
|
16 def parseHeader(self):
|
|
17 # Parse identifier
|
|
18 e_ident = self.f.read(16)
|
|
19 ELFMAGIC = bytes([0x7f]) + b'ELF'
|
|
20 assert e_ident[0:4] == ELFMAGIC
|
|
21 self.ei_class = e_ident[4]
|
|
22 print('ELF class: ', self.ElfClass)
|
|
23 assert self.ei_class in classes.keys()
|
|
24 self.ei_data = e_ident[5]
|
|
25 print('ei_data:', self.ei_data)
|
|
26 ei_version = e_ident[6]
|
|
27 assert ei_version == 1
|
|
28
|
|
29 # rest of the ELF header:
|
|
30 e_type = self.readHalf()
|
|
31 e_machine = self.readHalf()
|
|
32 e_version = self.readWord()
|
|
33 e_entry = self.readAddr()
|
|
34 e_phoff = self.readOff()
|
|
35 e_shoff = self.readOff()
|
|
36 e_flags = self.readWord()
|
|
37 e_ehsize = self.readHalf()
|
|
38 e_phentsize = self.readHalf()
|
|
39 e_phnum = self.readHalf()
|
|
40 e_shentsize = self.readHalf()
|
|
41 e_shnum = self.readHalf()
|
|
42 e_shstrndx = self.readHalf()
|
|
43
|
|
44 if self.ei_class == 1:
|
|
45 assert e_ehsize == 52
|
|
46 elif self.ei_class == 2:
|
|
47 assert e_ehsize == 64
|
|
48 print('program header size', e_phentsize, e_phnum)
|
|
49 print('section header size', e_shentsize, e_shnum, e_shstrndx)
|
|
50 def readFmt(self, fmt):
|
|
51 size = struct.calcsize(fmt)
|
|
52 return struct.unpack(fmt, self.f.read(size))
|
|
53 def readHalf(self):
|
|
54 return self.readFmt('<H')[0]
|
|
55 def readWord(self):
|
|
56 return self.readFmt('<I')[0]
|
|
57 def readAddr(self):
|
|
58 if self.ei_class == 1:
|
|
59 fmt = '<I'
|
|
60 elif self.ei_class == 2:
|
|
61 fmt = '<Q'
|
|
62 else:
|
|
63 raise Exception()
|
|
64 return self.readFmt(fmt)[0]
|
|
65 readOff = readAddr
|
|
66
|
|
67 def printProgramHeaders(self):
|
|
68 pass
|