解析ELF 头 程序头表 节头表

这里是解析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);

}


猜你喜欢

转载自blog.csdn.net/ylcangel/article/details/37997733