zoukankan      html  css  js  c++  java
  • readelf源码学习

    导入 /usr/include/elf.h

    main.cpp

    #include <iostream>
    #include <cstring>
    #include "elf.h"
    #include "stdio.h"
    #include "ELF_process.h"
    
    
    #define file_name "libhello-jni.so"
    #define SARMAG 8
    
    int
    main() {
    
        FILE *file = fopen(file_name,"rb");
        char armag[SARMAG];
    
        printf("Input file '%s'.
    ", file_name);
        if (file == NULL)
        {
            printf("Input file '%s' is not readable.
    ", file_name);
            return 0;
        }
    
        if (fread (armag, SARMAG, 1, file) != 1)
        {
            printf("%s: Failed to read file's magic number
    ", file_name);
            fclose (file);
            return 0;
        }
    
        rewind(file);
        ELF_process *pro;
        pro->Process_object(file);
        fclose (file);
        delete(pro);
    
        return 0;
    }

    ELF_process.h

    #include <iostream>
    
    
    
    
    
    /* ELF Header (32-bit implementations) */
    
    typedef struct {
        unsigned char    e_ident[16];        /* ELF "magic number" */
        unsigned char    e_type[2];        /* Identifies object file type */
        unsigned char    e_machine[2];        /* Specifies required architecture */
        unsigned char    e_version[4];        /* Identifies object file version */
        unsigned char    e_entry[4];        /* Entry point virtual address */
        unsigned char    e_phoff[4];        /* Program header table file offset */
        unsigned char    e_shoff[4];        /* Section header table file offset */
        unsigned char    e_flags[4];        /* Processor-specific flags */
        unsigned char    e_ehsize[2];        /* ELF header size in bytes */
        unsigned char    e_phentsize[2];        /* Program header table entry size */
        unsigned char    e_phnum[2];        /* Program header table entry count */
        unsigned char    e_shentsize[2];        /* Section header table entry size */
        unsigned char    e_shnum[2];        /* Section header table entry count */
        unsigned char    e_shstrndx[2];        /* Section header string table index */
    } Elf32_External_Ehdr;
    
    typedef struct {
        unsigned char    e_ident[16];        /* ELF "magic number" */
        unsigned char    e_type[2];        /* Identifies object file type */
        unsigned char    e_machine[2];        /* Specifies required architecture */
        unsigned char    e_version[4];        /* Identifies object file version */
        unsigned char    e_entry[8];        /* Entry point virtual address */
        unsigned char    e_phoff[8];        /* Program header table file offset */
        unsigned char    e_shoff[8];        /* Section header table file offset */
        unsigned char    e_flags[4];        /* Processor-specific flags */
        unsigned char    e_ehsize[2];        /* ELF header size in bytes */
        unsigned char    e_phentsize[2];        /* Program header table entry size */
        unsigned char    e_phnum[2];        /* Program header table entry count */
        unsigned char    e_shentsize[2];        /* Section header table entry size */
        unsigned char    e_shnum[2];        /* Section header table entry count */
        unsigned char    e_shstrndx[2];        /* Section header string table index */
    } Elf64_External_Ehdr;
    
    /* Section header */
    
    typedef struct {
        unsigned char    sh_name[4];        /* Section name, index in string tbl */
        unsigned char    sh_type[4];        /* Type of section */
        unsigned char    sh_flags[4];        /* Miscellaneous section attributes */
        unsigned char    sh_addr[4];        /* Section virtual addr at execution */
        unsigned char    sh_offset[4];        /* Section file offset */
        unsigned char    sh_size[4];        /* Size of section in bytes */
        unsigned char    sh_link[4];        /* Index of another section */
        unsigned char    sh_info[4];        /* Additional section information */
        unsigned char    sh_addralign[4];    /* Section alignment */
        unsigned char    sh_entsize[4];        /* Entry size if section holds table */
    } Elf32_External_Shdr;
    
    typedef struct {
        unsigned char    sh_name[4];        /* Section name, index in string tbl */
        unsigned char    sh_type[4];        /* Type of section */
        unsigned char    sh_flags[8];        /* Miscellaneous section attributes */
        unsigned char    sh_addr[8];        /* Section virtual addr at execution */
        unsigned char    sh_offset[8];        /* Section file offset */
        unsigned char    sh_size[8];        /* Size of section in bytes */
        unsigned char    sh_link[4];        /* Index of another section */
        unsigned char    sh_info[4];        /* Additional section information */
        unsigned char    sh_addralign[8];    /* Section alignment */
        unsigned char    sh_entsize[8];        /* Entry size if section holds table */
    } Elf64_External_Shdr;
    
    /* Program header */
    
    typedef struct {
        unsigned char    p_type[4];        /* Identifies program segment type */
        unsigned char    p_offset[4];        /* Segment file offset */
        unsigned char    p_vaddr[4];        /* Segment virtual address */
        unsigned char    p_paddr[4];        /* Segment physical address */
        unsigned char    p_filesz[4];        /* Segment size in file */
        unsigned char    p_memsz[4];        /* Segment size in memory */
        unsigned char    p_flags[4];        /* Segment flags */
        unsigned char    p_align[4];        /* Segment alignment, file & memory */
    } Elf32_External_Phdr;
    
    typedef struct {
        unsigned char    p_type[4];        /* Identifies program segment type */
        unsigned char    p_flags[4];        /* Segment flags */
        unsigned char    p_offset[8];        /* Segment file offset */
        unsigned char    p_vaddr[8];        /* Segment virtual address */
        unsigned char    p_paddr[8];        /* Segment physical address */
        unsigned char    p_filesz[8];        /* Segment size in file */
        unsigned char    p_memsz[8];        /* Segment size in memory */
        unsigned char    p_align[8];        /* Segment alignment, file & memory */
    } Elf64_External_Phdr;
    
    
    
    
    
    /* dynamic section structure */
    
    typedef struct {
        unsigned char    d_tag[4];        /* entry tag value */
        union {
            unsigned char    d_val[4];
            unsigned char    d_ptr[4];
        } d_un;
    } Elf32_External_Dyn;
    
    typedef struct {
        unsigned char    d_tag[8];        /* entry tag value */
        union {
            unsigned char    d_val[8];
            unsigned char    d_ptr[8];
        } d_un;
    } Elf64_External_Dyn;
    
    
    
    /* Relocation Entries */
    typedef struct {
        unsigned char r_offset[4];    /* Location at which to apply the action */
        unsigned char    r_info[4];    /* index and type of relocation */
    } Elf32_External_Rel;
    
    typedef struct {
        unsigned char r_offset[4];    /* Location at which to apply the action */
        unsigned char    r_info[4];    /* index and type of relocation */
        unsigned char    r_addend[4];    /* Constant addend used to compute value */
    } Elf32_External_Rela;
    
    typedef struct {
        unsigned char r_offset[8];    /* Location at which to apply the action */
        unsigned char    r_info[8];    /* index and type of relocation */
    } Elf64_External_Rel;
    
    typedef struct {
        unsigned char r_offset[8];    /* Location at which to apply the action */
        unsigned char    r_info[8];    /* index and type of relocation */
        unsigned char    r_addend[8];    /* Constant addend used to compute value */
    } Elf64_External_Rela;
    
    
    
    
    
    /* Symbol table entry */
    
    typedef struct {
        unsigned char    st_name[4];        /* Symbol name, index in string tbl */
        unsigned char    st_value[4];        /* Value of the symbol */
        unsigned char    st_size[4];        /* Associated symbol size */
        unsigned char    st_info[1];        /* Type and binding attributes */
        unsigned char    st_other[1];        /* No defined meaning, 0 */
        unsigned char    st_shndx[2];        /* Associated section index */
    } Elf32_External_Sym;
    
    typedef struct {
        unsigned char    st_name[4];        /* Symbol name, index in string tbl */
        unsigned char    st_info[1];        /* Type and binding attributes */
        unsigned char    st_other[1];        /* No defined meaning, 0 */
        unsigned char    st_shndx[2];        /* Associated section index */
        unsigned char    st_value[8];        /* Value of the symbol */
        unsigned char    st_size[8];        /* Associated symbol size */
    } Elf64_External_Sym;
    
    
    
    
    class ELF_process {
    
        ELF_process();
        void* get_data(void * var, FILE * file, long offset, size_t size, size_t nmemb,
                       const char * reason);
        void *cmalloc (size_t nmemb, size_t size);
        int  get_32bit_section_headers (FILE * file, unsigned int num);
        int  get_file_header(FILE *file);
    
        int  process_file_header();
        const char*  get_elf_class (unsigned int elf_class);
        const char * get_data_encoding (unsigned int encoding);
        const char * get_osabi_name (unsigned int osabi);
        const char *get_file_type (unsigned e_type);
        const char *get_machine_name (unsigned e_machine);
    
        int   process_section_headers (FILE * file);
        const char *get_section_type_name (unsigned int sh_type);
        const char *get_mips_section_type_name (unsigned int sh_type);
        const char *get_parisc_section_type_name (unsigned int sh_type);
        const char *get_ia64_section_type_name (unsigned int sh_type);
        const char *get_x86_64_section_type_name (unsigned int sh_type);
        const char *get_aarch64_section_type_name (unsigned int sh_type);
        const char *get_arm_section_type_name (unsigned int sh_type);
        const char *get_tic6x_section_type_name (unsigned int sh_type);
        const char *get_msp430x_section_type_name (unsigned int sh_type);
    
    
    
        int  process_program_headers (FILE * file);
        const char *get_segment_type (unsigned int p_type);
        const char *get_aarch64_segment_type (unsigned long type);
        const char *get_arm_segment_type (unsigned long type);
        const char *get_mips_segment_type (unsigned long type);
        const char *get_parisc_segment_type (unsigned long type);
        const char *get_ia64_segment_type (unsigned long type);
        const char *get_tic6x_segment_type (unsigned long type);
        int get_program_headers (FILE * file);
        int get_32bit_program_headers (FILE * file, Elf32_Phdr * pheaders);
        int get_64bit_program_headers (FILE * file, Elf64_Phdr * pheaders);
    
    
    
        int process_dynamic_section (FILE * file);
        int get_32bit_dynamic_section (FILE * file);
        int get_64bit_dynamic_section(FILE * file);
    
    
        void print_dynamic_flags (Elf32_Word flags);
        const char *get_dynamic_type (unsigned long type);
    
        int process_relocs (FILE * file);
    
        void get_32bit_rel(FILE *pFILE, unsigned int offset);
    public:
        int  Process_object(FILE *file);
    
    
        void process_symbol_table(FILE *pFILE);
    
        void get_32bit_symbol(FILE *pFILE);
    
    
        void get_32bit_strdyn(FILE *pFILE, Elf32_Word name);
    };

    ELF_process.cpp

    #include <elf.h>
    #include <cstring>
    #include "ELF_process.h"
    #define file_name "/home/hx/cProgram/Process/libhello-jni.so"
    #define BYTE_GET(field)  byte_get_little_endian (field,sizeof(field))
    static int is_32bit_elf;
    Elf32_Ehdr  elf_header;
    Elf32_Shdr* section_headers;
    Elf32_Phdr* program_headers;
    Elf32_Sym*  sym_dyn;
    
    static unsigned int dynamic_addr;
    static unsigned int dynamic_offset;
    unsigned int dynamic_strings;
    unsigned int dynamic_size;
    static unsigned int rel_nent;
    static unsigned int rel_dyn_offset;
    static unsigned int rel_dyn_size;
    static unsigned int sym_dyn_offset;
    static unsigned int sym_dyn_size;
    static unsigned int str_dyn_offset;
    static unsigned int str_dyn_size;
    unsigned int sym_nent;
    Elf32_Dyn* dynamic_section;
    
    
    static unsigned int dynamic_nent;
    
    #define SHT_PARISC_ANNOT    0x70000003
    #define SHT_PARISC_SYMEXTN    SHT_LOPROC + 8
    #define SHT_PARISC_STUBS      SHT_LOPROC + 9
    #define SHT_PARISC_DLKM        0x70000004
    
    #define PT_PARISC_WEAKORDER    0x70000002
    #define PT_HP_CORE_UTSNAME    (PT_LOOS + 0x15)
    
    #define SHT_IA_64_PRIORITY_INIT (SHT_LOPROC + 0x9000000)
    #define SHT_IA_64_VMS_TRACE             0x60000000
    #define SHT_IA_64_VMS_TIE_SIGNATURES    0x60000001
    #define SHT_IA_64_VMS_DEBUG             0x60000002
    #define SHT_IA_64_VMS_DEBUG_STR         0x60000003
    #define SHT_IA_64_VMS_LINKAGES          0x60000004
    #define SHT_IA_64_VMS_SYMBOL_VECTOR     0x60000005
    #define SHT_IA_64_VMS_FIXUP             0x60000006
    #define SHT_IA_64_LOPSREG    (SHT_LOPROC + 0x8000000)
    
    
    
    #define EM_L1OM        180    /* Intel L1OM */
    #define EM_K1OM        181    /* Intel K1OM */
    #define EM_TI_C6000    140    /* Texas Instruments TMS320C6000 DSP family */
    #define EM_MSP430    105    /* TI msp430 micro controller */
    
    
    #define SHT_ARM_DEBUGOVERLAY   0x70000004    /* Section holds overlay debug info.  */
    #define SHT_ARM_OVERLAYSECTION 0x70000005    /* Section holds GDB and overlay integration info.  */
    
    #define SHT_X86_64_UNWIND    0x70000001    /* unwind information */
    
    
    #define SHT_AARCH64_ATTRIBUTES    0x70000003  /* Section holds attributes.  */
    
    #define SHT_C6000_UNWIND    0x70000001
    #define SHT_C6000_PREEMPTMAP    0x70000002
    #define SHT_C6000_ATTRIBUTES    0x70000003
    #define SHT_TI_ICODE        0x7F000000
    #define SHT_TI_XREF        0x7F000001
    #define SHT_TI_HANDLER        0x7F000002
    #define SHT_TI_INITINFO        0x7F000003
    #define SHT_TI_PHATTRS        0x7F000004
    
    
    #define SHT_MSP430_ATTRIBUTES    0x70000003    /* Section holds ABI attributes.  */
    #define SHT_MSP430_SEC_FLAGS    0x7f000005    /* Holds TI compiler's section flags.  */
    #define SHT_MSP430_SYM_ALIASES    0x7f000006    /* Holds TI compiler's symbol aliases.  */
    
    
    
    #define PT_AARCH64_ARCHEXT    (PT_LOPROC + 0)
    
    
    int byte_get_little_endian (unsigned char *field, int size){
    
        switch (size){
            case 1:
                return *field;
            case 2:
                return ((unsigned int)(field[0]))
                    | (((unsigned int)(field[1])) << 8);
            case 3:
                return  ((unsigned long) (field[0]))
                        |    (((unsigned long) (field[1])) << 8)
                        |    (((unsigned long) (field[2])) << 16);
    
            case 4:
                return  ((unsigned long) (field[0]))
                        |    (((unsigned long) (field[1])) << 8)
                        |    (((unsigned long) (field[2])) << 16)
                        |    (((unsigned long) (field[3])) << 24);
        }
    
    }
    
    ELF_process::ELF_process() {
    
    }
    
    int ELF_process::Process_object(FILE *file) {
    
    
        if (!get_file_header(file)){
            printf("gei file header Failed");
            return 0;
        }
    
    
        /********* start     process ***********/
        if (!process_file_header()){
            return 0;
        }
    
    
        if(!process_section_headers(file)){
            return 0;
        }
    
        if(!process_program_headers(file)){
    
            process_dynamic_section(file);
        }
    
        process_relocs(file);
        process_symbol_table(file);
    
    
    
    
    }
    
    int ELF_process::get_file_header(FILE *file) {
    
        /* Read in the identity array.  */
        if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
            return 0;
    
        /* For now we only support 32 bit and 64 bit ELF files.  */
        is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
    
        /* Read in the rest of the header.  */
        if (is_32bit_elf){
    
            Elf32_External_Ehdr ehdr32;
            if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
                return 0;
    
            elf_header.e_type      = BYTE_GET (ehdr32.e_type);
            elf_header.e_machine   = BYTE_GET (ehdr32.e_machine);
            elf_header.e_version   = BYTE_GET (ehdr32.e_version);
            elf_header.e_entry     = BYTE_GET (ehdr32.e_entry);
            elf_header.e_phoff     = BYTE_GET (ehdr32.e_phoff);
            elf_header.e_shoff     = BYTE_GET (ehdr32.e_shoff);
            elf_header.e_flags     = BYTE_GET (ehdr32.e_flags);
            elf_header.e_ehsize    = BYTE_GET (ehdr32.e_ehsize);
            elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
            elf_header.e_phnum     = BYTE_GET (ehdr32.e_phnum);
            elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
            elf_header.e_shnum     = BYTE_GET (ehdr32.e_shnum);
            elf_header.e_shstrndx  = BYTE_GET (ehdr32.e_shstrndx);
    
            if (elf_header.e_shoff){
                if (is_32bit_elf)
                    get_32bit_section_headers(file,1);
                else
                {
                    //64位 ...
                }
            }
    
        }
        return 1;
    }
    
    int ELF_process::get_32bit_section_headers(FILE *file, unsigned int num) {
    
        Elf32_External_Shdr * shdrs;
        Elf32_Shdr* internal;
    
        shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
                                                  elf_header.e_shentsize, num,
                                                  ("section headers"));
        if (!shdrs)
            return 0;
    
        section_headers = (Elf32_Shdr *) cmalloc (num,sizeof (Elf32_Shdr));
    
        if (section_headers == NULL)
        {
            printf("Out of memory
    ");
            return 0;
        }
    
        internal = section_headers;
    
        for (int i = 0;i < num;i++, internal++)
        {
            internal->sh_name      = BYTE_GET (shdrs[i].sh_name);
            internal->sh_type      = BYTE_GET (shdrs[i].sh_type);
            internal->sh_flags     = BYTE_GET (shdrs[i].sh_flags);
            internal->sh_addr      = BYTE_GET (shdrs[i].sh_addr);
            internal->sh_offset    = BYTE_GET (shdrs[i].sh_offset);
            internal->sh_size      = BYTE_GET (shdrs[i].sh_size);
            internal->sh_link      = BYTE_GET (shdrs[i].sh_link);
            internal->sh_info      = BYTE_GET (shdrs[i].sh_info);
            internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
            internal->sh_entsize   = BYTE_GET (shdrs[i].sh_entsize);
        }
    
        free (shdrs);
    
        return 1;
    }
    
    void *
    ELF_process::get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,const char * reason)
    {
        void * mvar;
    
        if (size == 0 || nmemb == 0)
            return NULL;
    
        if (fseek (file, offset, SEEK_SET))
        {
            //error (_("Unable to seek to 0x%lx for %s
    "),
                 //  (unsigned long) archive_file_offset + offset, reason);
            return NULL;
        }
    
        mvar = var;
        if (mvar == NULL)
        {
            /* Check for overflow.  */
            if (nmemb < (~(size_t) 0 - 1) / size)
                /* + 1 so that we can '' terminate invalid string table sections.  */
                mvar = malloc (size * nmemb + 1);
    
            if (mvar == NULL)
            {
                //error (_("Out of memory allocating 0x%lx bytes for %s
    "),
                       //(unsigned long)(size * nmemb), reason);
                return NULL;
            }
    
            ((char *) mvar)[size * nmemb] = '';
        }
    
        if (fread (mvar, size, nmemb, file) != nmemb)
        {
            //error (_("Unable to read in 0x%lx bytes of %s
    "),
                  // (unsigned long)(size * nmemb), reason);
            if (mvar != var)
                free (mvar);
            return NULL;
        }
    
        return mvar;
    }
    void *ELF_process::cmalloc (size_t nmemb, size_t size)
    {
        /* Check for overflow.  */
        if (nmemb >= ~(size_t) 0 / size)
            return NULL;
        else
            return malloc (nmemb * size);
    }
    
    int ELF_process::process_file_header(void) {
    
        if (   elf_header.e_ident[EI_MAG0] != ELFMAG0
               || elf_header.e_ident[EI_MAG1] != ELFMAG1
               || elf_header.e_ident[EI_MAG2] != ELFMAG2
               || elf_header.e_ident[EI_MAG3] != ELFMAG3)
        {
            printf("Not an ELF file - it has the wrong magic bytes at the start
    ");
            return 0;
        }
    
        printf("ELF Header:
    ");
        printf("  Magic:     ");
        for (int i = 0; i <EI_NIDENT ; ++i)
            printf ("%2.2x ", elf_header.e_ident[i]);
            printf("
    ");
            printf("  Class:                             %s
    ",
                    get_elf_class(elf_header.e_ident[EI_CLASS]));
    
            printf ("  Data:                              %s
    ",
                    get_data_encoding (elf_header.e_ident[EI_DATA]));
            printf ("  Version:                           %d %s
    ",
                    elf_header.e_ident[EI_VERSION],
                    (elf_header.e_ident[EI_VERSION] == EV_CURRENT
                     ? "(current)"
                     : (elf_header.e_ident[EI_VERSION] != EV_NONE
                        ? ("<unknown: %lx>")
                        : "")));
        printf ("  OS/ABI:                            %s
    ",
                get_osabi_name (elf_header.e_ident[EI_OSABI]));
    
        printf ("  ABI Version:                       %d
    ",
                elf_header.e_ident[EI_ABIVERSION]);
    
        printf ("  Type:                              %s
    ",
                get_file_type (elf_header.e_type));
    
        printf ("  Machine:                           %s
    ",
                get_machine_name (elf_header.e_machine));
    
        printf ("  Version:                           0x%lx
    ",
                (unsigned long) elf_header.e_version);
    
        printf ("  Entry point address:               0x%x",elf_header.e_entry);
    
        printf ("
      Start of program headers:          %d",elf_header.e_phoff);
    
        printf (" (bytes into file)
      Start of section headers:          %d",elf_header.e_shoff);
        printf (" (bytes into file)
    ");
    
        printf ("  Flags:                             0x%lx
    ",(unsigned  long)elf_header.e_flags);
    
        printf ("  Size of this header:               %ld (bytes)
    ",(long)elf_header.e_ehsize);
    
        printf ("  Size of program headers:           %ld (bytes)
    ",(long)elf_header.e_phentsize);
    
        printf ("  Number of program headers:         %ld
    ",(long)elf_header.e_phnum);
    
        if (section_headers != NULL
            && elf_header.e_phnum == PN_XNUM
            && section_headers[0].sh_info != 0)
        printf (" (%ld)", (long) section_headers[0].sh_info);
    
        printf ("  Size of section headers:           %ld (bytes)
    ",
                (long) elf_header.e_shentsize);
    
        printf ("  Number of section headers:         %ld
    ",
                (long) elf_header.e_shnum);
    
        if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
            printf (" (%ld)", (long) section_headers[0].sh_size);
    
        printf ("  Section header string table index: %ld
    ",
                (long) elf_header.e_shstrndx);
    
        if (section_headers != NULL
            && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
            printf (" (%u)", section_headers[0].sh_link);
        else if (elf_header.e_shstrndx != SHN_UNDEF
                 && elf_header.e_shstrndx >= elf_header.e_shnum)
            printf (" <corrupt: out of range>");
    
    
    
    
    
        return 1;
    
    }
    
    
    const char *
    ELF_process::get_elf_class (unsigned int elf_class)
    {
        static char buff[32];
    
        switch (elf_class)
        {
            case ELFCLASSNONE: return ("none");
            case ELFCLASS32:   return "ELF32";
            case ELFCLASS64:   return "ELF64";
            default:
                snprintf (buff, sizeof (buff), ("<unknown: %x>"), elf_class);
                return buff;
        }
    }
    const char *
    ELF_process::get_data_encoding (unsigned int encoding)
    {
        static char buff[32];
    
        switch (encoding)
        {
            case ELFDATANONE: return ("none");
            case ELFDATA2LSB: return ("2's complement, little endian");
            case ELFDATA2MSB: return ("2's complement, big endian");
            default:
                snprintf (buff, sizeof (buff), ("<unknown: %x>"), encoding);
                return buff;
        }
    }
    const char *
    ELF_process::get_osabi_name (unsigned int osabi){
    
        static    char buff[32];
        switch (osabi){
         case  ELFOSABI_NONE:        return "UNIX System V ABI";
         case  ELFOSABI_HPUX:        return "HP-UX";
         case  ELFOSABI_NETBSD:      return "NetBSD";
         case  ELFOSABI_GNU:         return "Object uses GNU ELF extensions";
         case  ELFOSABI_SOLARIS:     return "Sun Solaris";
         case  ELFOSABI_AIX:         return "IBM AIX";
         case  ELFOSABI_IRIX:        return "SGI Irix";
         case  ELFOSABI_FREEBSD:     return "FreeBSD";
         case  ELFOSABI_TRU64:       return "Compaq TRU64 UNIX";
         case  ELFOSABI_MODESTO:     return "Novell Modesto";
         case  ELFOSABI_OPENBSD:     return "OpenBSD";
         case  ELFOSABI_ARM_AEABI:   return "ARM EABI";
         case  ELFOSABI_ARM:         return "ARM";
         case  ELFOSABI_STANDALONE:  return "Standalone (embedded) application";
            default:
                break;
        }
    
        snprintf (buff, sizeof (buff), ("<unknown: %x>"), osabi);
        return buff;
    }
    
    const char *ELF_process::get_file_type(unsigned e_type) {
    
        static char buff[32];
    
        switch (e_type) {
            case ET_NONE:
                return "NONE (None)";
            case ET_REL:
                return "REL (Relocatable file)";
            case ET_EXEC:
                return "EXEC (Executable file)";
            case ET_DYN:
                return "DYN (Shared object file)";
            case ET_CORE:
                return "CORE (Core file)";
    
            default:
                if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
                    snprintf(buff, sizeof(buff), ("Processor Specific: (%x)"), e_type);
                else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
                    snprintf(buff, sizeof(buff), ("OS Specific: (%x)"), e_type);
                else
                    snprintf(buff, sizeof(buff), ("<unknown>: %x"), e_type);
                return buff;
    
        }
    }
    
    const char *ELF_process::get_machine_name(unsigned e_machine) {
    
        static    char buff[64];
    
        switch (e_machine){
            case EM_NONE:        return ("None");
            case EM_AARCH64:    return "AArch64";
            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_S370:        return "IBM System/370";
            case EM_MIPS_RS3_LE:    return "MIPS R4000 big-endian";
            case EM_PARISC:        return "HPPA";
            case EM_SPARC32PLUS:    return "Sparc v8+" ;
            case EM_960:        return "Intel 90860";
            case EM_PPC:        return "PowerPC";
            case EM_PPC64:        return "PowerPC64";
            case EM_FR20:        return "Fujitsu FR20";
            case EM_RH32:        return "TRW RH32";
            case EM_ARM:        return "ARM";
            case EM_SH:            return "Renesas / SuperH SH";
            case EM_SPARCV9:        return "Sparc v9";
            case EM_TRICORE:        return "Siemens Tricore";
            case EM_ARC:        return "ARC";
            case EM_H8_300:        return "Renesas H8/300";
            case EM_H8_300H:        return "Renesas H8/300H";
            case EM_H8S:        return "Renesas H8S";
            case EM_H8_500:        return "Renesas H8/500";
            case EM_IA_64:        return "Intel IA-64";
            case EM_MIPS_X:        return "Stanford MIPS-X";
            case EM_COLDFIRE:        return "Motorola Coldfire";
            case EM_ALPHA:        return "Alpha";
            case EM_D10V:        return "d10v";
            case EM_D30V:        return "d30v";
            case EM_M32R:        return "Renesas M32R (formerly Mitsubishi M32r)";
            case EM_V800:        return "Renesas V850 (using RH850 ABI)";
            case EM_V850:        return "Renesas V850";
            case EM_MN10300:        return "mn10300";
            case EM_MN10200:        return "mn10200";
            case EM_FR30:        return "Fujitsu FR30";
            case EM_PJ:            return "picoJava";
            case EM_MMA:        return "Fujitsu Multimedia Accelerator";
            case EM_PCP:        return "Siemens PCP";
            case EM_NCPU:        return "Sony nCPU embedded RISC processor";
            case EM_NDR1:        return "Denso NDR1 microprocesspr";
            case EM_STARCORE:        return "Motorola Star*Core processor";
            case EM_ME16:        return "Toyota ME16 processor";
            case EM_ST100:        return "STMicroelectronics ST100 processor";
            case EM_TINYJ:        return "Advanced Logic Corp. TinyJ embedded processor";
            case EM_PDSP:        return "Sony DSP processor";
            case EM_FX66:        return "Siemens FX66 microcontroller";
            case EM_ST9PLUS:        return "STMicroelectronics ST9+ 8/16 bit microcontroller";
            case EM_ST7:        return "STMicroelectronics ST7 8-bit microcontroller";
            case EM_68HC16:        return "Motorola MC68HC16 Microcontroller";
            case EM_68HC12:        return "Motorola MC68HC12 Microcontroller";
            case EM_68HC11:        return "Motorola MC68HC11 Microcontroller";
            case EM_68HC08:        return "Motorola MC68HC08 Microcontroller";
            case EM_68HC05:        return "Motorola MC68HC05 Microcontroller";
            case EM_SVX:        return "Silicon Graphics SVx";
            case EM_ST19:        return "STMicroelectronics ST19 8-bit microcontroller";
            case EM_VAX:        return "Digital VAX";
            case EM_AVR:        return "Atmel AVR 8-bit microcontroller";
            case EM_CRIS:        return "Axis Communications 32-bit embedded processor";
            case EM_JAVELIN:        return "Infineon Technologies 32-bit embedded cpu";
            case EM_FIREPATH:        return "Element 14 64-bit DSP processor";
            case EM_ZSP:        return "LSI Logic's 16-bit DSP processor";
            case EM_MMIX:        return "Donald Knuth's educational 64-bit processor";
            case EM_HUANY:        return "Harvard Universitys's machine-independent object format";
            case EM_PRISM:        return "Vitesse Prism";
            case EM_X86_64:        return "Advanced Micro Devices X86-64";
            case EM_S390:        return "IBM S/390";
            case EM_OPENRISC:
            case EM_ARC_A5:        return "ARC International ARCompact processor";
            case EM_XTENSA:        return "Tensilica Xtensa Processor";
            case EM_MICROBLAZE:
            case EM_TILEPRO:        return "Tilera TILEPro multicore architecture family";
            case EM_TILEGX:        return "Tilera TILE-Gx multicore architecture family";
            default:
                snprintf (buff, sizeof (buff), ("<unknown>: 0x%x"), e_machine);
        }
    
        return buff;
    
    
    }
    
    int ELF_process::process_section_headers(FILE *file) {
    
        Elf32_Shdr * section;
        section = NULL;
        char * string_table;
    
    
        unsigned int  flag_shoff;
    
        if (elf_header.e_shnum == 0){
            if (elf_header.e_shoff!=0)
                printf("possibly corrupt ELF file header - it has a non-zero section header offset, but no section headers
    ");
            else
                printf ("
    There are no sections in this file.
    ");
            return 1;
        }
    
        printf ("  There are %d section headers, starting at offset 0x%lx:
    ",
                elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
    
        if (is_32bit_elf)
        {
            if (! get_32bit_section_headers (file, elf_header.e_shnum))
                return 0;
        }
    
        /* Read in the string table, so that we have names to display.  */
        if (elf_header.e_shstrndx != SHN_UNDEF
            && elf_header.e_shstrndx < elf_header.e_shnum)
        {
            section = section_headers + elf_header.e_shstrndx;
    
            flag_shoff = section->sh_offset;
    
        }
    
        if (elf_header.e_shnum > 1)
            printf ("
    Section Headers:
    ");
        else
            printf ("
    Section Header:
    ");
        section = section_headers;
    
    
        unsigned int countC;
        if (is_32bit_elf){
            printf("  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
    ");
            for (int i = 0;
                 i < elf_header.e_shnum;
                 i++, section++)
            {
                printf ("  [%2u] ", i);
    
                countC = flag_shoff + section->sh_name;
    
                fseek(file,countC,SEEK_SET);
                char string_name[20];
                fread(string_name,20,1,file);
    
                printf("%-16s ",string_name);
    
    
                printf ( " %-15.15s ",
                        get_section_type_name (section->sh_type));
    
                printf("%6.8lx",(unsigned long) section->sh_addr);
                printf ( " %6.6lx %6.6lx %2.2lx",
                             (unsigned long) section->sh_offset,
                             (unsigned long) section->sh_size,
                             (unsigned long) section->sh_entsize);
    
                if (section->sh_flags)
                    printf (" %2.2x ", section->sh_flags);
                else
                    printf("%4c",32);
    
                printf ("%2u ", section->sh_link);
                printf ("%3u %3lu", section->sh_info,
                        (unsigned long) section->sh_addralign);
    
                if (strcmp(string_name,".dynamic")==0)
                {
                    dynamic_addr   = section->sh_offset;
                    dynamic_size   = section->sh_size;
                }
    
                if (strcmp(string_name,".rel.dyn")==0){
                    rel_dyn_offset = section->sh_offset;
                    rel_dyn_size   = section->sh_size;
                }
    
                if(strcmp(string_name,".dynsym")==0){
                    sym_dyn_offset = section->sh_offset;
                    sym_dyn_size   = section->sh_size;
                }
    
                if(strcmp(string_name,".dynstr")==0){
                    str_dyn_offset = section->sh_offset;
                    str_dyn_size   = section->sh_size;
                }
    
    
    
                printf("
    ");
    
            }
    
    
        }
    
        return 1;
    }
    
    const char *ELF_process::get_section_type_name(unsigned int sh_type) {
    
    
        static char buff[32];
        switch (sh_type){
            case SHT_NULL:        return "NULL";
            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:
                if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC)){
    
    
                    const char * result;
    
                    switch (elf_header.e_machine){
    
                        case EM_MIPS:
                        case EM_MIPS_RS3_LE:
                            result = get_mips_section_type_name (sh_type);
                            break;
                        case EM_PARISC:
                            result = get_parisc_section_type_name (sh_type);
                            break;
                        case EM_IA_64:
                            result = get_ia64_section_type_name (sh_type);
                            break;
                        case EM_X86_64:
                        case EM_L1OM:
                        case EM_K1OM:
                            result = get_x86_64_section_type_name (sh_type);
                            break;
                        case EM_AARCH64:
                            result = get_aarch64_section_type_name (sh_type);
                            break;
                        case EM_ARM:
                            result = get_arm_section_type_name (sh_type);
                            break;
                        case EM_TI_C6000:
                            result = get_tic6x_section_type_name (sh_type);
                            break;
                        case EM_MSP430:
                            result = get_msp430x_section_type_name (sh_type);
                            break;
                        default:
                            result = NULL;
                            break;
    
                    }
                    if (result != NULL)
                        return result;
                    sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
                }
                else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
                {
                    const char * result;
    
                    switch (elf_header.e_machine)
                    {
                        case EM_IA_64:
                            result = get_ia64_section_type_name (sh_type);
                            break;
                        default:
                            result = NULL;
                            break;
                    }
    
                    if (result != NULL)
                        return result;
    
                    sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
                }
                else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
                    sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
                else
                    /* This message is probably going to be displayed in a 15
                       character wide field, so put the hex value first.  */
                    snprintf (buff, sizeof (buff), ("%08x: <unknown>"), sh_type);
    
                return buff;
        }
    }
    
    const char *ELF_process::get_mips_section_type_name(unsigned int sh_type) {
    
        switch (sh_type)
        {
            case SHT_MIPS_LIBLIST:     return "MIPS_LIBLIST";
            case SHT_MIPS_MSYM:         return "MIPS_MSYM";
            case SHT_MIPS_CONFLICT:     return "MIPS_CONFLICT";
            case SHT_MIPS_GPTAB:     return "MIPS_GPTAB";
            case SHT_MIPS_UCODE:     return "MIPS_UCODE";
            case SHT_MIPS_DEBUG:     return "MIPS_DEBUG";
            case SHT_MIPS_REGINFO:     return "MIPS_REGINFO";
            case SHT_MIPS_PACKAGE:     return "MIPS_PACKAGE";
            case SHT_MIPS_PACKSYM:     return "MIPS_PACKSYM";
            case SHT_MIPS_RELD:         return "MIPS_RELD";
            case SHT_MIPS_IFACE:     return "MIPS_IFACE";
            case SHT_MIPS_CONTENT:     return "MIPS_CONTENT";
            case SHT_MIPS_OPTIONS:     return "MIPS_OPTIONS";
            case SHT_MIPS_SHDR:         return "MIPS_SHDR";
            case SHT_MIPS_FDESC:     return "MIPS_FDESC";
            case SHT_MIPS_EXTSYM:     return "MIPS_EXTSYM";
            case SHT_MIPS_DENSE:     return "MIPS_DENSE";
            case SHT_MIPS_PDESC:     return "MIPS_PDESC";
            case SHT_MIPS_LOCSYM:     return "MIPS_LOCSYM";
            case SHT_MIPS_AUXSYM:     return "MIPS_AUXSYM";
            case SHT_MIPS_OPTSYM:     return "MIPS_OPTSYM";
            case SHT_MIPS_LOCSTR:     return "MIPS_LOCSTR";
            case SHT_MIPS_LINE:         return "MIPS_LINE";
            case SHT_MIPS_RFDESC:     return "MIPS_RFDESC";
            case SHT_MIPS_DELTASYM:     return "MIPS_DELTASYM";
            case SHT_MIPS_DELTAINST:     return "MIPS_DELTAINST";
            case SHT_MIPS_DELTACLASS:     return "MIPS_DELTACLASS";
            case SHT_MIPS_DWARF:     return "MIPS_DWARF";
            case SHT_MIPS_DELTADECL:     return "MIPS_DELTADECL";
            case SHT_MIPS_SYMBOL_LIB:     return "MIPS_SYMBOL_LIB";
            case SHT_MIPS_EVENTS:     return "MIPS_EVENTS";
            case SHT_MIPS_TRANSLATE:     return "MIPS_TRANSLATE";
            case SHT_MIPS_PIXIE:     return "MIPS_PIXIE";
            case SHT_MIPS_XLATE:     return "MIPS_XLATE";
            case SHT_MIPS_XLATE_DEBUG:     return "MIPS_XLATE_DEBUG";
            case SHT_MIPS_WHIRL:     return "MIPS_WHIRL";
            case SHT_MIPS_EH_REGION:     return "MIPS_EH_REGION";
            case SHT_MIPS_XLATE_OLD:     return "MIPS_XLATE_OLD";
            case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
            default:
                break;
        }
        return NULL;
    }
    
    const char *ELF_process::get_parisc_section_type_name(unsigned int sh_type) {
    
    
        switch (sh_type)
        {
            case SHT_PARISC_EXT:    return "PARISC_EXT";
            case SHT_PARISC_UNWIND:    return "PARISC_UNWIND";
            case SHT_PARISC_DOC:    return "PARISC_DOC";
            case SHT_PARISC_ANNOT:    return "PARISC_ANNOT";
            case SHT_PARISC_SYMEXTN:    return "PARISC_SYMEXTN";
            case SHT_PARISC_STUBS:    return "PARISC_STUBS";
            case SHT_PARISC_DLKM:    return "PARISC_DLKM";
            default:
                break;
        }
        return NULL;
    }
    
    const char *ELF_process::get_ia64_section_type_name(unsigned int sh_type) {
    
    
        /* If the top 8 bits are 0x78 the next 8 are the os/abi ID.  */
        if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
            return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
    
        switch (sh_type)
        {
            case SHT_IA_64_EXT:               return "IA_64_EXT";
            case SHT_IA_64_UNWIND:           return "IA_64_UNWIND";
            case SHT_IA_64_PRIORITY_INIT:      return "IA_64_PRIORITY_INIT";
            case SHT_IA_64_VMS_TRACE:          return "VMS_TRACE";
            case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
            case SHT_IA_64_VMS_DEBUG:          return "VMS_DEBUG";
            case SHT_IA_64_VMS_DEBUG_STR:      return "VMS_DEBUG_STR";
            case SHT_IA_64_VMS_LINKAGES:       return "VMS_LINKAGES";
            case SHT_IA_64_VMS_SYMBOL_VECTOR:  return "VMS_SYMBOL_VECTOR";
            case SHT_IA_64_VMS_FIXUP:          return "VMS_FIXUP";
            default:
                break;
        }
        return NULL;
    
    
    }
    
    const char *ELF_process::get_x86_64_section_type_name(unsigned int sh_type) {
    
    
        switch (sh_type)
        {
            case SHT_X86_64_UNWIND:    return "X86_64_UNWIND";
            default:
                break;
        }
        return NULL;
    
    }
    
    const char *ELF_process::get_aarch64_section_type_name(unsigned int sh_type) {
    
    
        switch (sh_type)
        {
            case SHT_AARCH64_ATTRIBUTES:
                return "AARCH64_ATTRIBUTES";
            default:
                break;
        }
        return NULL;
    
    
    
    }
    
    const char *ELF_process::get_arm_section_type_name(unsigned int sh_type) {
    
        switch (sh_type)
        {
            case SHT_ARM_EXIDX:           return "ARM_EXIDX";
            case SHT_ARM_PREEMPTMAP:      return "ARM_PREEMPTMAP";
            case SHT_ARM_ATTRIBUTES:      return "ARM_ATTRIBUTES";
            case SHT_ARM_DEBUGOVERLAY:    return "ARM_DEBUGOVERLAY";
            case SHT_ARM_OVERLAYSECTION:  return "ARM_OVERLAYSECTION";
            default:
                break;
        }
        return NULL;
    }
    
    const char *ELF_process::get_tic6x_section_type_name(unsigned int sh_type) {
    
        switch (sh_type)
        {
            case SHT_C6000_UNWIND:
                return "C6000_UNWIND";
            case SHT_C6000_PREEMPTMAP:
                return "C6000_PREEMPTMAP";
            case SHT_C6000_ATTRIBUTES:
                return "C6000_ATTRIBUTES";
            case SHT_TI_ICODE:
                return "TI_ICODE";
            case SHT_TI_XREF:
                return "TI_XREF";
            case SHT_TI_HANDLER:
                return "TI_HANDLER";
            case SHT_TI_INITINFO:
                return "TI_INITINFO";
            case SHT_TI_PHATTRS:
                return "TI_PHATTRS";
            default:
                break;
        }
        return NULL;
    
    
    }
    
    const char *ELF_process::get_msp430x_section_type_name(unsigned int sh_type) {
    
        switch (sh_type)
        {
            case SHT_MSP430_SEC_FLAGS:   return "MSP430_SEC_FLAGS";
            case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
            case SHT_MSP430_ATTRIBUTES:  return "MSP430_ATTRIBUTES";
            default: return NULL;
        }
    }
    
    
    
    
    
    const char *ELF_process::get_segment_type(unsigned int p_type) {
    
        static char buff[32];
    
        switch (p_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 "GNU_EH_FRAME";
            case PT_GNU_STACK:    return "GNU_STACK";
            case PT_GNU_RELRO:  return "GNU_RELRO";
    
            default:
                if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
                {
                    const char * result;
    
                    switch (elf_header.e_machine)
                    {
                        case EM_AARCH64:
                            result = get_aarch64_segment_type (p_type);
                            break;
                        case EM_ARM:
                            result = get_arm_segment_type (p_type);
                            break;
                        case EM_MIPS:
                        case EM_MIPS_RS3_LE:
                            result = get_mips_segment_type (p_type);
                            break;
                        case EM_PARISC:
                            result = get_parisc_segment_type (p_type);
                            break;
                        case EM_IA_64:
                            result = get_ia64_segment_type (p_type);
                            break;
                        case EM_TI_C6000:
                            result = get_tic6x_segment_type (p_type);
                            break;
                        default:
                            result = NULL;
                            break;
                    }
    
                    if (result != NULL)
                        return result;
    
                    sprintf (buff, "LOPROC+%x", p_type - PT_LOPROC);
                }
                else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
                {
                    const char * result;
    
                    switch (elf_header.e_machine)
                    {
                        case EM_PARISC:
                            result = get_parisc_segment_type (p_type);
                            break;
                        case EM_IA_64:
                            result = get_ia64_segment_type (p_type);
                            break;
                        default:
                            result = NULL;
                            break;
                    }
    
                    if (result != NULL)
                        return result;
    
                    sprintf (buff, "LOOS+%x", p_type - PT_LOOS);
                }
                else
                    snprintf (buff, sizeof (buff), ("<unknown>: %x"), p_type);
    
                return buff;
        }
    
    }
    
    
    
    int ELF_process::process_program_headers(FILE *file) {
    
        Elf32_Phdr* segment;
        unsigned long dynamic_addr;
        if(elf_header.e_phnum == 0){
    
            if(elf_header.e_phoff!=0){
                printf ("possibly corrupt ELF header - it has a non-zero program"
                                " header offset, but no program headers");
            } else
            {
                printf ("
    There are no program headers in this file.
    ");
                return 0;
            }
    
        }else{
            printf ("
    Program Headers:
    ");
    
    
            if(is_32bit_elf)
                printf("  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
    ");
            else
                printf("  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
    ");
    
        }
    
    
        if (! get_program_headers (file))
            return 0;
    
    
        unsigned int i;
        for (i = 0, segment = program_headers;
             i < elf_header.e_phnum;
             i++, segment++){
            printf ("  %-14.14s ", get_segment_type (segment->p_type));
    
            if(is_32bit_elf){
                printf ("0x%6.6x ", (unsigned int) segment->p_offset);
                printf ("0x%8.8x ", (unsigned int) segment->p_vaddr);
                printf ("0x%8.8x ", (unsigned int) segment->p_paddr);
                printf ("0x%5.5x ", (unsigned int) segment->p_filesz);
                printf ("0x%5.5x ", (unsigned int) segment->p_memsz);
                printf ("%c%c%c ",
                        (segment->p_flags & PF_R ? 'R' : ' '),
                        (segment->p_flags & PF_W ? 'W' : ' '),
                        (segment->p_flags & PF_X ? 'E' : ' '));
                printf ("%#x", (unsigned int) segment->p_align);
            }
    
            printf("
    ");
    
        }
    
    
    
        return 0;
    }
    
    
    const char *ELF_process::get_aarch64_segment_type(unsigned long type) {
    
        switch (type)
        {
            case PT_AARCH64_ARCHEXT:
                return "AARCH64_ARCHEXT";
            default:
                break;
        }
    
        return NULL;
    
    }
    
    const char *ELF_process::get_arm_segment_type(unsigned long type) {
    
        switch (type)
        {
            case PT_ARM_EXIDX:
                return "EXIDX";
            default:
                break;
        }
    
        return NULL;
    
    }
    
    const char *ELF_process::get_mips_segment_type(unsigned long type) {
    
        switch (type)
        {
            case PT_MIPS_REGINFO:
                return "REGINFO";
            case PT_MIPS_RTPROC:
                return "RTPROC";
            case PT_MIPS_OPTIONS:
                return "OPTIONS";
            default:
                break;
        }
    
        return NULL;
    }
    
    const char *ELF_process::get_parisc_segment_type(unsigned long type) {
        switch (type)
        {
            case PT_HP_TLS:        return "HP_TLS";
            case PT_HP_CORE_NONE:    return "HP_CORE_NONE";
            case PT_HP_CORE_VERSION:    return "HP_CORE_VERSION";
            case PT_HP_CORE_KERNEL:    return "HP_CORE_KERNEL";
            case PT_HP_CORE_COMM:    return "HP_CORE_COMM";
            case PT_HP_CORE_PROC:    return "HP_CORE_PROC";
            case PT_HP_CORE_LOADABLE:    return "HP_CORE_LOADABLE";
            case PT_HP_CORE_STACK:    return "HP_CORE_STACK";
            case PT_HP_CORE_SHM:    return "HP_CORE_SHM";
            case PT_HP_CORE_MMF:    return "HP_CORE_MMF";
            case PT_HP_PARALLEL:    return "HP_PARALLEL";
            case PT_HP_FASTBIND:    return "HP_FASTBIND";
            case PT_HP_OPT_ANNOT:    return "HP_OPT_ANNOT";
            case PT_HP_HSL_ANNOT:    return "HP_HSL_ANNOT";
            case PT_HP_STACK:        return "HP_STACK";
            case PT_HP_CORE_UTSNAME:    return "HP_CORE_UTSNAME";
            case PT_PARISC_ARCHEXT:    return "PARISC_ARCHEXT";
            case PT_PARISC_UNWIND:    return "PARISC_UNWIND";
            case PT_PARISC_WEAKORDER:    return "PARISC_WEAKORDER";
            default:
                break;
        }
    
        return NULL;
    
    
    }
    
    const char *ELF_process::get_ia64_segment_type(unsigned long type) {
    
        switch (type)
        {
            case PT_IA_64_ARCHEXT:    return "IA_64_ARCHEXT";
            case PT_IA_64_UNWIND:    return "IA_64_UNWIND";
            case PT_HP_TLS:        return "HP_TLS";
            case PT_IA_64_HP_OPT_ANOT:    return "HP_OPT_ANNOT";
            case PT_IA_64_HP_HSL_ANOT:    return "HP_HSL_ANNOT";
            case PT_IA_64_HP_STACK:    return "HP_STACK";
            default:
                break;
        }
    
        return NULL;
    }
    #define PT_C6000_PHATTR        0x70000000
    
    const char *ELF_process::get_tic6x_segment_type(unsigned long type) {
        switch (type)
        {
            case PT_C6000_PHATTR:    return "C6000_PHATTR";
            default:
                break;
        }
    
        return NULL;
    
    
    }
    
    int ELF_process::get_program_headers(FILE *file) {
    
        Elf32_Phdr* phdrs;
        Elf64_Phdr* phdrs64;
    
        /* Check cache of prior read.  */
        if (program_headers != NULL)
            return 1;
    
        phdrs = (Elf32_Phdr *) cmalloc (elf_header.e_phnum,
                                               sizeof (Elf32_Phdr));
    
        if (phdrs == NULL)
        {
            printf("Out of memory
    ");
            return 0;
        }
    
        if (is_32bit_elf
            ? get_32bit_program_headers (file, phdrs)
            : get_64bit_program_headers (file, phdrs64))
        {
            program_headers = phdrs;
            return 1;
        }
    
        free (phdrs);
        return 0;
    
    
    
    }
    
    int ELF_process::get_32bit_program_headers(FILE *file, Elf32_Phdr *pheaders) {
    
        Elf32_External_Phdr* phdrs;
        Elf32_External_Phdr* external;
        Elf32_Phdr* internal;
    
        unsigned int i;
    
        phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
                                                  elf_header.e_phentsize,
                                                  elf_header.e_phnum,
                                                  ("program headers"));
    
        if (!phdrs)
            return 0;
    
        for (i = 0, internal = pheaders, external = phdrs;
             i < elf_header.e_phnum;
             i++, internal++, external++){
    
            internal->p_type   = BYTE_GET (external->p_type);
            internal->p_offset = BYTE_GET (external->p_offset);
            internal->p_vaddr  = BYTE_GET (external->p_vaddr);
            internal->p_paddr  = BYTE_GET (external->p_paddr);
            internal->p_filesz = BYTE_GET (external->p_filesz);
            internal->p_memsz  = BYTE_GET (external->p_memsz);
            internal->p_flags  = BYTE_GET (external->p_flags);
            internal->p_align  = BYTE_GET (external->p_align);
        }
        free (phdrs);
    
        return 1;
    }
    
    int ELF_process::get_64bit_program_headers(FILE *file, Elf64_Phdr *pheaders) {
    
    
        return 0;
    }
    
    
    int ELF_process::process_dynamic_section(FILE *file) {
    
        Elf32_Dyn * entry;
    
    
        if (is_32bit_elf){
            if (! get_32bit_dynamic_section (file))
                return 0;
        } else if (! get_64bit_dynamic_section (file))
                 return 0;
    
        if(dynamic_addr){
            printf ("
    Dynamic section at offset 0x%x contains %u entries:
    ",
                    dynamic_addr, dynamic_nent);
            printf ("  Tag        Type                         Name/Value
    ");
        }
    
        for (entry = dynamic_section;
             entry < dynamic_section + dynamic_nent;
             entry++){
    
            const char * dtype;
            putchar (' ');
            printf("0x%2.8x ",entry->d_tag);
            dtype = get_dynamic_type(entry->d_tag);
            printf("(%s)%*s",dtype,(27-strlen(dtype))," ");
    
    
            switch (entry->d_tag){
                case DT_FLAGS:
                    print_dynamic_flags (entry->d_un.d_val);
                    break;
    
                case DT_AUXILIARY:
                case DT_FILTER:
                case DT_CONFIG:
                case DT_DEPAUDIT:
                case DT_AUDIT:
                    switch (entry->d_tag)
                    {
                        case DT_AUXILIARY:
                            printf ("Auxiliary library");
                            break;
    
                        case DT_FILTER:
                            printf ("Filter library");
                            break;
    
                        case DT_CONFIG:
                            printf ("Configuration file");
                            break;
    
                        case DT_DEPAUDIT:
                            printf ("Dependency audit library");
                            break;
    
                        case DT_AUDIT:
                            printf ("Audit library");
                            break;
                    }
                    break;
    
                default:
                    printf("0x%x",entry->d_un.d_val);
            }
    
            printf("
    ");
        }
    
    
    }
    
    
    
    int ELF_process::get_32bit_dynamic_section(FILE *file) {
    
        Elf32_External_Dyn * edyn = (Elf32_External_Dyn *) malloc(dynamic_size);
        Elf32_External_Dyn * ext;
        Elf32_Dyn * entry;
    
        fseek(file,dynamic_addr,SEEK_SET);
        fread(edyn,dynamic_size,1,file);
    
    
        if(edyn==NULL)
            return 0;
    
        for (ext = edyn, dynamic_nent = 0;
             (char *) ext < (char *) edyn + dynamic_size;
             ext++)
        {
            dynamic_nent++;
            if (BYTE_GET (ext->d_tag) == DT_NULL)
                break;
        }
    
        dynamic_section = (Elf32_Dyn *) cmalloc (dynamic_nent,
                                                        sizeof (* entry));
    
        if (dynamic_section == NULL)
        {
            printf("Out of memory
    ");
            free (edyn);
            return 0;
        }
    
    
        for (ext = edyn, entry = dynamic_section;
             entry < dynamic_section + dynamic_nent;
             ext++, entry++)
        {
            entry->d_tag      = BYTE_GET (ext->d_tag);
            entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
        }
    
        free(edyn);
    
        return 1;
    
    
    }
    
    int ELF_process::get_64bit_dynamic_section(FILE *file) {
    
        return 0;
    }
    
    void ELF_process::print_dynamic_flags(Elf32_Word flags) {
    
        int first = 1;
    
        while (flags)
        {
            Elf32_Word flag;
    
            flag = flags & - flags;
            flags &= ~ flag;
    
            if (first)
                first = 0;
            else
                putc (' ', stdout);
    
            switch (flag)
            {
                case DF_ORIGIN:        fputs ("ORIGIN", stdout); break;
                case DF_SYMBOLIC:    fputs ("SYMBOLIC", stdout); break;
                case DF_TEXTREL:    fputs ("TEXTREL", stdout); break;
                case DF_BIND_NOW:    fputs ("BIND_NOW", stdout); break;
                case DF_STATIC_TLS:    fputs ("STATIC_TLS", stdout); break;
                default:            fputs (("unknown"), stdout); break;
            }
        }
    
    }
    #define DT_FEATURE    0x6ffffdfc
    #define DT_USED        0x7ffffffe
    const char *ELF_process::get_dynamic_type(unsigned long type) {
    
        static char buff[64];
    
        switch (type){
    
            case DT_NULL:    return "NULL";
            case DT_NEEDED:    return "NEEDED";
            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_BIND_NOW:   return "BIND_NOW";
            case DT_INIT_ARRAY: return "INIT_ARRAY";
            case DT_FINI_ARRAY: return "FINI_ARRAY";
            case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
            case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
            case DT_RUNPATH:    return "RUNPATH";
            case DT_FLAGS:      return "FLAGS";
    
            case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
            case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
    
            case DT_CHECKSUM:    return "CHECKSUM";
            case DT_PLTPADSZ:    return "PLTPADSZ";
            case DT_MOVEENT:    return "MOVEENT";
            case DT_MOVESZ:    return "MOVESZ";
            case DT_FEATURE:    return "FEATURE";
            case DT_POSFLAG_1:    return "POSFLAG_1";
            case DT_SYMINSZ:    return "SYMINSZ";
            case DT_SYMINENT:    return "SYMINENT"; /* aka VALRNGHI */
    
            case DT_ADDRRNGLO:  return "ADDRRNGLO";
            case DT_CONFIG:    return "CONFIG";
            case DT_DEPAUDIT:    return "DEPAUDIT";
            case DT_AUDIT:    return "AUDIT";
            case DT_PLTPAD:    return "PLTPAD";
            case DT_MOVETAB:    return "MOVETAB";
            case DT_SYMINFO:    return "SYMINFO"; /* aka ADDRRNGHI */
    
            case DT_VERSYM:    return "VERSYM";
    
            case DT_TLSDESC_GOT: return "TLSDESC_GOT";
            case DT_TLSDESC_PLT: return "TLSDESC_PLT";
            case DT_RELACOUNT:    return "RELACOUNT";
            case DT_RELCOUNT:    return "RELCOUNT";
            case DT_FLAGS_1:    return "FLAGS_1";
            case DT_VERDEF:    return "VERDEF";
            case DT_VERDEFNUM:    return "VERDEFNUM";
            case DT_VERNEED:    return "VERNEED";
            case DT_VERNEEDNUM:    return "VERNEEDNUM";
    
            case DT_AUXILIARY:    return "AUXILIARY";
            case DT_USED:    return "USED";
            case DT_FILTER:    return "FILTER";
    
            case DT_GNU_PRELINKED: return "GNU_PRELINKED";
            case DT_GNU_CONFLICT: return "GNU_CONFLICT";
            case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
            case DT_GNU_LIBLIST: return "GNU_LIBLIST";
            case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
            case DT_GNU_HASH:    return "GNU_HASH";
    
    
        }
    
        return nullptr;
    }
    
    #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
    #define FALSE 0
    #define TRUE 1
    #define UNKNOWN -1
    static struct
    {
        const char * name;
        int reloc;
        int size;
        int rela;
    } dynamic_relocations [] =
            {
                    { "REL", DT_REL, DT_RELSZ, FALSE },
                    { "RELA", DT_RELA, DT_RELASZ, TRUE },
                    { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
            };
    Elf32_Rel* elf32_rel;
    int ELF_process::process_relocs(FILE *file) {
    
    
        Elf32_Rel* entry_rel;
    
        if(is_32bit_elf){
            get_32bit_rel(file,rel_dyn_offset);
        }
        else{
            //64位...
        }
        printf (" 
    at offset 0x%2.2x contains %u entries:
    ",
                rel_dyn_offset, rel_nent);
        printf ("  Offset          Info           Type           Sym. Value    Sym. Name
    ");
        for (entry_rel = elf32_rel;
             entry_rel < elf32_rel + rel_nent;
             entry_rel++)
        {
            printf("%10.8x ",entry_rel->r_offset);
            printf("%15.8x
    ",entry_rel->r_info);
        }
    
    
        return 0;
    }
    
    
    
    void ELF_process::get_32bit_rel(FILE *pFILE, unsigned int offset) {
    
        Elf32_External_Rel* rel= (Elf32_External_Rel *) malloc(rel_dyn_size);
        Elf32_External_Rel* ext;
        Elf32_Rel* relt;
    
        fseek(pFILE,offset,SEEK_SET);
        fread(rel,rel_dyn_size,1,pFILE);
    
        if(rel==NULL)
            return;
    
        for (ext = rel, rel_nent = 0;
             (char *) ext < (char *) rel + rel_dyn_size;
             ext++)
        {
            rel_nent++;
            if (BYTE_GET (rel->r_offset) == DT_NULL)
                break;
        }
    
        elf32_rel = (Elf32_Rel *) cmalloc (dynamic_nent,
                                           sizeof (* relt));
    
    
        for (ext = rel, relt = elf32_rel;
             relt < elf32_rel + rel_nent;
             ext++, relt++)
        {
            relt->r_offset     = BYTE_GET (ext->r_offset);
            relt->r_info       = BYTE_GET (ext->r_info);
        }
    
        free(rel);
    
        return;
    }
    
    void ELF_process::process_symbol_table(FILE *pFILE) {
    
    
        Elf32_Sym* sym;
        get_32bit_symbol(pFILE);
    
        printf("
    ");
    
        unsigned int i;
        for ( i=0, sym = sym_dyn;sym<sym_dyn+sym_nent;sym++,i++)
        {
            printf("%2d: ",i);
            printf("%2.8x ",sym->st_value);
            printf("%-2.2x",sym->st_shndx);
            printf("%-12.2x ",sym->st_other);
            printf("%-12.2x ",sym->st_info);
            printf("%-12.2x ",sym->st_size);
            get_32bit_strdyn(pFILE,sym->st_name);
        }
    
    }
    
    void ELF_process::get_32bit_symbol(FILE *pFILE) {
    
        Elf32_External_Sym* exty = (Elf32_External_Sym *) malloc(sym_dyn_size);
        Elf32_External_Sym* ext;
        Elf32_Sym* symbool;
    
        fseek(pFILE,sym_dyn_offset,SEEK_SET);
        fread(exty,sym_dyn_size,1,pFILE);
    
        if (!exty)
            return;
        for (ext = exty, sym_nent = 0;
             (char *) ext < (char *) exty + sym_dyn_size;
             ext++)
        {
            sym_nent++;
        }
    
        sym_dyn = (Elf32_Sym *) cmalloc (sym_nent,
                                           sizeof (* exty));
    
        for (ext = exty, symbool = sym_dyn ;
             symbool < sym_dyn + sym_nent;
             ext++, symbool++)
        {
    
            symbool->st_name       = BYTE_GET(ext->st_name);
            symbool->st_info       = BYTE_GET(ext->st_info);
            symbool->st_other      = BYTE_GET(ext->st_other);
            symbool->st_shndx      = BYTE_GET(ext->st_shndx);
            symbool->st_size       = BYTE_GET(ext->st_size);
            symbool->st_value      = BYTE_GET(ext->st_value);
    
            //printf("%2.2x ",sym_dyn->st_name);
        }
    
        free(exty);
    
        return;
    
    }
    
    void ELF_process::get_32bit_strdyn(FILE *pFILE, Elf32_Word name) {
    
        unsigned char sym_name[1024];
        fseek(pFILE,(str_dyn_offset+name),SEEK_SET);
        fread(sym_name,1024,1,pFILE);
        printf("%s
    ",sym_name);
    }
  • 相关阅读:
    数组函数
    跨域
    连接数据库的几种方式
    PHP语言的优缺点
    盗链
    缓存
    电商架构演进
    分布式集群
    序列化
    json
  • 原文地址:https://www.cnblogs.com/NigelX/p/6522001.html
Copyright © 2011-2022 走看看