导入 /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] = '