python3 elf文件解析

原地址:https://github.com/guanchao/elfParser

作者是用python2写的,现在给出我修改后的python3版本。(测试发现有bug,以后自己写个,0.0)

  1 #!/usr/bin/env python
  2 # coding:utf-8
  3 
  4 import sys
  5 import binascii
  6 
  7 '''
  8 # 节区类型定义
  9 /* sh_type */
 10 #define SHT_NULL    0
 11 #define SHT_PROGBITS    1
 12 #define SHT_SYMTAB    2
 13 #define SHT_STRTAB    3
 14 #define SHT_RELA    4
 15 #define SHT_HASH    5
 16 #define SHT_DYNAMIC    6
 17 #define SHT_NOTE    7
 18 #define SHT_NOBITS    8
 19 #define SHT_REL    9
 20 #define SHT_SHLIB    10
 21 #define SHT_DYNSYM    11
 22 #define SHT_NUM    12
 23 #define SHT_LOPROC    0x70000000
 24 #define SHT_HIPROC    0x7fffffff
 25 #define SHT_LOUSER    0x80000000
 26 #define SHT_HIUSER    0xffffffff
 27 #define SHT_MIPS_LIST    0x70000000
 28 #define SHT_MIPS_CONFLICT    0x70000002
 29 #define SHT_MIPS_GPTAB    0x70000003
 30 #define SHT_MIPS_UCODE    0x70000004
 31 '''
 32 SH_TYPE_MAP_LIST = {0: 'SHT_NULL',
 33                     1: 'SHT_PROGBITS',
 34                     2: 'SHT_SYMTAB',
 35                     3: 'SHT_STRTAB',
 36                     4: 'SHT_RELA',
 37                     5: 'SHT_HASH',
 38                     6: 'SHT_DYNAMIC',
 39                     7: 'SHT_NOTE',
 40                     8: 'SHT_NOBITS',
 41                     9: 'SHT_REL',
 42                     10: 'SHT_SHLIB',
 43                     11: 'SHT_DYNSYM',
 44                     # 0x60000000:'SHT_LOOS',
 45                     # 0x6fffffff:'SHT_HIOS',
 46                     0x70000000: 'SHT_LOPROC',
 47                     0x7FFFFFFF: 'SHT_HIPROC',
 48                     0x80000000: 'SHT_LOUSER',
 49                     0x8FFFFFFF: 'SHT_HIUSER',
 50                     0x70000000: 'SHT_MIPS_LIST',
 51                     0x70000002: 'SHT_MIPS_CONFLICT',
 52                     0x70000003: 'SHT_MIPS_GPTAB',
 53                     0x70000004: 'SHT_MIPS_UCODE',
 54                     }
 55 
 56 PT_TYPE_MAP_LIST = {
 57     0: 'NULL',
 58     1: 'LOAD',
 59     2: 'DYNAMIC',
 60     3: 'INTERP',
 61     4: 'NOTE',
 62     5: 'SHLIB',
 63     6: 'PHDR',
 64     7: 'TLS',
 65     0x70000000: 'LOPROC',
 66     0x70000001: 'HIPROC',
 67     0x6474E551: 'GNU_STACK',
 68     0x6474E552: 'GNU_RELRO',
 69 }
 70 
 71 '''
 72 Elf32_Dyn.d_tag
 73 '''
 74 DYNAMIC_TYPE = {
 75     0: 'NULL',
 76     1: 'NEEDED',
 77     2: 'PLTRELSZ',
 78     3: 'PLTGOT',
 79     4: 'HASH',
 80     5: 'STRTAB',
 81     6: 'SYMTAB',
 82     7: 'RELA',
 83     8: 'RELASZ',
 84     9: 'RELAENT',
 85     10: 'STRSZ',
 86     11: 'SYMENT',
 87     12: 'INIT',
 88     13: 'FINIT',
 89     14: 'SONAME',
 90     15: 'RPATH',
 91     16: 'SYMBOLIC',
 92     17: 'REL',
 93     18: 'RELSZ',
 94     19: 'RELENT',
 95     20: 'PLTREL',
 96     21: 'DEBUG',
 97     22: 'TEXTREL',
 98     23: 'JMPREL',
 99     26: 'FINIT_ARRAY',
100     28: 'FINIT_ARRAYSZ',
101     25: 'INIT_ARRAY',
102     27: 'INIT_ARRAYSZ',
103     30: 'FLAGS',
104     0x6FFFFFFA: 'RELCOUNT',
105     0x6FFFFFFB: 'FLAGS_1',
106     0x70000000: 'LOPROC',
107     0x7fffffff: 'HIPROC',
108     0x70000001: 'MIPS_RLD_VERSION',
109     0x70000002: 'MIPS_TIME_STAMP',
110     0x70000003: 'MIPS_ICHECKSUM',
111     0x70000004: 'MIPS_IVERSION',
112     0x70000005: 'MIPS_FLAGS',
113     0x70000006: 'MIPS_BASE_ADDRESS',
114     0x70000008: 'MIPS_CONFLICT',
115     0x70000009: 'MIPS_LIBLIST',
116     0x7000000a: 'MIPS_LOCAL_GOTNO',
117     0x7000000b: 'MIPS_CONFLICTNO',
118     0x70000010: 'MIPS_LIBLISTNO',
119     0x70000011: 'MIPS_SYMTABNO',
120     0x70000012: 'MIPS_UNREFEXTNO',
121     0x70000013: 'MIPS_GOTSYM',
122     0x70000014: 'MIPS_HIPAGENO',
123     0x70000016: 'MIPS_RLD_MAP',
124 
125 }
126 '''
127 typedef struct elf32_hdr{
128   unsigned char    e_ident[EI_NIDENT];
129   Elf32_Half    e_type;
130   Elf32_Half    e_machine;
131   Elf32_Word    e_version;
132   Elf32_Addr    e_entry;  /* Entry point */
133   Elf32_Off    e_phoff;
134   Elf32_Off    e_shoff;
135   Elf32_Word    e_flags;
136   Elf32_Half    e_ehsize;
137   Elf32_Half    e_phentsize;
138   Elf32_Half    e_phnum;
139   Elf32_Half    e_shentsize;
140   Elf32_Half    e_shnum;
141   Elf32_Half    e_shstrndx;
142 } Elf32_Ehdr;
143 '''
144 
145 
146 class Elf32_Ehdr(object):
147     """docstring for Elf32_Ehdr"""
148 
149     def __init__(self):
150         super(Elf32_Ehdr, self).__init__()
151         self.e_ident = None
152         self.e_type = None
153         self.e_machine = None
154         self.e_version = None
155         self.e_entry = None
156         self.e_phoff = None
157         self.e_shoff = None
158         self.e_flags = None
159         self.e_ehsize = None
160         self.e_phentsize = None
161         self.e_phnum = None
162         self.e_shentsize = None
163         self.e_shnum = None
164         self.e_shstrndx = None
165 
166 
167 class e_ident(object):
168     """docstring for e_ident"""
169 
170     def __init__(self):
171         super(e_ident, self).__init__()
172         self.file_identification = None
173         self.ei_class = None
174         self.ei_data = None
175         self.ei_version = None
176         self.ei_osabi = None
177         self.ei_abiversion = None
178         self.ei_pad = None
179         self.ei_nident = None
180 
181     def __str__(self):
182         return 'e_ident=[file_identification=%s, ei_class=%d, ei_data=%d, ei_version=%d, ei_osabi=%d, ei_abiversion=%d, ei_pad=%s, ei_nident=%d]' % (
183             self.file_identification, self.ei_class, self.ei_data, self.ei_version, self.ei_osabi, self.ei_abiversion,
184             self.ei_pad, self.ei_nident)
185 
186 
187 class Elf32_Shdr(object):
188     """docstring for Elf32_Shdr"""
189 
190     def __init__(self):
191         super(Elf32_Shdr, self).__init__()
192         '''
193         typedef struct Elf32_Shdr {
194           Elf32_Word    sh_name;
195           Elf32_Word    sh_type;
196           Elf32_Word    sh_flags;
197           Elf32_Addr    sh_addr;
198           Elf32_Off    sh_offset;
199           Elf32_Word    sh_size;
200           Elf32_Word    sh_link;
201           Elf32_Word    sh_info;
202           Elf32_Word    sh_addralign;
203           Elf32_Word    sh_entsize;
204         } Elf32_Shdr;
205         '''
206         self.sh_name = None
207         self.sh_type = None
208         self.sh_flags = None
209         self.sh_addr = None
210         self.sh_offset = None
211         self.size = None
212         self.sh_link = None
213         self.sh_addralign = None
214         self.sh_entsize = None
215 
216         self.section_name = None
217 
218     def __str__(self):
219         return 'Elf32_Shdr=[sh_name=%s, sh_type=%d, sh_flags=%d, sh_addr=%s, sh_sh_offset=%s, sh_size=%d, sh_link=%d, sh_info=%d, sh_addralign=%d, sh_entsize=%d]' % 
220                (hex(self.sh_name), self.sh_type, self.sh_flags, hex(self.sh_addr), hex(self.sh_offset), self.sh_size,
221                 self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize)
222 
223 
224 class Elf32_Sym(object):
225     """docstring for Elf32_Sym"""
226 
227     def __init__(self):
228         super(Elf32_Sym, self).__init__()
229         '''
230         typedef struct elf32_sym{
231           Elf32_Word    st_name;
232           Elf32_Addr    st_value;
233           Elf32_Word    st_size;
234           unsigned char    st_info;
235           unsigned char    st_other;
236           Elf32_Half    st_shndx;
237         } Elf32_Sym;
238         '''
239         self.st_name = None
240         self.st_value = None
241         self.st_size = None
242         self.st_info = None
243         self.st_other = None
244         self.st_shndx = None
245 
246         self.symbol_name = None
247 
248     def __str__(self):
249         return 'Elf32_Dyn=[st_name=%s, st_value=%d, st_size=%d, st_info=%d, st_other=%d, st_shndx=%d] #%s' % 
250                (self.st_name, self.st_value, self.st_size, self.st_info, self.st_other, self.st_shndx, self.symbol_name)
251 
252 
253 class Elf32_Phdr(object):
254     """docstring for Elf32_Phdr"""
255 
256     def __init__(self):
257         super(Elf32_Phdr, self).__init__()
258         '''
259             /* 32-bit ELF base types. */
260             typedef uint32_t Elf32_Addr;
261             typedef uint16_t Elf32_Half;
262             typedef uint32_t Elf32_Off;
263             typedef int32_t  Elf32_Sword;
264             typedef uint32_t Elf32_Word;
265         '''
266         self.p_type = None  # Elf32_Word
267         self.p_offset = None  # Elf32_Off
268         self.p_vaddr = None  # Elf32_Addr
269         self.p_paddr = None  # Elf32_Addr
270         self.p_filesz = None  # Elf32_word
271         self.p_memsz = None  # Elf32_Word
272         self.p_flags = None  # Elf32_Word
273         self.p_align = None  # Elf32_Word
274 
275 
276 class Elf32_Dyn(object):
277     """docstring for Elf32_dyn"""
278 
279     def __init__(self):
280         super(Elf32_Dyn, self).__init__()
281         '''
282         typedef struct dynamic{
283           Elf32_Sword d_tag;
284           union{
285             Elf32_Sword    d_val;
286             Elf32_Addr    d_ptr;
287           } d_un;
288         } Elf32_Dyn;
289         '''
290         self.d_tag = None
291         self.d_un = None
292 
293     def __str__(self):
294         return 'Elf32_Dyn=[d_tag=%d, d_un=%d]' % 
295                (self.d_tag, self.d_un)
296 
297 
298 class ELF(object):
299     """docstring for ELF"""
300 
301     def __init__(self, filepath):
302         super(ELF, self).__init__()
303         self.filepath = filepath
304         self.elf32_Ehdr = Elf32_Ehdr()
305 
306         # section header table
307         self.sectionHeaderTable = []
308 
309         # section name table
310         self.sectionNameTable = None
311 
312         # program header table
313         self.programHeaderTable = []
314 
315         # dynamic symbol table
316         self.symbolTable = []  # .dynsym
317         self.dynstrTable = None  # .dynstr
318 
319         # dynamic link table
320         self.dynamicLinkTable = []  # .dynamic
321 
322         self.initELFHeader()
323         self.initSectionHeader()
324         self.initProgramHeader()
325         self.initSymbolTalbe()
326         self.initDynamicLinkTable()
327 
328     def initELFHeader(self):
329         f = open(self.filepath, "rb")
330         self.f = f
331         # unsigned char    e_ident[EI_NIDENT];
332         f.seek(0, 0)
333         self.elf32_Ehdr.e_ident = e_ident()
334         self.elf32_Ehdr.e_ident.file_identification = f.read(4)
335         self.elf32_Ehdr.e_ident.ei_class = int.from_bytes(f.read(1), 'little')
336         self.elf32_Ehdr.e_ident.ei_data = int.from_bytes(f.read(1), 'little')
337         self.elf32_Ehdr.e_ident.ei_version = int.from_bytes(f.read(1), 'little')
338         self.elf32_Ehdr.e_ident.ei_osabi = int.from_bytes(f.read(1), 'little')
339         self.elf32_Ehdr.e_ident.ei_abiversion = int.from_bytes(f.read(1), 'little')
340         self.elf32_Ehdr.e_ident.ei_pad = binascii.b2a_hex(f.read(6))
341         self.elf32_Ehdr.e_ident.ei_nident = int.from_bytes(f.read(1), 'little')
342 
343         # Elf32_Half    e_type;
344         f.seek(16, 0)
345         self.elf32_Ehdr.e_type = int.from_bytes(f.read(2), 'little')
346 
347         # Elf32_Half    e_machine;
348         f.seek(18, 0)
349         self.elf32_Ehdr.e_machine = int.from_bytes(f.read(2), 'little')
350 
351         # Elf32_Word    e_version;
352         f.seek(20, 0)
353         self.elf32_Ehdr.e_version = int.from_bytes(f.read(4), 'little')
354 
355         # Elf32_Addr    e_entry;
356         f.seek(24, 0)
357         self.elf32_Ehdr.e_entry = int.from_bytes(f.read(4), 'little')
358 
359         # Elf32_Off    e_phoff;
360         f.seek(28, 0)
361         self.elf32_Ehdr.e_phoff = int.from_bytes(f.read(4), 'little')
362 
363         # Elf32_Off    e_shoff;
364         f.seek(32, 0)
365         self.elf32_Ehdr.e_shoff = int.from_bytes(f.read(4), 'little')
366 
367         # Elf32_Word    e_flags;
368         f.seek(36, 0)
369         self.elf32_Ehdr.e_flags = int.from_bytes(f.read(4), 'little')
370 
371         # Elf32_Half    e_ehsize;
372         f.seek(40, 0)
373         self.elf32_Ehdr.e_ehsize = int.from_bytes(f.read(2), 'little')
374 
375         # Elf32_Half    e_phentsize;
376         f.seek(42, 0)
377         self.elf32_Ehdr.e_phentsize = int.from_bytes(f.read(2), 'little')
378 
379         # Elf32_Half    e_phnum;
380         f.seek(44, 0)
381         self.elf32_Ehdr.e_phnum = int.from_bytes(f.read(2), 'little')
382 
383         # Elf32_Half    e_shentsize;
384         f.seek(46, 0)
385         self.elf32_Ehdr.e_shentsize = int.from_bytes(f.read(2), 'little')
386 
387         # Elf32_Half    e_shnum;
388         f.seek(48, 0)
389         self.elf32_Ehdr.e_shnum = int.from_bytes(f.read(2), 'little')
390 
391         # Elf32_Half    e_shstrndx;
392         f.seek(50, 0)
393         self.elf32_Ehdr.e_shstrndx = int.from_bytes(f.read(2), 'little')
394 
395     def initSectionHeader(self):
396         # print(self.elf32_Ehdr.e_shnum)
397         for i in range(self.elf32_Ehdr.e_shnum):
398             self.sectionHeaderTable.append(self.parseSectionHeader(self.elf32_Ehdr.e_shoff + i * self.elf32_Ehdr.e_shentsize))
399         if self.elf32_Ehdr.e_shnum == 0:
400             return
401         # init section name table
402         self.f.seek(self.sectionHeaderTable[self.elf32_Ehdr.e_shstrndx].sh_offset)
403         size = self.sectionHeaderTable[self.elf32_Ehdr.e_shstrndx].sh_size
404         self.sectionNameTable = self.f.read(size)
405 
406         for i in range(self.elf32_Ehdr.e_shnum):
407             idx = self.sectionHeaderTable[i].sh_name
408             name = []
409             while self.sectionNameTable[idx] != 0:
410                 name.append(chr(self.sectionNameTable[idx]))
411                 idx += 1
412             # print("".join(name))
413             self.sectionHeaderTable[i].section_name = "".join(name)
414 
415     def parseSectionHeader(self, offset):
416         self.f.seek(offset, 0)
417         elf32_Shdr = Elf32_Shdr()
418         # elf32_Shdr.sh_name = int.from_bytes(self.f.read(4), 16)
419         elf32_Shdr.sh_name = int.from_bytes(self.f.read(4), 'little')
420         elf32_Shdr.sh_type = int.from_bytes(self.f.read(4), 'little')
421         elf32_Shdr.sh_flags = int.from_bytes(self.f.read(4), 'little')
422         elf32_Shdr.sh_addr = int.from_bytes(self.f.read(4), 'little')
423         elf32_Shdr.sh_offset = int.from_bytes(self.f.read(4), 'little')
424         elf32_Shdr.sh_size = int.from_bytes(self.f.read(4), 'little')
425         elf32_Shdr.sh_link = int.from_bytes(self.f.read(4), 'little')
426         elf32_Shdr.sh_info = int.from_bytes(self.f.read(4), 'little')
427         elf32_Shdr.sh_addralign = int.from_bytes(self.f.read(4), 'little')
428         elf32_Shdr.sh_entsize = int.from_bytes(self.f.read(4), 'little')
429         return elf32_Shdr
430 
431     def displaySectionHeader(self):
432         print('[+] Section Header Table:')
433 
434         print('  #      %-32s%-16s%-16s%-16s%-8s%-8s%-8s%-8s%-8s%-8s' % (
435             'Name', 'Type', 'Addr', 'Offset', 'Size', 'ES', 'Flg', 'Lk', 'Inf', 'Al'))
436 
437         for index in range(len(self.sectionHeaderTable)):
438             elf32_Shdr = self.sectionHeaderTable[index]
439             if elf32_Shdr.sh_type in SH_TYPE_MAP_LIST:
440                 print('  [%4d] %-32s%-16s%-16s%-16s%-8s%-8d%-8d%-8d%-8d%-8d' % 
441                 (index,
442                  self.getSectionName(elf32_Shdr),
443                  SH_TYPE_MAP_LIST[elf32_Shdr.sh_type].strip(),
444                  hex(elf32_Shdr.sh_addr),
445                  hex(elf32_Shdr.sh_offset),
446                  hex(elf32_Shdr.sh_size),
447                  elf32_Shdr.sh_entsize,
448                  elf32_Shdr.sh_flags,
449                  elf32_Shdr.sh_link,
450                  elf32_Shdr.sh_info,
451                  elf32_Shdr.sh_addralign,
452                  ))
453 
454             else:
455                 print('  [%4d] %-32s%-16d%-16s%-16s%-8s%-8d%-8d%-8d%-8d%-8d' % 
456                 (index,
457                  self.getSectionName(elf32_Shdr),
458                  elf32_Shdr.sh_type,
459                  hex(elf32_Shdr.sh_addr),
460                  hex(elf32_Shdr.sh_offset),
461                  hex(elf32_Shdr.sh_size),
462                  elf32_Shdr.sh_entsize,
463                  elf32_Shdr.sh_flags,
464                  elf32_Shdr.sh_link,
465                  elf32_Shdr.sh_info,
466                  elf32_Shdr.sh_addralign,
467                  ))
468 
469         print()
470 
471     def getSectionName(self, elf32_Shdr):
472         idx = self.sectionNameTable.find(0, elf32_Shdr.sh_name)
473         return self.sectionNameTable[elf32_Shdr.sh_name:idx]
474 
475     def initProgramHeader(self):
476         for i in range(self.elf32_Ehdr.e_phnum):
477             self.programHeaderTable.append(
478                 self.parseProgramHeader(self.elf32_Ehdr.e_phoff + i * self.elf32_Ehdr.e_phentsize))
479 
480     def parseProgramHeader(self, offset):
481         '''
482         typedef struct elf32_phdr{
483           Elf32_Word    p_type;
484           Elf32_Off    p_offset;
485           Elf32_Addr    p_vaddr;
486           Elf32_Addr    p_paddr;
487           Elf32_Word    p_filesz;
488           Elf32_Word    p_memsz;
489           Elf32_Word    p_flags;
490           Elf32_Word    p_align;
491         } Elf32_Phdr;
492         '''
493         self.f.seek(offset, 0)
494         elf32_Phdr = Elf32_Phdr()
495         elf32_Phdr.p_type = int.from_bytes(self.f.read(4), 'little')
496         elf32_Phdr.p_offset = int.from_bytes(self.f.read(4), 'little')
497         elf32_Phdr.p_vaddr = int.from_bytes(self.f.read(4), 'little')
498         elf32_Phdr.p_paddr = int.from_bytes(self.f.read(4), 'little')
499         elf32_Phdr.p_filesz = int.from_bytes(self.f.read(4), 'little')
500         elf32_Phdr.p_memsz = int.from_bytes(self.f.read(4), 'little')
501         elf32_Phdr.p_flags = int.from_bytes(self.f.read(4), 'little')
502         elf32_Phdr.p_align = int.from_bytes(self.f.read(4), 'little')
503         return elf32_Phdr
504 
505     def displayProgramHeader(self):
506         print('[+] Program Header Table:')
507 
508         print('  #      %-16s%-16s%-16s%-16s%-8s%-8s%-8s%-8s' % (
509             'Type', 'offset', 'VirtAddr', 'PhysAddr', 'FileSiz', 'MemSiz', 'Flg', 'Align'))
510 
511         for index in range(len(self.programHeaderTable)):
512             elf32_Phdr = self.programHeaderTable[index]
513 
514             if elf32_Phdr.p_type in PT_TYPE_MAP_LIST:
515                 print('  [%4d] %-16s%-16s%-16s%-16s%-8s%-8s%-8d%-8s' % (
516                     index,
517                     PT_TYPE_MAP_LIST[elf32_Phdr.p_type],
518                     hex(elf32_Phdr.p_offset),
519                     hex(elf32_Phdr.p_vaddr),
520                     hex(elf32_Phdr.p_paddr),
521                     hex(elf32_Phdr.p_filesz),
522                     hex(elf32_Phdr.p_memsz),
523                     elf32_Phdr.p_flags,
524                     hex(elf32_Phdr.p_align),
525                 ))
526 
527             else:
528                 print('  [%4d] %-16d%-16s%-16s%-16s%-8s%-8s%-8d%-8s' % (
529                     index,
530                     elf32_Phdr.p_type,
531                     hex(elf32_Phdr.p_offset),
532                     hex(elf32_Phdr.p_vaddr),
533                     hex(elf32_Phdr.p_paddr),
534                     hex(elf32_Phdr.p_filesz),
535                     hex(elf32_Phdr.p_memsz),
536                     elf32_Phdr.p_flags,
537                     hex(elf32_Phdr.p_align),
538                 ))
539 
540         print('
[+] Section to segment mapping:')
541 
542         for index in range(len(self.programHeaderTable)):
543             elf32_Phdr = self.programHeaderTable[index]
544             sections = self.getSegmentSections(elf32_Phdr)
545 
546             sections_str = ''
547             for elf32_Shdr in sections:
548                 idx = self.sectionNameTable.index(0, elf32_Shdr.sh_name)
549                 sections_str += self.sectionNameTable[elf32_Shdr.sh_name:idx].decode() + ' '
550             print('  [%4d] %s' % (index, sections_str))
551 
552         print()
553 
554 
555     def getSegmentSections(self, elf32_Phdr):
556         start = elf32_Phdr.p_offset
557         end = elf32_Phdr.p_offset + elf32_Phdr.p_filesz
558 
559         sections = []
560         for index in range(len(self.sectionHeaderTable)):
561             elf32_Shdr = self.sectionHeaderTable[index]
562             section_start = elf32_Shdr.sh_offset
563             section_end = elf32_Shdr.sh_offset + elf32_Shdr.sh_size
564             if section_start >= start and section_end <= end:
565                 sections.append(elf32_Shdr)
566 
567         return sections
568 
569     def initSymbolTalbe(self):
570         # init dynsym
571         elf32_Shdr = self.getSectionByName('.dynsym')
572         if elf32_Shdr != None:
573             for i in range(int(elf32_Shdr.sh_size / elf32_Shdr.sh_entsize)):
574                 self.symbolTable.append(self.parseSymbolTable(elf32_Shdr.sh_offset + i * elf32_Shdr.sh_entsize))
575 
576         # init dynstr
577         dynstr_elf32_Shdr = self.getSectionByName('.dynstr')
578         self.f.seek(dynstr_elf32_Shdr.sh_offset)
579 
580         self.dynstrTable = self.f.read(dynstr_elf32_Shdr.sh_size)
581 
582         for i in range(len(self.symbolTable)):
583             idx = self.symbolTable[i].st_name
584             name = []
585             while  self.dynstrTable[idx+1] != 0:
586                 name.append(chr(self.dynstrTable[idx]))
587                 idx += 1
588             # print("".join(name))
589             self.symbolTable[i].symbol_name = "".join(name)
590 
591     def parseSymbolTable(self, offset):
592         '''
593             typedef struct elf32_sym{
594               Elf32_Word    st_name;
595               Elf32_Addr    st_value;
596               Elf32_Word    st_size;
597               unsigned char    st_info;
598               unsigned char    st_other;
599               Elf32_Half    st_shndx;
600             } Elf32_Sym;
601         '''
602         self.f.seek(offset, 0)
603         elf32_Sym = Elf32_Sym()
604         elf32_Sym.st_name = int.from_bytes(self.f.read(4), 'little')
605         elf32_Sym.st_value = int.from_bytes(self.f.read(4), 'little')
606         elf32_Sym.st_size = int.from_bytes(self.f.read(4), 'little')
607         elf32_Sym.st_info = int.from_bytes(self.f.read(1), 'little')
608         elf32_Sym.st_other = int.from_bytes(self.f.read(1), 'little')
609         elf32_Sym.st_shndx = int.from_bytes(self.f.read(2), 'little')
610         return elf32_Sym
611 
612     def displaySymbolTable(self):
613         print('[+] Dynamic Symbol Table:')
614 
615         print('  #      %-10s%-8s%-8s%-8s%-8s%-8s%-8s'
616               % ('Value', 'Size', 'Type', 'Bind', 'Other', 'Ndx', 'Name'))
617         BIND_TYPE = {0: 'LOCAL', 1: 'GLOBAL', 2: 'WEAK', 13: 'LOPROC', 15: 'HIPROC'}
618         ELF32_ST_TYPE = {0: 'NOTYPE', 1: 'OBJECT', 2: 'FUNC', 3: 'SECTION', 4: 'FILE', 13: 'LOPROC', 15: 'HIPROC'}
619         SHN_TYPE = {0: 'UNDEF', 0xfff1: 'ABS', 0xfff2: 'COMMON', }
620 
621         for index in range(len(self.symbolTable)):
622             elf32_Sym = self.symbolTable[index]
623             bind = elf32_Sym.st_info >> 4
624             type = elf32_Sym.st_info & 0xf
625 
626             if elf32_Sym.st_shndx == 0 or elf32_Sym.st_shndx == 0xfff1 or elf32_Sym.st_shndx == 0xfff2:
627                 shn_type = SHN_TYPE[elf32_Sym.st_shndx]
628             else:
629                 shn_type = str(elf32_Sym.st_shndx)
630             print('  [%4d] %-10s%-8d%-8s%-8s%-8d%-8s%-8s' % (
631                 index,
632                 hex(elf32_Sym.st_value),
633                 elf32_Sym.st_size,
634                 ELF32_ST_TYPE[type],
635                 BIND_TYPE[bind],
636                 elf32_Sym.st_other,
637                 shn_type,
638                 elf32_Sym.symbol_name
639             ))
640         print()
641 
642     def initDynamicLinkTable(self):
643         # init dynamic
644         elf32_Shdr = self.getSectionByName('.dynamic')
645         if elf32_Shdr != None:
646             for i in range(int(elf32_Shdr.sh_size / elf32_Shdr.sh_entsize)):
647                 self.dynamicLinkTable.append(
648                     self.parseDynamicLinkTable(elf32_Shdr.sh_offset + i * elf32_Shdr.sh_entsize))
649 
650     def parseDynamicLinkTable(self, offset):
651         '''
652         typedef struct dynamic{
653           Elf32_Sword d_tag;
654           union{
655             Elf32_Sword    d_val;
656             Elf32_Addr    d_ptr;
657           } d_un;
658         } Elf32_Dyn;
659         '''
660         self.f.seek(offset, 0)
661         elf32_Dyn = Elf32_Dyn()
662         elf32_Dyn.d_tag = int.from_bytes(self.f.read(4), 'little')
663         elf32_Dyn.d_un = int.from_bytes(self.f.read(4), 'little')
664         return elf32_Dyn
665 
666     def displayDynamicLinkTable(self):
667         print('[+] Dynamic Link Table:')
668         print('  #      %-16s%-16s%-8s' % ('Tag', 'Type', 'Name/Value'))
669 
670         for index in range(len(self.dynamicLinkTable)):
671             elf32_Dyn = self.dynamicLinkTable[index]
672             print('  [%4d] %-16s%-16s%-16s' % (
673                 index,
674                 hex(elf32_Dyn.d_tag),
675                 DYNAMIC_TYPE[elf32_Dyn.d_tag],
676                 self.getElf32_Dyn_TypeInfo(elf32_Dyn),
677 
678             ))
679 
680     def getElf32_Dyn_TypeInfo(self, elf32_Dyn):
681         if elf32_Dyn.d_tag == 1:  # DT_NEEDED
682             idx = self.dynstrTable.find(0, elf32_Dyn.d_un)
683             return 'Shared library: [%s]' % self.dynstrTable[elf32_Dyn.d_un: idx]
684 
685         elif elf32_Dyn.d_tag == 0xe:  # DT_SONAME
686             idx = self.dynstrTable.find(0, elf32_Dyn.d_un)
687             return 'Library soname: [%s]' % self.dynstrTable[elf32_Dyn.d_un: idx]
688 
689         return hex(elf32_Dyn.d_un)
690 
691     def displayELFHeader(self):
692         print('[+] ELF Header:')
693         print('e_ident:	%s' % self.elf32_Ehdr.e_ident)
694         print('e_type: 	%s' % self.elf32_Ehdr.e_type)
695         print('e_machine:	%s' % self.elf32_Ehdr.e_machine)
696         print('e_version:	%s' % self.elf32_Ehdr.e_version)
697         print('e_entry:	%s' % self.elf32_Ehdr.e_entry)
698         print('e_phoff:	%s	//Program header offset' % hex(self.elf32_Ehdr.e_phoff))
699         print('e_shoff:	%s	//Section header offset' % hex(self.elf32_Ehdr.e_shoff))
700         print('e_flags:	%s' % self.elf32_Ehdr.e_flags)
701         print('e_ehsize:	%s	//ELF header size' % self.elf32_Ehdr.e_ehsize)
702         print('e_phentsize:	%s	//Program header entry size' % self.elf32_Ehdr.e_phentsize)
703         print('e_phnum:	%s	//Program header number' % self.elf32_Ehdr.e_phnum)
704         print('e_shentsize:	%s	//Section header entry size' % (self.elf32_Ehdr.e_shentsize))
705         print('e_shnum:	%s	//Section header number' % (self.elf32_Ehdr.e_shnum))
706         print('e_shstrndx:	%s	//Section header string index' % (self.elf32_Ehdr.e_shstrndx))
707         print()
708 
709     def disassemble(self):
710         '''
711         Display assembler contents of executable sections (.text .plt ...)
712         '''
713         self.__disassembleTEXTSection()
714         self.__disassemblePLTSection()
715 
716     def __disassembleTEXTSection(self):
717         elf32_Shdr = self.getSectionByName('.text')
718         if elf32_Shdr == None:
719             return
720         # TODO
721         pass
722 
723     def __disassemblePLTSection(self):
724         elf32_Shdr = self.getSectionByName('.plt')
725         if elf32_Shdr == None:
726             return
727         # TODO
728         pass
729 
730     def getSectionByName(self, name):
731         for elf32_Shdr in self.sectionHeaderTable:
732             if elf32_Shdr.section_name == name:
733                 return elf32_Shdr
734         return None
735 
736 
737 if __name__ == '__main__':
738     elf = ELF(sys.argv[1])
739     elf.displayELFHeader()
740     elf.displaySectionHeader()
741     elf.displayProgramHeader()
742     elf.displaySymbolTable()
743     elf.displayDynamicLinkTable()
744     elf.disassemble()
原文地址:https://www.cnblogs.com/DirWang/p/11316892.html