对elf进行解析

 elf.c

/**************************************
 *Copyright yldfree 
 *2017-10-5
 * ************************************/
#include <stdio.h>
#include <stdlib.h>
#include <elf.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include "elf.h"

void show_arg_help(void)
{
    printf("\t -ehdr filename  show elf header\n"); 
    printf("\t -phdr filename  show elf program header info\n"); 
    printf("\t -shdr filename  show elf section header info\n"); 
    printf("\t -symtab filename  show elf symbol table info\n"); 
    printf("\t -dsymtab filename  show elf symbol table info\n"); 
    printf("\t -dynamic filename  show elf symbol table info\n"); 
    return;
}

int parse_args(int argc,char*argv[],char *buff)
{
    int index = 1;
         
    if(!strcmp(argv[index],"-ehdr"))
    {
        strcpy(buff,argv[index+1]); 
        return SHOW_EHDR; 
    }
    if(!strcmp(argv[index],"-phdr"))
    {
        strcpy(buff,argv[index+1]); 
        return SHOW_PHDR; 
    }

    if(!strcmp(argv[index],"-shdr"))
    {
        strcpy(buff,argv[index+1]); 
        return SHOW_SHDR;
    }
    if(!strcmp(argv[index],"-symtab"))
    {
        strcpy(buff,argv[index+1]); 
        return SHOW_SYMTAB;
    }
    if(!strcmp(argv[index],"-dsymtab"))
    {
        strcpy(buff,argv[index+1]); 
        return SHOW_DSYMTAB;
    }
    if(!strcmp(argv[index],"-dynamic"))
    {
        strcpy(buff,argv[index+1]); 
        return SHOW_DYNAMIC;
    }
    if(!strcmp(argv[index],"-rel"))
    {
        strcpy(buff,argv[index+1]); 
        return SHOW_RELTAB;
    }
   
    show_arg_help(); 
    return SHOW_MAX;   
}

char *get_machine_type(int matype)
{
    switch(matype)
    {
        case EM_M32:		return "WE32100";
        case EM_SPARC:		return "Sparc";
        case EM_386:		return "Intel 80386";
        case EM_68K:		return "MC68000";
        case EM_88K:		return "MC88000";
        case EM_860:		return "Intel 80860";
        case EM_MIPS:		return "MIPS R3000";
        case EM_PARISC:		return "HPPA";
        case EM_SPARC32PLUS:	return "Sparc v8+" ;
        case EM_PPC:		return "PowerPC";
        case EM_PPC64:		return "PowerPC64";
        case EM_S390:            return "EM_S390";
        case EM_SH:		return "Renesas / SuperH SH";
        case EM_SPARCV9:	return "Sparc v9";
        case EM_IA_64:		return "Intel IA-64";
        case EM_CRIS:		return "Axis Communications 32-bit embedded processor";
        case EM_V850:		return "NEC v850";
        case EM_X86_64:		return "Advanced Micro Devices X86-64";
        case EM_M32R:	        return "Renesas M32R";
	case EM_H8_300:		return "Renesas H8/300,300H,H8S";
        case EM_MN10300:	return "Panasonic/MEI MN10300, AM33";      
        default:                return "Invalid";
    } 
}


