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);
    }
  • 相关阅读:
    CF1202F You Are Given Some Letters...
    CF1178E Archaeology
    PTA (Advanced Level) 1005 Spell It Right
    PTA (Advanced Level) 1004 Counting Leaves
    Qt5——从零开始的Hello World教程(Qt Creator)
    PTA (Advanced Level) 1003 Emergency
    PTA (Advanced Level) 1002 A+B for Polynomials
    HDU 1272 小希的迷宫
    FZU 2150 Fire Game
    HihoCoder
  • 原文地址:https://www.cnblogs.com/NigelX/p/6522001.html
Copyright © 2011-2022 走看看