这里是解析ELF头程序头表和节头表的实现:并未对所以平台提供全部支持,但是细节相似。
/*
* ParseHeaders.c
*
* Created on: 2014年7月19日
* Author: angel-toms
*/
#include "ElfParser.h"
Elf32_Ehdr* get_elf_header(MemMapping* mem){
Elf32_Ehdr* pHeader = NULL;
pHeader = (Elf32_Ehdr*) calloc(1,GET_SIZE(Elf32_Ehdr));
if(NULL == pHeader){
perror("Error,malloc elf header failed !");
goto bail;
}
memcpy(pHeader,mem->base,GET_SIZE(Elf32_Ehdr));
bail:
return pHeader;
}
void print_elf_header(MemMapping* mem,Elf32_Ehdr* pHeader){
printf("ELF Header:\n");
printf("Magic: ");
int i = 0;
for(; i < EI_NIDENT ; i++){
printf("%.2X ",pHeader->e_ident[i]);
}
printf("\n");
printf("Class: ");
switch(pHeader->e_ident[EI_CLASS]){
case ELFCLASSNONE:
printf("Unknown class\n");
break;
case ELFCLASS32:
printf("32-bit architecture\n");
break;
case ELFCLASS64:
printf("64-bit architecture\n");
break;
default:
printf("\n");
break;
}
printf("Data: ");
switch(pHeader->e_ident[EI_DATA]){
case ELFDATANONE:
printf("Unknown data format\n");
break;
case ELFDATA2LSB:
printf("2's complement little-endian\n");
break;
case ELFDATA2MSB:
printf("2's complement big-endian\n");
break;
default:
printf("\n");
break;
}
printf("Version: ");
switch(pHeader->e_ident[EI_VERSION]){
case EV_NONE:
printf("Unkwon\n");
break;
case EV_CURRENT:
printf("1 (current)\n");
break;
default:
printf("\n");
break;
}
printf("OS/ABI: ");
switch(pHeader->e_ident[EI_OSABI]){
case ELFOSABI_NONE:
printf("UNIX System V\n");
break;
case ELFOSABI_HPUX:
printf("HP-UX operating system\n");
break;
case ELFOSABI_NETBSD:
printf("NetBSD\n");
break;
case ELFOSABI_LINUX:
printf("GNU/Linux");
break;
case ELFOSABI_HURD:
printf("GNU/Hurd\n");
break;
case ELFOSABI_86OPEN:
printf("86Open common IA32 ABI");
break;
case ELFOSABI_SOLARIS:
printf("Solaris\n");
break;
case ELFOSABI_AIX:
printf("AIX\n");
break;
case ELFOSABI_IRIX:
printf("IRIX\n");
break;
case ELFOSABI_FREEBSD:
printf("FreeBSD\n");
break;
case ELFOSABI_TRU64:
printf("TRU64 UNIX\n");
break;
case ELFOSABI_MODESTO:
printf("Novell Modesto\n");
break;
case ELFOSABI_OPENBSD:
printf("OpenBSD\n");
break;
case ELFOSABI_OPENVMS:
printf("Open VMS\n");
break;
case ELFOSABI_NSK:
printf("HP Non-Stop Kernel\n");
break;
case ELFOSABI_AROS:
printf("Amiga Research OS\n");
break;
case ELFOSABI_ARM:
printf("ARM\n");
break;
case ELFOSABI_STANDALONE:
printf("Standalone (embedded) application\n");
break;
default:
printf("\n");
break;
}
printf("ABI Version: ");
switch(pHeader->e_ident[EI_ABIVERSION]){
case 0:
printf("0\n");
break;
default:
printf("\n");
break;
}
printf("Type: ");
switch(pHeader->e_type){
case ET_NONE:
printf("Unknown type\n");
break;
case ET_REL:
printf("Relocatable\n");
break;
case ET_EXEC:
printf("Executable\n");
break;
case ET_DYN:
printf("Shared object\n");
break;
case ET_CORE:
printf("Core file\n");
break;
case ET_LOOS:
printf("First operating system specific\n");
break;
case ET_HIOS:
printf("Last operating system-specific\n");
break;
case ET_LOPROC:
printf("First processor-specific\n");
break;
case ET_HIPROC:
printf("Last processor-specific\n");
break;
default:
break;
}
printf("Machine: ");
switch(pHeader->e_machine){
case EM_NONE:
printf("Unknown machine\n");
break;
case EM_M32:
printf("AT&T WE32100\n");
break;
case EM_SPARC:
printf("Sun SPARC\n");
break;
case EM_386:
printf("Intel i386\n");
break;
case EM_68K:
printf("Motorola 68000\n");
break;
case EM_88K:
printf("Motorola 88000\n");
break;
case EM_860:
printf("Intel i860\n");
break;
case EM_MIPS:
printf("MIPS R3000 Big-Endian only\n");
break;
case EM_S370:
printf("IBM System/370\n");
break;
case EM_MIPS_RS3_LE:
printf("MIPS R3000 Little-Endian\n");
break;
case EM_PARISC:
printf("HP PA-RISC\n");
break;
case EM_VPP500:
printf("Fujitsu VPP500\n");
break;
case EM_SPARC32PLUS:
printf("SPARC v8plus\n");
break;
case EM_960:
printf("Intel 80960\n");
break;
case EM_PPC:
printf("PowerPC 32-bit\n");
break;
case EM_PPC64:
printf("PowerPC 64-bit\n");
break;
case EM_S390:
printf("IBM System/390\n");
break;
case EM_V800:
printf("NEC V800\n");
break;
case EM_FR20:
printf("Fujitsu FR20\n");
break;
case EM_RH32:
printf("TRW RH-32\n");
break;
case EM_RCE:
printf("Motorola RCE\n");
break;
case EM_ARM:
printf("ARM\n");
break;
case EM_SH:
printf("Hitachi SH\n");
break;
case EM_SPARCV9:
printf("SPARC v9 64-bit\n");
break;
case EM_TRICORE:
printf("Siemens TriCore embedded processor\n");
break;
case EM_ARC:
printf("Argonaut RISC Core\n");
break;
case EM_H8_300:
printf("Hitachi H8/300\n");
break;
case EM_H8S:
printf("Hitachi H8S\n");
break;
case EM_H8_500:
printf("Hitachi H8/500\n");
break;
case EM_IA_64:
printf("Intel IA-64 Processor\n");
break;
case EM_MIPS_X:
printf("Stanford MIPS-X\n");
break;
case EM_COLDFIRE:
printf("Motorola ColdFire\n");
break;
case EM_68HC12:
printf("Motorola M68HC12\n");
break;
case EM_MMA:
printf("Fujitsu MMA\n");
break;
case EM_PCP:
printf("Siemens PCP\n");
break;
case EM_NCPU:
printf("Sony nCPU\n");
break;
case EM_NDR1:
printf("Denso NDR1 microprocessor\n");
break;
case EM_STARCORE:
printf("Motorola Star*Core processor\n");
break;
case EM_ME16:
printf("Toyota ME16 processor\n");
break;
case EM_ST100:
printf("STMicroelectronics ST100 processor\n");
break;
case EM_TINYJ:
printf("Advanced Logic Corp. TinyJ processor\n");
break;
case EM_X86_64:
printf("Advanced Micro Devices x86-64\n");
break;
case EM_PDSP:
printf("Sony DSP Processor\n");
break;
case EM_FX66:
printf("Siemens FX66 microcontroller\n");
break;
case EM_ST9PLUS:
printf("STMicroelectronics ST9+ 8/16 microcontroller\n");
break;
case EM_ST7:
printf("STmicroelectronics ST7 8-bit microcontroller\n");
break;
case EM_68HC16:
printf("Motorola MC68HC16 microcontroller\n");
break;
case EM_68HC11:
printf("Motorola MC68HC11 microcontroller\n");
break;
case EM_68HC08:
printf("Motorola MC68HC08 microcontroller\n");
break;
case EM_68HC05:
printf("Motorola MC68HC05 microcontroller\n");
break;
case EM_SVX:
printf("Silicon Graphics SVx\n");
break;
case EM_ST19:
printf("STMicroelectronics ST19 8-bit mc\n");
break;
case EM_VAX:
printf("Digital VAX\n");
break;
case EM_CRIS:
printf("Axis Communications 32-bit embedded processor\n");
break;
case EM_JAVELIN:
printf("Infineon Technologies 32-bit embedded processor\n");
break;
case EM_FIREPATH:
printf("Element 14 64-bit DSP Processor\n");
break;
case EM_ZSP:
printf("LSI Logic 16-bit DSP Processor\n");
break;
case EM_MMIX:
printf("Donald Knuth's educational 64-bit proc\n");
break;
case EM_HUANY:
printf("Harvard University machine-independent object files\n");
break;
case EM_PRISM:
printf("SiTera Prism\n");
break;
case EM_AVR:
printf("Atmel AVR 8-bit microcontroller\n");
break;
case EM_FR30:
printf("Fujitsu FR30\n");
break;
case EM_D10V:
printf("Mitsubishi D10V\n");
break;
case EM_D30V:
printf("Mitsubishi D30V\n");
break;
case EM_V850:
printf("NEC v850\n");
break;
case EM_M32R:
printf("Mitsubishi M32R\n");
break;
case EM_MN10300:
printf("Matsushita MN10300\n");
break;
case EM_MN10200:
printf("Matsushita MN10200\n");
break;
case EM_PJ:
printf("picoJava\n");
break;
case EM_OPENRISC:
printf("OpenRISC 32-bit embedded processor\n");
break;
case EM_ARC_A5:
printf("ARC Cores Tangent-A5\n");
break;
case EM_XTENSA:
printf("Tensilica Xtensa Architecture\n");
break;
case EM_VIDEOCORE:
printf("Alphamosaic VideoCore processor\n");
break;
case EM_TMM_GPP:
printf("hompson Multimedia General Purpose Processor\n");
break;
case EM_NS32K:
printf("National Semiconductor 32000 series\n");
break;
case EM_TPC:
printf("Tenor Network TPC processor\n");
break;
case EM_SNP1K:
printf("Trebia SNP 1000 processor\n");
break;
case EM_ST200:
printf("STMicroelectronics ST200 microcontroller\n");
break;
case EM_IP2K:
printf("Ubicom IP2xxx microcontroller family\n");
break;
case EM_MAX:
printf("MAX Processor\n");
break;
case EM_CR:
printf("National Semiconductor CompactRISC microprocessor\n");
break;
case EM_F2MC16:
printf("Fujitsu F2MC16\n");
break;
case EM_MSP430:
printf("exas Instruments embedded microcontroller msp430\n");
break;
case EM_BLACKFIN:
printf("Analog Devices Blackfin (DSP) processor\n");
break;
case EM_SE_C33:
printf("S1C33 Family of Seiko Epson processors\n");
break;
case EM_SEP:
printf("Sharp embedded microprocessor\n");
break;
case EM_ARCA:
printf("Arca RISC Microprocessor\n");
break;
case EM_UNICORE:
printf("Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University\n");
break;
case EM_486:
printf("Intel i486\n");
break;
case EM_ALPHA_STD:
printf("Digital Alpha (standard value)\n");
break;
case EM_ALPHA:
printf("Alpha (written in the absence of an ABI\n");
break;
default:
printf("\n");
break;
}
printf("Version: 0x%x\n",pHeader->e_version);
printf("Entry point address: 0x%.8x\n",pHeader->e_entry);
printf("Start of program headers: %u (bytes into file)\n",pHeader->e_phoff);
printf("Start of section headers: %u (bytes into file)\n",pHeader->e_shoff);
printf("Flags: 0x%x\n",pHeader->e_flags);
printf("Size of this header: %u (bytes)\n",pHeader->e_ehsize);
printf("Size of program headers: %u (bytes)\n",pHeader->e_phentsize);
printf("Number of program headers: %u\n",pHeader->e_phnum);
printf("Size of section headers: %u (bytes)\n",pHeader->e_shentsize);
printf("Number of section headers: %u\n",pHeader->e_shnum);
printf("Section header string table index: %u\n",pHeader->e_shstrndx);
}
Elf32_Phdr* get_elf_program_header_table(MemMapping* mem,Elf32_Ehdr* pHeader){
Elf32_Phdr* pPheader = NULL;
pPheader = (Elf32_Phdr*)calloc(pHeader->e_phnum,pHeader->e_phentsize);
if(NULL == pPheader){
perror("Error,calloc elf program header failed");
goto bail;
}
memcpy(pPheader,(mem->base + pHeader->e_phoff),(pHeader->e_phnum * pHeader->e_phentsize));
bail:
return pPheader;
}
void print_elf_program_header_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Phdr* pPheader){
u4 phOff = (u4)(mem->base + pHeader->e_phoff);
u1 i = 0;
printf("Program Headers:\n");
printf("Program header num %u, offset in file %u, relative offset in mem %u\n",pHeader->e_phnum,pHeader->e_phoff,phOff);
printf("There are %u program headers, starting at offset in file %u\n",pHeader->e_phnum,pHeader->e_phoff);
printf("Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n");
for( ; i < pHeader->e_phnum ; i++ ){
switch(pPheader[i].p_type){
case PT_NULL:
printf("%-45s","Unused entry");
break;
case PT_LOAD:
printf("%-45s","Loadable segment");
break;
case PT_DYNAMIC:
printf("%-45s","Dynamic linking information segment");
break;
case PT_INTERP:
printf("%-45s","Pathname of interpreter");
break;
case PT_NOTE:
printf("%-45s","Auxiliary information");
break;
case PT_SHLIB:
printf("%-45s","Reserved (not used)");
break;
case PT_PHDR:
printf("%-45s","Location of program header itself");
break;
case PT_TLS:
printf("%-45s","Thread local storage segment");
break;
case PT_LOOS:
printf("%-45s","First OS-specific");
break;
case PT_SUNW_UNWIND:
printf("%-45s","amd64 UNWIND program header");
break;
case PT_GNU_EH_FRAME:
printf("%-45s","GNU_EH_FRAME");
break;
case PT_GNU_STACK:
printf("%-45s","GNU_STACK");
break;
case PT_GNU_RELRO:
printf("%-45s","GNU_RELRO");
break;
case PT_LOSUNW:
printf("%-45s","LOSUNW");
break;
case PT_SUNWSTACK:
printf("%-45s","describes the stack segment");
break;
case PT_SUNWDTRACE:
printf("%-45s","private");
break;
case PT_SUNWCAP:
printf("%-45s","hard/soft capabilities segment");
break;
case PT_HISUNW:
printf("%-45s","HISUNW");
break;
case PT_LOPROC:
printf("%-45s","First processor-specific type");
break;
case PT_HIPROC:
printf("%-45s","Last processor-specific type");
break;
case PT_ARM_EXIDX:
printf("%-45s","ARM EXIDX");
break;
default:
printf("%-45X",pPheader[i].p_type);
break;
}
printf("0x%.6x ",pPheader[i].p_offset);
printf("0x%.8x ",pPheader[i].p_vaddr);
printf("0x%.8x ",pPheader[i].p_paddr);
printf("0x%.5x ",pPheader[i].p_filesz);
printf("0x%.5x ",pPheader[i].p_memsz);
switch(pPheader[i].p_flags){
case PF_X:
printf(" E ");
break;
case PF_W:
printf(" W ");
break;
case PF_R:
printf("R ");
break;
case (PF_X | PF_W):
printf(" WE ");
break;
case (PF_X | PF_R):
printf("R E ");
break;
case (PF_W | PF_R):
printf("RW ");
break;
case (PF_W | PF_R | PF_X):
printf("RWE ");
break;
default:
printf(" ");
break;
}
printf("0x%.4x\n",pPheader[i].p_align);
}
}
Elf32_Shdr* get_elf_section_header_table(MemMapping* mem,Elf32_Ehdr* pHeader){
Elf32_Shdr* pSheader = NULL;
pSheader = calloc(pHeader->e_shnum,pHeader->e_shentsize);
if(NULL == pSheader){
perror("Error,calloc elf section header failed");
goto bail;
}
memcpy(pSheader,(mem->base + pHeader->e_shoff) ,( pHeader->e_shnum * pHeader->e_shentsize ));
bail:
return pSheader;
}
void print_elf_section_header_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader){
u1 i = 0;
u1* stringTableMem = get_elf_section_of_shstr_table(mem,pHeader,pSheader);
if(NULL == stringTableMem){
printf("Error,get elf section header string table failed");
return;
}
printf("Section Headers:\n");
printf("There are %u section headers, starting at offset in file 0x%.8x,starting at offset relative 0x%.8x:\n"
,pHeader->e_shnum,pHeader->e_shoff,(u4)(mem->base + pHeader->e_shoff));
printf("[Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n");
for( ; i < pHeader->e_shnum ; i++ ){
printf("[%2u] ",i);
printf("%-20s",(stringTableMem + pSheader[i].sh_name));
switch(pSheader[i].sh_type){
case SHT_NULL:
printf("%-35s","NULL");
break;
case SHT_PROGBITS:
printf("%-35s","program defined information");
break;
case SHT_SYMTAB:
printf("%-35s","symbol table section");
break;
case SHT_STRTAB:
printf("%-35s","string table section");
break;
case SHT_RELA:
printf("%-35s","relocation section with addends");
break;
case SHT_HASH:
printf("%-35s","symbol hash table section");
break;
case SHT_DYNAMIC:
printf("%-35s","dynamic section");
break;
case SHT_NOTE:
printf("%-35s","note section");
break;
case SHT_NOBITS:
printf("%-35s","no space section");
break;
case SHT_REL:
printf("%-35s","relocation section - no addends");
break;
case SHT_SHLIB:
printf("%-35s","reserved - purpose unknown");
break;
case SHT_DYNSYM:
printf("%-35s","dynamic symbol table section");
break;
case SHT_INIT_ARRAY:
printf("%-35s","Initialization function pointers");
break;
case SHT_FINI_ARRAY:
printf("%-35s","Termination function pointers");
break;
case SHT_PREINIT_ARRAY:
printf("%-35s","Pre-initialization function ptrs");
break;
case SHT_GROUP:
printf("%-35s","Section group");
break;
case SHT_SYMTAB_SHNDX:
printf("%-35s","Section indexes (see SHN_XINDEX)");
break;
case SHT_LOOS:
printf("%-35s","First of OS specific semantics");
break;
case SHT_LOSUNW:
printf("%-35s","LOSUNW");
break;
case SHT_SUNW_cap:
printf("%-35s","SUNW_cap");
break;
case SHT_SUNW_SIGNATURE:
printf("%-35s","SUNW_SIGNATURE");
break;
case SHT_SUNW_ANNOTATE:
printf("%-35s","SUNW_ANNOTATE");
break;
case SHT_SUNW_DEBUGSTR:
printf("%-35s","SUNW_DEBUGSTR");
break;
case SHT_SUNW_DEBUG:
printf("%-35s","SUNW_DEBUG");
break;
case SHT_SUNW_move:
printf("%-35s","SUNW_move");
break;
case SHT_SUNW_COMDAT:
printf("%-35s","SUNW_COMDAT");
break;
case SHT_SUNW_syminfo:
printf("%-35s","SUNW_syminfo");
break;
case SHT_SUNW_verdef:
printf("%-35s","SUNW_verdef");
break;
case SHT_GNU_verneed:
printf("%-35s","Symbol versions required");
break;
case SHT_GNU_versym:
printf("%-35s","Symbol version table");
break;
case SHT_LOPROC:
printf("%-35s","reserved range for processor");
break;
case SHT_MIPS_OPTIONS:
printf("%-35s","MIPS_OPTIONS");
break;
case SHT_MIPS_DWARF:
printf("%-35s","MIPS gcc uses MIPS_DWARF");
break;
case SHT_HIPROC:
printf("%-35s","specific section header types");
break;
case SHT_LOUSER:
printf("%-35s","reserved range for application");
break;
case SHT_HIUSER:
printf("%-35s","specific indexes");
break;
case SHT_MIPS_MSYM:
printf("%-35s","ARM_EXIDX");
break;
case SHT_MIPS_GPTAB:
printf("%-35s","ARM_ATTRIBUTES");
break;
default:
printf("%-35x",pSheader[i].sh_type);
break;
}
printf("%.8x ",pSheader[i].sh_addr);
printf("%.6x ",pSheader[i].sh_offset);
printf("%.6x ",pSheader[i].sh_size);
printf("%.2x ",pSheader[i].sh_entsize);
switch(pSheader[i].sh_flags){
case SHF_WRITE:
printf(" W ");
break;
case SHF_ALLOC:
printf(" A ");
break;
case SHF_EXECINSTR:
printf(" X ");
break;
case SHF_MERGE:
printf(" M ");
break;
case SHF_STRINGS:
printf(" S ");
break;
case SHF_INFO_LINK:
printf(" I ");
break;
case SHF_LINK_ORDER:
printf(" L ");
break;
case SHF_OS_NONCONFORMING:
printf(" O ");
break;
case SHF_GROUP:
printf(" G ");
break;
case SHF_TLS:
printf(" ");
break;
case SHF_MASKOS:
printf(" ");
break;
case SHF_MASKPROC:
printf(" p ");
break;
case (SHF_WRITE | SHF_ALLOC):
printf(" WA ");
break;
case (SHF_WRITE | SHF_EXECINSTR):
printf(" WX ");
break;
case (SHF_EXECINSTR | SHF_ALLOC):
printf(" XA ");
break;
case (SHF_EXECINSTR | SHF_ALLOC |SHF_WRITE ):
printf(" WXA ");
break;
default:
//other | ellipsis
printf(" ");
break;
}
printf("%x ",pSheader[i].sh_link);
printf("%3u ",pSheader[i].sh_info);
printf("%u",pSheader[i].sh_addralign);
printf("\n");
}
printf("Key to Flags:\n");
printf(" W (write), A (alloc), X (execute), M (merge), S (strings)\n");
printf(" I (info), L (link order), G (group), x (unknown)\n");
printf(" O (extra OS processing required) o (OS specific), p (processor specific)\n");
printf("\n");
free(stringTableMem);
}