void show_ehdr(ObjElf *pelf)
{
    int i;
    printf("*******************************show elf header****************************************\n\n");
   
    printf("Magic:                  ");   
    for(i = 0; i < EI_NIDENT; i++)//EI_NIDENT=16
        printf("%02x ",pelf->ehdr->e_ident[i]);
    printf("\n");
    printf("\t                ************************************\n");
    printf("\t                * M[4]SysBit: ");
    switch(pelf->ehdr->e_ident[4])
    {
        case 1:
	     printf("32 Bit                                   \n");
             break;
        case 2:
	     printf("64 Bit                                   \n");	
	     break;
        default:
	     printf("Undefined                                \n");		
             break;
    }
    printf("\t                * M[5]CodeFormat: ");
    switch(pelf->ehdr->e_ident[5])
    {
        case ELFDATA2LSB://1
	     printf("little endian                            \n");
             break;
        case ELFDATA2MSB:
	     printf("big endain                               \n");
             break;
        default:
	     printf("Invalid                                  \n");
             break;	
    } 	
    printf("\t                ************************************\n"); 
    
    printf("File Type:              ");
    switch(pelf->ehdr->e_type)
    {
        case ET_REL:
	    printf("Relocatable File\n");
            break;
        case ET_EXEC:
	    printf("Execute File\n");
            break;
        case ET_DYN:
            printf("Dynamic File\n");
            break;
        case ET_CORE:
            printf("Core File\n");	
            break;
        default:
	    printf("Invalid File\n");
            break;	 
    }
    printf("Machine Type:           %s\n",get_machine_type(pelf->ehdr->e_machine));
    printf("Version:                0x%x\n",pelf->ehdr->e_version);
    printf("Program Entry:          0x%x\n",pelf->ehdr->e_entry);
    printf("Program Header Offset:  0x%x\n",pelf->ehdr->e_phoff);
    printf("Pro Header item size:   %d\n",pelf->ehdr->e_phentsize);
    printf("Pro Header item Num:    %d\n",pelf->ehdr->e_phnum);   
    printf("Section Header Offset:  0x%x\n",pelf->ehdr->e_shoff);
    printf("Sec Header item size:   %d\n",pelf->ehdr->e_shentsize);
    printf("Sec Header item num:    %d\n",pelf->ehdr->e_shnum);
    printf("Flags:                  0x%x\n",pelf->ehdr->e_flags);
    printf("Elf header size:        %d\n",pelf->ehdr->e_ehsize);
    printf("SecName StrTab Index:   %d\n",pelf->ehdr->e_shstrndx);

    printf("\n**************************************************************************************\n");     

}

char *get_phdr_type(int type)
{
    switch(type)
    {
        case PT_NULL: return "NULL";
 	case PT_LOAD: return "LOAD";
        case PT_DYNAMIC: return "DYNAMIC";
	case PT_INTERP: return "INTERP";
	case PT_NOTE:	return "NOTE";
	case PT_SHLIB:	return "SHLIB";
	case PT_PHDR:   return "PHDR";
    	case PT_TLS:    return"TLS"; 
    	case PT_GNU_EH_FRAME: return "EHFRAME";
    	case PT_GNU_STACK: return "STACK";
    	case PT_GNU_RELRO: return "RELRO";
    } 

    return "NULL";
}

char * get_phdr_flags(int flag,char *buff)
{  
    if(flag & PF_R) 
      strcat(buff,"R");
    if(flag & PF_W)
      strcat(buff,"W");
    if(flag & PF_X)
      strcat(buff,"X");
    if('\0' == buff[0])
      strcat(buff,"NULL");	
    return buff;      
}

void show_phdr(ObjElf *pelf)
{
    int phnum = pelf->ehdr->e_phnum;
    int phentsize = pelf->ehdr->e_phentsize;   
    int i = 0;
    char buff[10];

    if(NULL == pelf)
    {
        printf("Error !!  parse Program header error\n");
        return;
    }         
    printf("\n********************************************Parser Program Header ***********************************************\n");
    printf("* item size: %d, item num:%d  R:读 W:写 X:执行*\n\n",phentsize,phnum);
    printf("%7s | %4s | %8s(d) | %8s(x) | %8s(x) | %8s(d) | %8s(d) | %8s(x) |\n","Type","Flags","offset","vaddr","paddr","fsize","msize","align");
    printf("-----------------------------------------------------------------------------------------------------\n");
    for(i = 0; i < phnum; i++)
    {
        memset(buff,0,10);   
        if( 0 == i % 2)
            printf("\033[32m");
        printf("%7s | ",get_phdr_type(pelf->phdr[i].p_type));
        printf("%4s  |",get_phdr_flags(pelf->phdr[i].p_flags,buff));
        printf("%8d     |",pelf->phdr[i].p_offset);  
        printf("%8x     |",pelf->phdr[i].p_vaddr);  
        printf("%8x     |",pelf->phdr[i].p_paddr);  
        printf("%8ld     |",pelf->phdr[i].p_filesz);    
        printf("%8ld     |",pelf->phdr[i].p_memsz);  
        printf("%8x     |",pelf->phdr[i].p_align);      
        if( 0 == i % 2)
            printf("\033[0m");
        printf("\n");
    }
    printf("------------------------------------------------------------------------------------------------------\n");
    printf("NULL: 不知类型. \nLOAD: 可以加载,如(.data .text). \nDYNAMIC: 动态连接段. \nINTERP: 动态链接器.\n");
    printf("NOTE: 辅助信息\nSHLIB: 保留字段\nPHDR: 指定程序头表在文件及程序内存映像中的位置和大小\n");
    printf("TLS:  线程本地存储信息\nEHFRAME: 异常处理信息的位置和大小\n");	
    printf("STACK: 包含了堆栈段的权限 \nRELRO: 段内的数据在重定向后是只读的\n");
    
    printf("\n*****************************************************************************************************************\n\n");
   
 
}

