#!/usr/bin/python
import struct
import sys
elfhdr = {}
def verify_elf(filename):
f = open(filename,'rb')
elfident = f.read(16)
magic = [ord(i) for i in elfident]
if( magic[0] != 127 or magic[1]!= ord('E') or magic[2] != ord('L') or magic[3] != ord('F')):
print "your input file %s not a elf file" %filename
return
else:
temp = f.read(struct.calcsize('2HI3QI6H'))
temp = struct.unpack('2HI3QI6H',temp)
global elfhdr
elfhdr['magic'] = magic
elfhdr['e_type']= temp[0]
elfhdr['e_machine'] = temp[1]
elfhdr['e_version'] = temp[2]
elfhdr['e_entry'] = temp[3]
elfhdr['e_phoff'] = temp[4]
elfhdr['e_shoff'] = temp[5]
elfhdr['e_flags'] = temp[6]
elfhdr['e_ehsize'] = temp[7]
elfhdr['e_phentsize'] = temp[8]
elfhdr['e_phnum'] = temp[9]
elfhdr['e_shentsize'] = temp[10]
elfhdr['e_shnum'] = temp[11]
elfhdr['e_shstrndx'] = temp[12]
f.close()
def display_elfhdr(elffile):
global elfhdr
print "ELF Header"
magic = elfhdr['magic']
print " Magic: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" %(magic[0] ,magic[1],magic[2],magic[3],magic[4],magic[5],magic[6],magic[7],magic[8],magic[9],magic[10],magic[11],magic[12],magic[13],magic[14],magic[15])
if magic[4] == 1 :
print " Class: ELF32"
else:
print " Class: ELF64"
if magic[5] == 1:
print " Data: 2's complement,little endian"
else:
print "Data: 2's complement,bigendian"
print " Version: %d(current)" %magic[6]
if magic[7] == 0:
os_abi = 'System V ABI'
elif magic[7]== 1:
os_abi = 'HP-Ux operating system'
elif magic[7] == 255:
os_abi = 'Standalone (embedded) application'
print " OS/ABI: %s" %os_abi
print " ABI Version: %d" %magic[8]
if elfhdr['e_type'] == 0:
type = 'No file type'
elif elfhdr['e_type'] == 1:
type = 'Relocatable object file'
elif elfhdr['e_type'] == 2:
type = 'Executable file'
elif elfhdr['e_type'] == 3:
type = 'Core file'
print " Type: %s" %type
print " Machine: %d" %elfhdr['e_machine']
print " Version: 0x%x" %elfhdr['e_version']
print " Entry point address: 0x%x" %elfhdr['e_entry']
print " Start of program headers: %d (bytes into file)" %elfhdr['e_phoff']
print " Start of section headers: %d (bytes into file)" %elfhdr['e_shoff']
print " Flags: 0x%x" %elfhdr['e_flags']
print " Size of this header: %d (bytes)" %elfhdr['e_ehsize']
print " Size of program headers: %d (bytes)" %elfhdr['e_phentsize']
print " Number of program headers: %d " %elfhdr['e_phnum']
print " Size of section headers: %d (bytes)" %elfhdr['e_shentsize']
print " Number of section headers: %d" %elfhdr['e_shnum']
print " Section header string table index: %d"%elfhdr['e_shstrndx']
def display_sections(elffile):
verify_elf(elffile)
sections = []
global elfhdr
sec_start = elfhdr['e_shoff']
sec_size = elfhdr['e_shentsize']
f = open(elffile,'rb')
f.seek(sec_start)
for i in range(0,elfhdr['e_shnum']):
temp = f.read(sec_size)
temp = struct.unpack('2I4Q2I2Q',temp)
sec = {}
sec['sh_name'] = temp[0]
sec['sh_type'] = temp[1]
sec['sh_flags'] = temp[2]
sec['sh_addr'] = temp[3]
sec['sh_offset'] = temp[4]
sec['sh_size'] = temp[5]
sec['sh_link'] = temp[6]
sec['sh_info'] = temp[7]
sec['sh_addralign'] = temp[8]
sec['sh_entsize'] = temp[9]
sections.append(sec)
print "There are %d section headers,starting at offset 0x%x:\n" %(elfhdr['e_shnum'],sec_start)
print "Section Headers:"
print " [Nr] Name Type Address Offset"
print " Size Entsize Flags Link Info Align"
start = sections[elfhdr['e_shstrndx']]['sh_offset']
for i in range(0,elfhdr['e_shnum']):
offset = start + sections[i]['sh_name']
name = get_name(f,offset)
type2str = ['NULL','PROGBITS','SYMTAB','STRTAB','RELA','HASH','DYNAMIC','NOTE','NOBITS','REL','SHLIB','DYNSYM']
flags = sections[i]['sh_flags']
if (flags == 1):
flagsstr = 'W'
elif (flags == 2):
flagsstr = 'A'
elif (flags == 4):
flagsstr = 'X'
elif (flags == 3):
flagsstr = 'W' + 'A'
elif (flags == 6):
flagsstr = 'A' + 'X'
elif (flags == 0x0f000000 or flags == 0xf0000000):
flagsstr = 'MS'
else:
flagsstr = ''
print " [%d] %s %s %x %x" %(i,name,type2str[sections[i]['sh_type'] & 0x7],sections[i]['sh_addr'],sections[i]['sh_addralign'])
print " %x %x %s %d %d %x" %(sections[i]['sh_size'],sections[i]['sh_entsize'],flagsstr,sections[i]['sh_link'],sections[i]['sh_info'],sections[i]['sh_addralign'])
f.close()
def get_name(f,offset):
name = ''
f.seek(offset)
while 1:
c = f.read(1)
if c == '\0':
break
else:
name += c
return name
if __name__ == '__main__':file = sys.argv[1]
verify_elf(file)
display_elfhdr(file)
display_sections(file)
未完待续