char *get_section_flag(int flag,char *buff)
{
     if(flag & SHF_WRITE)
        strcat(buff,"W");
     if(flag & SHF_ALLOC)
        strcat(buff,"A");
     if(flag & SHF_EXECINSTR) 
        strcat(buff,"X"); 
     if(flag & SHF_MERGE)
        strcat(buff,"M");
     if(flag & SHF_STRINGS)
        strcat(buff,"S");
     if(flag & SHF_INFO_LINK) 
        strcat(buff,"I");
     if(flag & SHF_LINK_ORDER)
        strcat(buff,"L");
     if(flag & SHF_OS_NONCONFORMING)
        strcat(buff,"O");
     if(flag & SHF_GROUP)
        strcat(buff,"G");
     if(flag & SHF_TLS)
        strcat(buff,"T");
     if(flag & SHF_EXCLUDE) 
        strcat(buff,"E");  
     if(buff[0] == '\0')
        strcat(buff,"NULL");
     return buff;  
}
char *get_section_type(int type)
{
    switch(type)
    {
        case SHT_PROGBITS:	return "PROGBITS";
        case SHT_SYMTAB:	return "SYMTAB";
        case SHT_STRTAB:	return "STRTAB";
        case SHT_RELA:		return "RELA";
        case SHT_HASH:		return "HASH";
        case SHT_DYNAMIC:	return "DYNAMIC";
        case SHT_NOTE:		return "NOTE";
        case SHT_NOBITS:	return "NOBITS";
        case SHT_REL:		return "REL";
        case SHT_SHLIB:		return "SHLIB";
        case SHT_DYNSYM:	return "DYNSYM";
        case SHT_INIT_ARRAY:	return "INIT_ARRAY";
        case SHT_FINI_ARRAY:	return "FINI_ARRAY";
        case SHT_PREINIT_ARRAY:	return "PREINIT_ARRAY";
        case SHT_GNU_HASH:	return "GNU_HASH";
        case SHT_GROUP:		return "GROUP";
        case SHT_SYMTAB_SHNDX:	return "SYMTAB SECTION INDICIES";
        case SHT_GNU_verdef:	return "VERDEF";
        case SHT_GNU_verneed:	return "VERNEED";
        case SHT_GNU_versym:	return "VERSYM";
        case 0x6ffffff0:	return "VERSYM";
        case 0x6ffffffc:	return "VERDEF";
        case 0x7ffffffd:	return "AUXILIARY";
        case 0x7fffffff:	return "FILTER";
        case SHT_GNU_LIBLIST:	return "GNU_LIBLIST";
        default:		return "NULL";
    }

    return "NULL";
}

void show_shdr(ObjElf *pelf)
{
    int i = 0;
    int shnum = pelf->ehdr->e_shnum;
    int shentsize = pelf->ehdr->e_ehsize;
    char buff[256]={0};  

    printf("**************************************************************show section header********************************************************************\n");
    printf("* section num:%d section item size:%d  W:可写 A:占用内存 X:可执行*\n\n",shnum,shentsize); 
    printf("%20s | %23s | %5s | %9s | %8s | %8s | %8s | %8s | %8s | %12s |\n","name","type","flags","offset(d)","vaddr(x)","size(d)","link(d)","info(d)","align(x)","entsizd(d)");
    
    printf("------------------------------------------------------------------------------------------------------------------------------------------\n");
    for(i = 0; i < shnum; i++)
    {
        memset(buff,0,256); 
        if( 0 == i % 2)
            printf("\033[32m");
        printf("%20s | ",pelf->shstrtab+pelf->shdr[i].sh_name);
        printf("%23s | ",get_section_type(pelf->shdr[i].sh_type));
        printf("%5s | ", get_section_flag(pelf->shdr[i].sh_flags,buff));
        printf("%9d | ",pelf->shdr[i].sh_offset);
        printf("%8x | ",pelf->shdr[i].sh_addr);
        printf("%8d | ",pelf->shdr[i].sh_size);
        printf("%8d | ",pelf->shdr[i].sh_link);
        printf("%8d | ",pelf->shdr[i].sh_info);
        printf("%8x | ",pelf->shdr[i].sh_addralign);
        printf("%12d | ",pelf->shdr[i].sh_entsize);
        if( 0 == i % 2)
            printf("\033[0m");

        printf("\n");
    }
    printf("--------------------------------------------------------------------------------------------------------------------------------------------\n");
     
    

    printf("\n*****************************************************************************************************************************************************\n");
}

char *get_symtabtype(int type)
{
    switch(type)
    {
        case STT_NOTYPE: return "NOTYPE";
        case STT_OBJECT: return "OBJECT";
        case STT_FUNC:   return "FUNC";
        case STT_SECTION:  return  "SECT";  
        case STT_FILE:     return  "FILE";   
        case STT_COMMON:   return  "COMM";  
        case STT_TLS:      return  "TLS";  
        case STT_RELC:     return  "RELC";  
        case STT_SRELC:    return  "SRELC";   
        case STT_GNU_IFUNC: return  "GNUIFUNC";   
        case STT_HIOS:     return  "HIOS";  
    }     

    return "INVAL";
}

char *get_symtabbind(int bind)
{
        
    switch(bind)
    {
        case STB_LOCAL      :return "LOCAL";  
        case STB_GLOBAL     :return "GLOBAL";  
        case STB_WEAK       :return "WEAK";  
        case STB_GNU_UNIQUE :return "GNUUNI";      
        case STB_HIOS       :return "HIOS";  
    }
 
    return "INVAL";
}


char *get_symtabndx(ObjElf  *pelf,int ndx)
{
   if(ndx == SHN_UNDEF)
      return "UNDEF";
   if(ndx == SHN_LORESERVE)
      return "LORESERVE";
   if(ndx == SHN_LOPROC) 
      return "LOPROC";
   if(ndx == SHN_HIPROC) 
      return "HIPROC";
   if(ndx == SHN_ABS)
      return "ABS";
   if(ndx == SHN_COMMON)
      return "COMMON";

   if(ndx >= pelf->ehdr->e_shnum)
     return "INVAL";    
  
   return pelf->shstrtab + pelf->shdr[ndx].sh_name;
} 

void show_symtab(ObjElf *pelf)
{
    int i =0;
  
    printf("%4s | %8s | %8s | %5s | %20s | %8s | %8s | %s \n","Num","type","bind","other","secname","value(x)","size(d)","name");
    printf("-------------------------------------------------------------------------------------\n");
    for(i; i < pelf->symnum; i++)
    { 
        printf("%4d: ",i);
        printf("%8s | ",get_symtabtype(ELF_ST_TYPE(pelf->symtab[i].st_info)));
        printf("%8s | ",get_symtabbind(ELF_ST_BIND(pelf->symtab[i].st_info)));
        printf("%5d | ",pelf->symtab[i].st_other);
        printf("%20s | ",get_symtabndx(pelf,pelf->symtab[i].st_shndx),pelf->symtab[i].st_shndx);
        printf("%8x | ",pelf->symtab[i].st_value);
        printf("%8d | ",pelf->symtab[i].st_size);  
        printf("%s ",pelf->strtab+pelf->symtab[i].st_name);
        printf("\n");  
   }

}

void show_dsymtab(ObjElf *pelf)
{
    int i =0;
  
    printf("%4s | %8s | %8s | %5s | %20s | %8s | %8s | %s \n","Num","type","bind","other","secname","value(x)","size(d)","name");
    printf("-------------------------------------------------------------------------------------\n");
    for(i; i < pelf->dsymnum; i++)
    { 
        printf("%4d: ",i);
        printf("%8s | ",get_symtabtype(ELF_ST_TYPE(pelf->dsymtab[i].st_info)));
        printf("%8s | ",get_symtabbind(ELF_ST_BIND(pelf->dsymtab[i].st_info)));
        printf("%5d | ",pelf->dsymtab[i].st_other);
        printf("%20s | ",get_symtabndx(pelf,pelf->dsymtab[i].st_shndx),pelf->dsymtab[i].st_shndx);
        printf("%8x | ",pelf->dsymtab[i].st_value);
        printf("%8d | ",pelf->dsymtab[i].st_size);  
        printf("%s ",pelf->dstrtab+pelf->dsymtab[i].st_name);
        printf("\n");  
   }

}


char *get_dynamic_tag(int tag)
{
    switch(tag)
    {
        case DT_NEEDED   :return "NEEDED";    
        case DT_NULL     :return "NULL";        
        case DT_PLTRELSZ :return "PLTRELSZ";      
        case DT_PLTGOT   :return "PLTGOT";        
        case DT_HASH     :return "HASH";        
        case DT_STRTAB   :return "STRTAB";      
        case DT_SYMTAB   :return "SYMTAB";        
        case DT_RELA     :return "RELA";     
        case DT_RELASZ   :return "RELASZ";        
        case DT_RELAENT  :return "RELAENT";         
        case DT_STRSZ    :return "STRSZ";        
        case DT_SYMENT   :return "SYMENT";         
        case DT_INIT     :return "INIT";       
        case DT_FINI     :return "FINI";        
        case DT_SONAME   :return "SONAME";         
        case DT_RPATH    :return "RPATH";           
        case DT_SYMBOLIC :return "SYMBOLIC";     
        case DT_REL      :return "REL";        
        case DT_RELSZ    :return "RELSZ";         
        case DT_RELENT   :return "RELENT";      
        case DT_PLTREL   :return "PLTREL";         
        case DT_DEBUG    :return "DEBUG";      
        case DT_TEXTREL  :return "TEXTREL";           
        case DT_JMPREL   :return "JMPREL";     
        case DT_VERSYM    : return "VERSYM";  
        case DT_VERDEF    : return "VERDEF";  
        case DT_VERDEFNUM : return "VERDEFNUM";  
        case DT_VERNEED   : return "VERNEED"; 
        case DT_VERNEEDNUM: return "VERNEEDNUM";   
        case DT_GNU_HASH:   return "GNUHASH";
   }   
    return "INVAL";
}

char * get_dynamic_val(ObjElf *pelf,int index,char *buff)
{
     int tag = pelf->dynamic[index].d_tag;
  
     switch(tag)
     {
         case DT_NEEDED:
              sprintf(buff,"%s", pelf->dstrtab + pelf->dynamic[index].d_un.d_val);   
              break; 
         case DT_NULL     : break; 
         case DT_PLTRELSZ : 
              sprintf(buff,"%d", pelf->dynamic[index].d_un.d_val);
              break;   
         case DT_PLTGOT   : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr);
              break;   
         case DT_HASH     :
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr); 
              break;  
         case DT_STRTAB   : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr); 
              break;  
         case DT_SYMTAB   : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr); 
              break;  
         case DT_RELA     : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr); 
              break; 
         case DT_RELASZ   : 
              sprintf(buff,"%d", pelf->dynamic[index].d_un.d_val);
              break;   
         case DT_RELAENT  : 
              sprintf(buff,"%d", pelf->dynamic[index].d_un.d_val);
              break;     
         case DT_STRSZ    : 
              sprintf(buff,"%d", pelf->dynamic[index].d_un.d_val);
              break;  
         case DT_SYMENT   : 
              sprintf(buff,"%d", pelf->dynamic[index].d_un.d_val);
              break;    
         case DT_INIT     : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr); 
              break; 
         case DT_FINI     : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr); 
              break; 
         case DT_SONAME   : 
              sprintf(buff,"%s", pelf->dstrtab + pelf->dynamic[index].d_un.d_val);   
              break;    
         case DT_RPATH    : 
              sprintf(buff,"%s", pelf->dstrtab + pelf->dynamic[index].d_un.d_val);   
              break;    
         case DT_SYMBOLIC : 
              break;  
         case DT_REL      : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr);    
              break; 
         case DT_RELSZ    : 
              sprintf(buff,"%d", pelf->dynamic[index].d_un.d_val);
              break;   
         case DT_RELENT   : 
              sprintf(buff,"%d", pelf->dynamic[index].d_un.d_val);
              break; 
         case DT_PLTREL   : 
              sprintf(buff,"%d", pelf->dynamic[index].d_un.d_val);
              break;    
         case DT_DEBUG    : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr);    
              break;   
         case DT_TEXTREL  : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr);    
              break;       
         case DT_JMPREL   : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr);    
              break;  
         case DT_VERSYM    : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr);    
              break; 
         case DT_VERDEF    : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr);    
              break; 
         case DT_VERDEFNUM : 
              sprintf(buff,"%d",pelf->dynamic[index].d_un.d_val);    
              break;   
         case DT_VERNEED   : 
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr);    
              break; 
         case DT_VERNEEDNUM: 
              sprintf(buff,"%d",pelf->dynamic[index].d_un.d_val);    
              break;     
         case DT_GNU_HASH:   
              sprintf(buff,"0x%x",pelf->dynamic[index].d_un.d_ptr);    
              break; 
    }   
    return buff;          
}

void show_dynamic(ObjElf *pelf)
{
    int i = 0;
    char tebuff[1024]={0};

    printf("%23s | %s\n","tag","name/value");
    printf("----------------------------------------------\n");
    for(i; i<pelf->dynamicnum; i++)
    {  
        memset(tebuff,0,1024); 
        if(0 == pelf->dynamic[i].d_tag)
            continue;
        printf("%13s(%8x) | ",get_dynamic_tag(pelf->dynamic[i].d_tag),pelf->dynamic[i].d_tag);
        printf("%s ",  get_dynamic_val(pelf,i,tebuff));
        printf("\n");
    }
    printf("----------------------------------------------\n");
    	
    return;		   
}

char *get_reltype(int type)
{
    switch(type)
    {
        case R_X86_64_NONE      :return "NONE";     
        case R_X86_64_64        :return "R_X86_64_64";       
        case R_X86_64_PC32   	:return "R_X86_64_PC32";       
        case R_X86_64_GOT32     :return "R_X86_64_GOT32";            
        case R_X86_64_PLT32     :return "R_X86_64_PLT32";               
        case R_X86_64_COPY      :return "R_X86_64_COPY";              
        case R_X86_64_GLOB_DAT  :return "R_X86_64_GLOB_DAT";              
        case R_X86_64_JUMP_SLOT :return "R_X86_64_JUMP_SLOT";       
        case R_X86_64_RELATIVE  :return "R_X86_64_RELATIVE";        
        case R_X86_64_GOTPCREL  :return "R_X86_64_GOTPCREL";     
        case R_X86_64_32        :return "R_X86_64_32";      
        case R_X86_64_32S       :return "R_X86_64_32S";    
        case R_X86_64_16        :return "R_X86_64_16";      
        case R_X86_64_PC16      :return "R_X86_64_PC16";     
        case R_X86_64_8         :return "R_X86_64_8";        
        case R_X86_64_PC8       :return "R_X86_64_PC8";        
    }   

    return "INVALID";
}

void show_reltab(ObjElf *pelf)
{
    int i,j;
    int flag = 0; 
    int isappend;
    int numitem;
    Elf_Rel *prel = NULL;
    Elf_Rela *prela = NULL;    
        
    for(i = 0; i < pelf->ehdr->e_shnum; i++)
    {
        if(pelf->shdr[i].sh_type == SHT_RELA)
        {
            
            if(0 == flag)
            {
                printf("%10s | %25s | %10s | %s\n","offset(x)","type","sym.val","append");
                flag = 1;
            }
            prela = (Elf_Rela *)(pelf->base + pelf->shdr[i].sh_offset);
            printf("--------------------%s---------------\n",pelf->shstrtab + pelf->shdr[i].sh_name);
            numitem = pelf->shdr[i].sh_size / pelf->shdr[i].sh_entsize;             
            for(j = 0; j< numitem; j++)
            {
                printf("%10x | ",prela[j].r_offset);
                printf("%25s | ",get_reltype(ELF_R_TYPE(prela[j].r_info)));
                printf("%10d | ",pelf->dsymtab[ELF_R_SYM(prela[j].r_info)].st_value);
                printf("%d  ",  prela[j].r_addend);
                printf("\n");  
            }  
        
        }
        else if(pelf->shdr[i].sh_type == SHT_REL)
        {
            if(0 == flag)
            {
                printf("%10s | %25s | %10s | %10s\n","offset(d)","type","sym.val","append");
                flag = 1;
            }
            prel = (Elf_Rel *)(pelf->base + pelf->shdr[i].sh_offset);
            printf("-------------------%s---------------\n",pelf->shstrtab + pelf->shdr[i].sh_name);
            numitem = pelf->shdr[i].sh_size / pelf->shdr[i].sh_entsize;                      
            for(j = 0; j< numitem; j++)
            {
                printf("%10x | ",prel[j].r_offset);
                printf("%25s | ",get_reltype(ELF_R_TYPE(prel[j].r_info)));
                printf("%10d | ",pelf->dsymtab[ELF_R_SYM(prel[j].r_info)].st_value);
                printf("%d  ",  0);
                printf("\n");  
            }  
        
 
        }   

    }    

}

void run_opcode(int type,ObjElf *pelf)
{
    switch(type)
    {
        case SHOW_EHDR:
		show_ehdr(pelf);
		break;
        case SHOW_PHDR:
		show_phdr(pelf);
		break;
	case SHOW_SHDR:
		show_shdr(pelf);
		break;
        case SHOW_SYMTAB:
		show_symtab(pelf);
                break;
        case SHOW_DSYMTAB:
                show_dsymtab(pelf);
                break;
        case SHOW_DYNAMIC:
                show_dynamic(pelf);
                break;
        case SHOW_RELTAB:
                show_reltab(pelf);
                break;
        default:
		break;
    } 
    return;
}

void set_stelf_value(ObjElf *pelf)
{
    int i = 0;
    int shnum = 0;

    pelf->ehdr = (Elf_Ehdr *)pelf->base; //elf header
    pelf->phdr = (Elf_Phdr *)(pelf->ehdr->e_phoff+pelf->base); //pro header offset
    pelf->shdr = (Elf_Shdr *)(pelf->ehdr->e_shoff+pelf->base); //section header offset
    pelf->shstrtab = (char*)(pelf->shdr[pelf->ehdr->e_shstrndx].sh_offset + pelf->base);//shstrtab offset
        
    //获得符号表数组的地址和个数
    shnum = pelf->ehdr->e_shnum;
    for(i = 0 ;i < shnum; i++) 
    {
        if(SHT_SYMTAB == pelf->shdr[i].sh_type)
        {
            pelf->symtab = (Elf_Sym *)(pelf->base + pelf->shdr[i].sh_offset);         
            pelf->symnum = pelf->shdr[i].sh_size / (pelf->shdr[i].sh_entsize);
        }
        if(SHT_STRTAB == pelf->shdr[i].sh_type)
        {    
            if(!strcmp(pelf->shstrtab + pelf->shdr[i].sh_name,".strtab"))
            {
                pelf->strtab = (char*)(pelf->base+pelf->shdr[i].sh_offset);
            }
            else if(!strcmp(pelf->shstrtab + pelf->shdr[i].sh_name,".dynstr"))
            {
                pelf->dstrtab = (char*)(pelf->base+pelf->shdr[i].sh_offset);
            }    
        }  
        if(SHT_DYNSYM == pelf->shdr[i].sh_type)
        {
            pelf->dsymtab = (Elf_Sym *)(pelf->base + pelf->shdr[i].sh_offset);
            pelf->dsymnum = pelf->shdr[i].sh_size / (pelf->shdr[i].sh_entsize);
        } 
        if(SHT_DYNAMIC == pelf->shdr[i].sh_type) 
        {
            pelf->dynamic = (Elf_Dyn *)(pelf->base + pelf->shdr[i].sh_offset);
            pelf->dynamicnum = pelf->shdr[i].sh_size / (pelf->shdr[i].sh_entsize);
        }  
    }

}

int main(int argc,char *argv[])
{
    struct stat sta;
    ObjElf elf={0}; 
    int type;
    if(argc <= 1)
    {
        show_arg_help();
        return -1;
    } 
    type = parse_args(argc,argv,elf.filename);
    if(type == SHOW_MAX)
    {
        return -1;
    } 
    elf.optype = type;
    if(elf.filename[0] == '\0')
    {
        show_arg_help();
        return -1;
    }    
    if(stat(elf.filename,&sta) < 0)
    {
        printf("error\n");
        return -1;
    }
    elf.filesize = sta.st_size;

    elf.fd  = open(elf.filename,O_RDWR);   
    if(elf.fd < 0)
    {
        printf("open file %s error\n",elf.filename);
        return -1;
    }
    
    elf.base = mmap(NULL,elf.filesize,PROT_READ|PROT_WRITE,MAP_PRIVATE,elf.fd,0);
    if(NULL == elf.base)
    {
        printf("fail to map file %s\n",elf.filename);
        goto out;
    }
    if(!(0x7f == elf.base[0] && !strncmp("ELF",&elf.base[1],3)))
    {
        printf("Elf format is error\n");
        return -1; 
    }
        
    set_stelf_value(&elf);

    run_opcode(type,&elf); 
      
out:
   if(NULL != elf.base)
   {
       munmap(elf.base,elf.filesize); 
   }

   if(elf.fd > 0)
      close(elf.fd); 
   
    return 0;
}

 

elf.h

#ifndef __YLD_ELF_H
#define __YLD_ELF_H

#define SHF_MERGE	(1 << 4)	/* Data in this section can be merged */
#define SHF_STRINGS	(1 << 5)	/* Contains null terminated character strings */
#define SHF_INFO_LINK	(1 << 6)	/* sh_info holds section header table index */
#define SHF_LINK_ORDER	(1 << 7)	/* Preserve section ordering when linking */
#define SHF_OS_NONCONFORMING (1 << 8)	/* OS specific processing required */
#define SHF_GROUP	(1 << 9)	/* Member of a section group */
#define SHF_TLS		(1 << 10)	/* Thread local storage section */


#define STT_RELC	8		/* Complex relocation expression */
#define STT_SRELC	9		/* Signed Complex relocation expression */
#define STT_LOOS	10		/* OS-specific semantics */
#define STT_GNU_IFUNC	10		/* Symbol is an indirect code object */
#define STT_HIOS	12		/* OS-specific semantics */
#define STT_LOPROC	13		/* Processor-specific semantics */
#define STT_HIPROC	15		/* Processor-specific semantics */

#define STB_LOOS	10		/* OS-specific semantics */
#define STB_GNU_UNIQUE	10		/* Symbol is unique in namespace */
#define STB_HIOS	12		/* OS-specific semantics */
#define STB_LOPROC	13		/* Processor-specific semantics */
#define STB_HIPROC	15		/* Processor-specific semantics */

#define ELF_ST_BIND ELF64_ST_BIND
#define ELF_ST_TYPE ELF64_ST_TYPE

#define ELF_R_SYM  ELF64_R_SYM
#define ELF_R_TYPE ELF64_R_TYPE
typedef Elf64_Ehdr  Elf_Ehdr;
typedef Elf64_Phdr  Elf_Phdr;
typedef Elf64_Shdr  Elf_Shdr;
typedef Elf64_Sym   Elf_Sym;
typedef Elf64_Dyn   Elf_Dyn;
typedef Elf64_Rel   Elf_Rel;
typedef Elf64_Rela  Elf_Rela;

typedef enum op_type{
        SHOW_EHDR = 0,
        SHOW_PHDR,
        SHOW_SHDR,    
        SHOW_SYMTAB,   
        SHOW_DSYMTAB,   
        SHOW_DYNAMIC,
        SHOW_RELTAB,
        SHOW_MAX
}OpType;

typedef struct obj_elf
{
    off_t filesize;
    int  fd;
    int symnum;
    int dsymnum;
    int dynamicnum;
    char *base;
    char filename[256];
    int  optype;
    char *shstrtab;
    char *strtab;
    char *dstrtab;
    Elf_Ehdr *ehdr;
    Elf_Phdr *phdr;
    Elf_Shdr *shdr;
    Elf_Sym  *symtab;
    Elf_Sym  *dsymtab;
    Elf_Dyn  *dynamic;
}ObjElf;



#endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值