//---------------------------------------- //--- 010 Editor v2.0 Binary Template // // File: ELFTemplate.bt // Author: 010Editor (Unknown?) // Tim "diff" Strazzere // Revision: 2.2 // Purpose: Defines a template for // parsing ELF 32-bit and 64-bit files. //---------------------------------------- // // Version 2.2 // FIXED: // - Fixed issues if the section header count is greater // the actual number of sections that exist. // More information; // http://dustri.org/b/?p=832 // // Version 2.1 // FIXED: // - Fixed issue with local variables so it's actually // runnable inside v4.0.3 // Define structures used in ELF files // ELF Header Types // ELF identification element // Accelerate a slow lookup with an array local int sec_tbl_elem[255]; // used for color pt_load segment local int PT_LOAD_Count = 0; // used for color section //local int SECTION_Count = 0; //标识已经通过section头部表获取到符号表 local int getSymBySection = 0; typedef enum { ELFCLASSNONE =0, ELFCLASS32 =1, ELFCLASS64 =2 }ei_class_2_e; typedef enum { ELFDATAONE =0, ELFDATA2LSB =1, ELFDATA2MSB =2 }ei_data_e; typedef enum { E_NONE =0, E_CURRENT =1 }ei_version_e; typedef enum { ELFOSABI_NONE =0, //No extensions or unspecified ELFOSABI_HPUX =1, //Hewlett-Packard HP-UX ELFOSABI_NETBSD =2, //NetBSD ELFOSABI_SOLARIS=6, //Sun Solaris ELFOSABI_AIX =7, //AIX ELFOSABI_IRIX =8, //IRIX ELFOSABI_FREEBSD=9, //FreeBSD ELFOSABI_TRU64 =10, //Compaq TRU64 UNIX ELFOSABI_MODESTO=11, //Novell Modesto ELFOSABI_OPENBSD=12, //Open BSD ELFOSABI_OPENVMS=13, //Open VMS ELFOSABI_NSK =14, //Hewlett-Packard Non-Stop Kernel ELFOSABI_AROS =15 //Amiga Research OS }ei_osabi_e; typedef struct { char file_identification[4]; ei_class_2_e ei_class_2; ei_data_e ei_data; if( ei_data == ELFDATA2LSB ) { LittleEndian(); } else { BigEndian(); } ei_version_e ei_version; ei_osabi_e ei_osabi; uchar ei_abiversion; uchar ei_pad[6]; uchar ei_nident_SIZE; } e_ident_t; // Elf Data Types for 32/64 bit //32 bit typedef uint32 Elf32_Word; typedef uint32 Elf32_Off; typedef uint32 Elf32_Addr ; typedef uint16 Elf32_Half; typedef uint32 Elf32_Xword; //64 bit typedef uint32 Elf64_Word; typedef uint64 Elf64_Off; typedef uint64 Elf64_Addr ; typedef uint16 Elf64_Half; typedef uint64 Elf64_Xword; string VAddr32( Elf32_Addr &addr ) { local char buf[128]; SPrintf( buf, "0x%08X", addr ); return buf; } string VAddr64( Elf64_Addr &addr ) { local char buf[128]; SPrintf( buf, "0x%016LX", addr ); return buf; } typedef enum { ET_NONE =0, ET_REL =1, ET_EXEC =2, ET_DYN =3, ET_CORE =4, ET_LOOS =0xfe00, ET_HIOS =0xfeff, ET_LOPROC =0xff00, ET_HIPROC =0xffff } e_type32_e; typedef e_type32_e e_type64_e; typedef enum { // list has to to be completed EM_NONE =0, //No machine EM_M32 =1, //AT&T WE 32100 EM_SPARC =2, //SPARC EM_386 =3, //Intel 80386 EM_68K =4, //Motorola 68000 EM_88K =5, //Motorola 88000 reserved6 =6, //Reserved for future use (was EM_486) EM_860 =7, //Intel 80860 EM_MIPS =8, //MIPS I Architecture EM_S370 =9, //IBM System/370 Processor EM_MIPS_RS3_LE =10, //MIPS RS3000 Little-endian reserved11 =11, //Reserved for future use reserved12 =12, //Reserved for future use reserved13 =13, //Reserved for future use reserved14 =14, //Reserved for future use EM_PARISC =15, //Hewlett-Packard PA-RISC reserved16 =16, //Reserved for future use EM_VPP500 =17, //Fujitsu VPP500 EM_SPARC32PLUS =18, //Enhanced instruction set SPARC EM_960 =19, //Intel 80960 EM_PPC =20, //PowerPC EM_PPC64 =21, //64-bit PowerPC EM_S390 =22, //IBM System/390 Processor reserved23 =23, //Reserved for future use reserved24 =24, //Reserved for future use reserved25 =25, //Reserved for future use reserved26 =26, //Reserved for future use reserved27 =27, //Reserved for future use reserved28 =28, //Reserved for future use reserved29 =29, //Reserved for future use reserved30 =30, //Reserved for future use reserved31 =31, //Reserved for future use reserved32 =32, //Reserved for future use reserved33 =33, //Reserved for future use reserved34 =34, //Reserved for future use reserved35 =35, //Reserved for future use EM_V800 =36, //NEC V800 EM_FR20 =37, //Fujitsu FR20 EM_RH32 =38, //TRW RH-32 EM_RCE =39, //Motorola RCE EM_ARM =40, //Advanced RISC Machines ARM EM_ALPHA =41, //Digital Alpha EM_SH =42, //Hitachi SH EM_SPARCV9 =43, //SPARC Version 9 EM_TRICORE =44, //Siemens TriCore embedded processor EM_ARC =45, //Argonaut RISC Core, Argonaut Technologies Inc. EM_H8_300 =46, //Hitachi H8/300 EM_H8_300H =47, //Hitachi H8/300H EM_H8S =48, //Hitachi H8S EM_H8_500 =49, //Hitachi H8/500 EM_IA_64 =50, //Intel IA-64 processor architecture EM_MIPS_X =51, //Stanford MIPS-X EM_COLDFIRE =52, //Motorola ColdFire EM_68HC12 =53, //Motorola M68HC12 EM_MMA =54, //Fujitsu MMA Multimedia Accelerator EM_PCP =55, //Siemens PCP EM_NCPU =56, //Sony nCPU embedded RISC processor EM_NDR1 =57, //Denso NDR1 microprocessor EM_STARCORE =58, //Motorola Star*Core processor EM_ME16 =59, //Toyota ME16 processor EM_ST100 =60, //STMicroelectronics ST100 processor EM_TINYJ =61, //Advanced Logic Corp. TinyJ embedded processor family EM_X86_64 =62, //AMD x86-64 architecture EM_PDSP =63, //Sony DSP Processor EM_PDP10 =64, //Digital Equipment Corp. PDP-10 EM_PDP11 =65, //Digital Equipment Corp. PDP-11 EM_FX66 =66, //Siemens FX66 microcontroller EM_ST9PLUS =67, //STMicroelectronics ST9+ 8/16 bit microcontroller EM_ST7 =68, //STMicroelectronics ST7 8-bit microcontroller EM_68HC16 =69, //Motorola MC68HC16 Microcontroller EM_68HC11 =70, //Motorola MC68HC11 Microcontroller EM_68HC08 =71, //Motorola MC68HC08 Microcontroller EM_68HC05 =72, //Motorola MC68HC05 Microcontroller EM_SVX =73, //Silicon Graphics SVx EM_ST19 =75, //Digital VAX EM_CRIS =76, //Axis Communications 32-bit embedded processor EM_JAVELIN =77, //Infineon Technologies 32-bit embedded processor EM_FIREPATH =78, //Element 14 64-bit DSP Processor EM_ZSP =79, //LSI Logic 16-bit DSP Processor EM_MMIX =80, //Donald Knuth's educational 64-bit processor EM_HUANY =81, //Harvard University machine-independent object files EM_PRISM =82, //SiTera Prism EM_AVR =83, //Atmel AVR 8-bit microcontroller EM_FR30 =84, //Fujitsu FR30 EM_D10V =85, //Mitsubishi D10V EM_D30V =86, //Mitsubishi D30V EM_V850 =87, //NEC v850 EM_M32R =88, //Mitsubishi M32R EM_MN10300 =89, //Matsushita MN10300 EM_MN10200 =90, //Matsushita MN10200 EM_PJ =91, //picoJava EM_OPENRISC =92, //OpenRISC 32-bit embedded processor EM_ARC_A5 =93, //ARC Cores Tangent-A5 EM_XTENSA =94, //Tensilica Xtensa Architecture EM_VIDEOCORE =95, //Alphamosaic VideoCore processor EM_TMM_GPP =96, //Thompson Multimedia General Purpose Processor EM_NS32K =97, //National Semiconductor 32000 series EM_TPC =98, //Tenor Network TPC processor EM_SNP1K =99, //Trebia SNP 1000 processor EM_ST200 =100, //STMicroelectronics (www.st.com) ST200 microcontroller EM_IP2K =101, //Ubicom IP2xxx microcontroller family EM_MAX =102, //MAX Processor EM_CR =103, //National Semiconductor CompactRISC microprocessor EM_F2MC16 =104, //Fujitsu F2MC16 EM_MSP430 =105, //Texas Instruments embedded microcontroller msp430 EM_BLACKFIN =106, //Analog Devices Blackfin (DSP) processor EM_SE_C33 =107, //S1C33 Family of Seiko Epson processors EM_SEP =108, //Sharp embedded microprocessor EM_ARCA =109, //Arca RISC Microprocessor EM_UNICORE =110 //Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University } e_machine32_e; typedef e_machine32_e e_machine64_e; typedef enum { EV_NONE =0, EV_CURRENT =1 } e_version32_e; typedef e_version32_e e_version64_e; // Program Header Types typedef enum { PT_NULL =0, PT_LOAD =1, PT_DYNAMIC =2, PT_INERP =3, PT_NOTE =4, PT_SHLIB =5, PT_PHDR =6, PT_LOOS =0x60000000, PT_HIOS =0x6fffffff, PT_LOPROC =0x70000000, PT_HIPROC =0x7fffffff } p_type32_e; typedef p_type32_e p_type64_e; typedef enum { PF_None =0, PF_Exec =1, PF_Write =2, PF_Write_Exec =3, PF_Read =4, PF_Read_Exec =5, PF_Read_Write =6, PF_Read_Write_Exec =7 } p_flags32_e; typedef p_flags32_e p_flags64_e; typedef enum { DT_NULL = 0, DT_NEEDED = 1, DT_PLTRELSZ = 2, DT_PLTGOT = 3, DT_HASH = 4, DT_STRTAB = 5, DT_SYMTAB = 6, DT_RELA = 7, DT_RELASZ = 8, DT_RELAENT = 9, DT_STRSZ = 10, DT_SYMENT = 11, DT_INIT = 12, DT_FINI = 13, DT_SONAME = 14, DT_RPATH = 15, DT_SYMBOLIC = 16, DT_REL = 17, DT_RELSZ = 18, DT_RELENT = 19, DT_PLTREL = 20, DT_DEBUG = 21, DT_TEXTREL = 22, DT_JMPREL = 23, DT_BIND_NOW = 24, DT_INIT_ARRAY = 25, DT_FINI_ARRAY = 26, DT_INIT_ARRAYSZ = 27, DT_FINI_ARRAYSZ = 28, DT_RUNPATH = 29, DT_FLAGS = 30, DT_ENCODING = 31, DT_PREINIT_ARRAY = 32, DT_PREINIT_ARRAYSZ = 33, DT_MAXPOSTAGS = 34, DT_SUNW_SYMTAB = 0x60000011, DT_SUNW_SYMSZ = 0x60000012 } p_dyn_tag32; typedef enum { SHN_UNDEF = 0, /* undefined, e.g. undefined symbol */ SHN_LORESERVE = 0xff00, /* Lower bound of reserved indices */ SHN_LOPROC = 0xff00, /* Lower bound processor-specific index */ SHN_HIPROC = 0xff1f, /* Upper bound processor-specific index */ SHN_LOOS = 0xff20, /* Lower bound OS-specific index */ SHN_HIOS = 0xff3f, /* Upper bound OS-specific index */ SHN_ABS = 0xfff1, /* Absolute value, not relocated */ SHN_COMMON = 0xfff2, /* FORTRAN common or unallocated C */ SHN_HIRESERVE = 0xffff /* Upper bound of reserved indices */ } s_name32_e; typedef s_name32_e s_name64_e; typedef enum { SHT_NULL = 0, /* Inactive section header */ SHT_PROGBITS = 1, /* Information defined by the program */ SHT_SYMTAB = 2, /* Symbol table - not DLL */ SHT_STRTAB = 3, /* String table */ SHT_RELA = 4, /* Explicit addend relocations, Elf64_Rela */ SHT_HASH = 5, /* Symbol hash table */ SHT_DYNAMIC = 6, /* Information for dynamic linking */ SHT_NOTE = 7, /* A Note section */ SHT_NOBITS = 8, /* Like SHT_PROGBITS with no data */ SHT_REL = 9, /* Implicit addend relocations, Elf64_Rel */ SHT_SHLIB = 10, /* Currently unspecified semantics */ SHT_DYNSYM = 11, /* Symbol table for a DLL */ SHT_LOOS = 0x60000000, /* Lowest OS-specific section type */ SHT_HIOS = 0x6fffffff, /* Highest OS-specific section type */ SHT_LOPROC = 0x70000000, /* Lowest processor-specific section type */ SHT_HIPROC = 0x7fffffff /* Highest processor-specific section type */ } s_type32_e; typedef s_type32_e s_type64_e; string ReservedSectionName( s_name32_e id ) { local char buf[255]; if( id == SHN_UNDEF ) return "SHN_UNDEF"; if( id >= SHN_LOPROC && id <= SHN_HIPROC ) { SPrintf( buf, "SHN_PROC_%02X", id - SHN_LOPROC ); return buf; } if( id >= SHN_LOOS && id <= SHN_HIOS ) { SPrintf( buf, "SHN_OS_%02X", id - SHN_LOOS ); return buf; } if( id == SHN_ABS ) return "SHN_ABS"; if( id == SHN_COMMON ) return "SHN_COMMON"; SPrintf( buf, "SHN_RESERVE_%02X", id - SHN_LORESERVE ); return buf; } // Program Table 32/64 bit typedef struct { //32bit local quad off = FTell(); p_type32_e p_type; Elf32_Off p_offset_FROM_FILE_BEGIN ; Elf32_Addr p_vaddr_VIRTUAL_ADDRESS; Elf32_Addr p_paddr_PHYSICAL_ADDRESS; Elf32_Word p_filesz_SEGMENT_FILE_LENGTH; Elf32_Word p_memsz_SEGMENT_RAM_LENGTH; p_flags32_e p_flags; Elf32_Word p_align; if( p_filesz_SEGMENT_FILE_LENGTH > 0 ) { FSeek(p_offset_FROM_FILE_BEGIN); if(p_type==PT_LOAD){ if(PT_LOAD_Count%2 == 0){ SetBackColor(cLtGreen); }else{ SetBackColor(0xFFBBFF); } PT_LOAD_Count += 1; } char p_data[p_filesz_SEGMENT_FILE_LENGTH]; SetBackColor(cNone); } FSeek(off + file.elf_header.e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE); } program_table_entry32_t ; typedef struct { //64bit local quad off = FTell(); p_type64_e p_type; p_flags64_e p_flags; Elf64_Off p_offset_FROM_FILE_BEGIN ; Elf64_Addr p_vaddr_VIRTUAL_ADDRESS; Elf64_Addr p_paddr_PHYSICAL_ADDRESS; Elf64_Xword p_filesz_SEGMENT_FILE_LENGTH; Elf64_Xword p_memsz_SEGMENT_RAM_LENGTH; Elf64_Xword p_align; if( p_filesz_SEGMENT_FILE_LENGTH > 0 ) { FSeek(p_offset_FROM_FILE_BEGIN); char p_data[p_filesz_SEGMENT_FILE_LENGTH]; } FSeek(off + file.elf_header.e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE); } program_table_entry64_t ; string ProgramType( p_type64_e type ) { switch( type ) { case PT_NULL: return "NULL"; case PT_LOAD: return "Loadable Segment"; case PT_DYNAMIC: return "Dynamic Segment"; case PT_INERP: return "Interpreter Path"; case PT_NOTE: return "Note"; case PT_SHLIB: return "PT_SHLIB"; case PT_PHDR: return "Program Header"; default: return "Unknown Section"; } } string ProgramFlags( p_flags64_e flags ) { local string rv = "("; rv += ( flags & PF_Read ) ? "R" : "_"; rv += ( flags & PF_Write ) ? "W" : "_"; rv += ( flags & PF_Exec ) ? "X" : "_"; rv += ")"; return rv; } string ProgramInfo64( program_table_entry64_t &ent ) { return ProgramFlags( ent.p_flags ) + " " + ProgramType( ent.p_type ); } string ProgramInfo32( program_table_entry32_t &ent ) { return ProgramFlags( ent.p_flags ) + " " + ProgramType( ent.p_type ); } // ************************************* Section Table *************************************** typedef enum { SF32_None =0, SF32_Write =1, SF32_Alloc =2, SF32_Alloc_Write =3, SF32_Exec =4, SF32_Exec_Write =5, SF32_Exec_Alloc =6, SF32_Exec_Alloc_Write =7 } s_flags32_e; typedef enum { SF64_None =0, SF64_Exec =1, SF64_Alloc =2, SF64_Alloc_Exec =3, SF64_Write =4, SF64_Write_Exec =5, SF64_Write_Alloc =6, SF64_Write_Alloc_Exec =7 } s_flags64_e; // Pointer to where the next name is located local quad section_name_block_off; typedef struct { s_name32_e s_name_off ; local quad off = FTell(); FSeek( section_name_block_off + s_name_off ); string s_name_str; FSeek( off ); } s_name32_t ; typedef s_name32_t s_name64_t; string SectionName( s_name32_t § ) { if( sect.s_name_off > SHN_UNDEF && sect.s_name_off < SHN_LORESERVE ) { return sect.s_name_str; } return ReservedSectionName( sect.s_name_off ); } typedef struct { //64bit local quad off = FTell(); s_name64_t s_name; /* Section name */ s_type64_e s_type; /* Section type */ s_flags64_e s_flags; /* Section attributes */ Elf64_Addr s_addr; /* Virtual address in memory */ Elf64_Off s_offset ; /* Offset in file */ Elf64_Xword s_size; /* Size of section */ Elf64_Word s_link; /* Link to other section */ Elf64_Word s_info; /* Miscellaneous information */ Elf64_Xword s_addralign; /* Address alignment boundary */ Elf64_Xword s_entsize; /* Entry size, if section has table */ if( s_type != SHT_NOBITS && s_type != SHT_NULL && s_size > 0 ) { FSeek(s_offset); char data[s_size]; } FSeek(off + file.elf_header.e_shentzise_SECTION_HEADER_ENTRY_SIZE); } section_table_entry64_t ; // Section Table 32/64 bit typedef struct { //32bit local quad off = FTell(); s_name32_t s_name; /* Section name */ s_type32_e s_type; /* Section type */ s_flags32_e s_flags; /* Section attributes */ Elf32_Addr s_addr; /* Virtual address in memory */ Elf32_Off s_offset ; /* Offset in file */ Elf32_Xword s_size; /* Size of section */ Elf32_Word s_link; /* Link to other section */ Elf32_Word s_info; /* Miscellaneous information */ Elf32_Xword s_addralign; /* Address alignment boundary*/ Elf32_Xword s_entsize; /* Entry size, if section has table */ if( s_type != SHT_NOBITS && s_type != SHT_NULL && s_size > 0 ) { FSeek(s_offset); //if(SECTION_Count %2 == 0){ // SetForeColor(cPurple); //}else{ // SetForeColor(cYellow); //} //SECTION_Count += 1; char s_data[s_size]; //SetForeColor(cNone); } FSeek(off + file.elf_header.e_shentzise_SECTION_HEADER_ENTRY_SIZE); } section_table_entry32_t ; string SectionName64( section_table_entry64_t § ) { return SectionName( sect.s_name ); } string SectionName32( section_table_entry32_t § ) { return SectionName( sect.s_name ); } // ************************************** Symbol Table *************************************** local quad symbol_name_block_off; typedef struct { Elf32_Word sym_name_off ; /* Symbol table name offset */ local quad off = FTell(); FSeek( symbol_name_block_off + sym_name_off ); string sym_name_str; FSeek( off ); } sym_name32_t ; typedef sym_name32_t sym_name64_t; string SymbolName( sym_name32_t &sym ) { if( sym.sym_name_off > 0 ) { return sym.sym_name_str; } return ""; } typedef enum { STB_LOCAL = 0, STB_GLOBAL = 1, STB_WEAK = 2, STB_OS_1 = 10, STB_OS_2 = 11, STB_OS_3 = 12, STB_PROC_1 = 13, STB_PROC_2 = 14, STB_PROC_3 = 15 } sym_info_bind_e; typedef enum { STT_NOTYPE = 0, STT_OBJECT = 1, STT_FUNC = 2, STT_SECTION = 3, STT_FILE = 4, STT_OS_1 = 10, STT_OS_2 = 11, STT_OS_3 = 12, STT_PROC_1 = 13, STT_PROC_2 = 14, STT_PROC_3 = 15 } sym_info_type_e; typedef struct { BitfieldDisablePadding(); if( IsBigEndian() ) { uchar sym_info_bind:4; uchar sym_info_type:4; } else { uchar sym_info_type:4; uchar sym_info_bind:4; } BitfieldEnablePadding(); } sym_info_t ; string SymInfoEnums( sym_info_t &info ) { local sym_info_bind_e x = info.sym_info_bind; local sym_info_type_e y = info.sym_info_type; return EnumToString( x ) + " | " + EnumToString( y ); } typedef struct { Elf64_Word sym_name; /* Symbol name */ unsigned char sym_info; /* Type and Binding attributes */ unsigned char sym_other; /* Reserved */ Elf64_Half sym_shndx; /* Section table index */ Elf64_Addr sym_value; /* Symbol value */ Elf64_Xword sym_size; /* Size of object (e.g., common) */ } Elf64_Sym_fixed; typedef struct { Elf32_Word sym_name; /* Symbol name */ Elf32_Addr sym_value; /* Symbol value */ Elf32_Xword sym_size; /* Size of object (e.g., common) */ unsigned char sym_info; /* Type and Binding attributes */ unsigned char sym_other; /* Reserved */ Elf32_Half sym_shndx; /* Section table index */ } Elf32_Sym_fixed; local int loadable1Vaddr; local int loadable1FileOff; typedef struct { sym_name64_t sym_name; /* Symbol name */ sym_info_t sym_info; /* Type and Binding attributes */ unsigned char sym_other; /* Reserved */ Elf64_Half sym_shndx; /* Section table index */ Elf64_Addr sym_value; /* Symbol value */ Elf64_Xword sym_size; /* Size of object (e.g., common) */ if( sym_size ) { if(SectionHasData( sym_shndx )){ local quad off = FTell(); FSeek( SectionVAddrOffset( sym_shndx, sym_value)); char sym_data[sym_size]; FSeek( off ); } else{ //section has being removed or is bss section local Elf32_Addr fAddr = sym_value - loadable1Vaddr + loadable1FileOff; if(fAddr + sym_size < FileSize()){ local quad off = FTell(); FSeek(sym_value - loadable1Vaddr + loadable1FileOff); //sym_value is the vAddr char sym_data[sym_size]; FSeek( off ); } } } } Elf64_Sym ; typedef struct { sym_name32_t sym_name; /* Symbol name */ Elf32_Addr sym_value; /* Symbol value */ Elf32_Xword sym_size; /* Size of object (e.g., common) */ sym_info_t sym_info; /* Type and Binding attributes */ unsigned char sym_other; /* Reserved */ Elf32_Half sym_shndx; /* Section table index */ if( sym_size ) { if(SectionHasData( sym_shndx )){ local quad off = FTell(); FSeek( SectionVAddrOffset( sym_shndx, sym_value)); char sym_data[sym_size]; FSeek( off ); } else{ //section has being removed or is bss section local Elf32_Addr fAddr = sym_value - loadable1Vaddr + loadable1FileOff; if(fAddr + sym_size < FileSize()){ local quad off = FTell(); FSeek(sym_value - loadable1Vaddr + loadable1FileOff); //sym_value is the vAddr char sym_data[sym_size]; FSeek( off ); } } } } Elf32_Sym ; string SymbolName64( Elf64_Sym &sym ) { return ( sym.sym_size ? "" : "[U] " ) + SymbolName( sym.sym_name ); } string SymbolName32( Elf32_Sym &sym ) { return ( sym.sym_size ? "" : "[U] " ) + SymbolName( sym.sym_name ) +" "+ SymInfoEnums(sym.sym_info); } local Elf32_Off dtStrOff; local Elf32_Word dtStrSize; typedef struct { p_dyn_tag32 d_tag ; union { Elf32_Word d_val ; Elf32_Addr d_ptr ; Elf32_Off d_off ; } d_un ; if(d_tag == DT_NEEDED || d_tag == DT_SONAME ){ local quad off = FTell(); FSeek( dtStrOff + d_un.d_off); string name_str; FSeek( off ); } if (d_tag == DT_HASH){ local quad off2 = FTell(); FSeek(d_un.d_ptr); struct{ Elf32_Word nbucket; Elf32_Word nchain; Elf32_Word bucket[nbucket]; Elf32_Word chain[nchain]; } dt_hash; FSeek(off2); } } Elf32_Dyn ; //just for arm, copy from aosp, 不同的abi有不同的定义 typedef enum { R_ARM_NONE =0, R_ARM_PC24 =1, R_ARM_ABS32 =2, R_ARM_REL32 =3, R_ARM_PC13 =4, R_ARM_ABS16 =5, R_ARM_ABS12 =6, R_ARM_THM_ABS5 =7, R_ARM_ABS8 =8, R_ARM_SBREL32 =9, R_ARM_THM_PC22 =10, R_ARM_THM_PC8 =11, R_ARM_AMP_VCALL9 =12, R_ARM_SWI24 =13, R_ARM_THM_SWI8 =14, R_ARM_XPC25 =15, R_ARM_THM_XPC22 =16, R_ARM_TLS_DTPMOD32 =17, R_ARM_TLS_DTPOFF32 =18, R_ARM_TLS_TPOFF32 =19, R_ARM_COPY =20, R_ARM_GLOB_DAT =21, R_ARM_JUMP_SLOT =22, R_ARM_RELATIVE =23, R_ARM_GOTOFF =24, R_ARM_GOTPC =25, R_ARM_GOT32 =26, R_ARM_PLT32 =27, R_ARM_ALU_PCREL_7_0 =32, R_ARM_ALU_PCREL_15_8 =33, R_ARM_ALU_PCREL_23_15 =34, R_ARM_ALU_SBREL_11_0 =35, R_ARM_ALU_SBREL_19_12 =36, R_ARM_ALU_SBREL_27_20 =37, R_ARM_GNU_VTENTRY =100, R_ARM_GNU_VTINHERIT =101, R_ARM_THM_PC11 =102, R_ARM_THM_PC9 =103, R_ARM_TLS_GD32 =104, R_ARM_TLS_LDM32 =105, R_ARM_TLS_LDO32 =106, R_ARM_TLS_IE32 =107, R_ARM_TLS_LE32 =108, R_ARM_TLS_LDO12 =109, R_ARM_TLS_LE12 =110, R_ARM_TLS_IE12GP =111, R_ARM_RXPC25 =249, R_ARM_RSBREL32 =250, R_ARM_THM_RPC22 =251, R_ARM_RREL32 =252, R_ARM_RABS32 =253, R_ARM_RPC24 =254, R_ARM_RBASE =255 } r_type_t; //低一位表示type,高三位表示sym_index typedef struct { r_type_t type; Elf32_Half sym_index; char sym_index2; } r_info_t_32; typedef struct { Elf32_Addr r_offset; r_info_t_32 r_info; } Elf32_Rel; typedef struct { Elf32_Addr r_offset; r_info_t_32 r_info; Elf32_Word r_addend; } Elf32_Rela; string DynName32(Elf32_Dyn &dyn){ if(dyn.d_tag == DT_NEEDED || dyn.d_tag == DT_SONAME ){ return EnumToString(dyn.d_tag) + " " +dyn.name_str; } return EnumToString(dyn.d_tag); } // **************************************** ELF File ***************************************** int FindNamedSection( string sect ) { local int iter; for( iter=0; iter < file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES; iter++ ) { if( Strcmp( file.section_header_table.section_table_element[ iter ].s_name.s_name_str, sect ) == 0 ) { return iter; } } return -1; } int FindSectionByNamePrefix( string name ) { local int iter; for( iter=0; iter < file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES; iter++ ) { if( Strstr( file.section_header_table.section_table_element[ iter ].s_name.s_name_str, name ) == 0 ) { return iter; } } return -1; } //通过类型查找segment, repeat表示出现的次数 int FindSegmentByType( p_type32_e ptype , int repeat) { local int i; local int j = 0; local p_type32_e tmpType; for(i=0; i; // Find the program table if( file.elf_header.e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES > 0 ) { FSeek(file.elf_header.e_phoff_PROGRAM_HEADER_OFFSET_IN_FILE); struct { if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { program_table_entry32_t program_table_element[file.elf_header.e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES]; } else { program_table_entry64_t program_table_element[file.elf_header.e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES]; } } program_header_table; } // Find the header name location local quad section_name_off = file.elf_header.e_shoff_SECTION_HEADER_OFFSET_IN_FILE + ( file.elf_header.e_shentzise_SECTION_HEADER_ENTRY_SIZE * file.elf_header.e_shtrndx_STRING_TABLE_INDEX ); // Find the header name block if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { if( FileSize() >= section_name_off + 2 * sizeof( Elf32_Word ) + sizeof( Elf32_Xword ) + sizeof( Elf32_Addr ) ) section_name_block_off = ReadUInt( section_name_off + 2 * sizeof( Elf32_Word ) + sizeof( Elf32_Xword ) + sizeof( Elf32_Addr ) ); else { Printf("Invalid section header found, skipping!\n"); Warning("Invalid section header found, skipped and attempting to continue..."); } } else { if( FileSize() >= section_name_off + 2 * sizeof( Elf64_Word ) + sizeof( Elf64_Xword ) + sizeof( Elf64_Addr ) ) section_name_block_off = ReadUQuad( section_name_off + 2 * sizeof( Elf64_Word ) + sizeof( Elf64_Xword ) + sizeof( Elf64_Addr ) ); else { Printf("Invalid section header found, skipping!\n"); Warning("Invalid section header found, skipped and attempting to continue..."); } } local int sec_tbl_cur_elem; // Find the section headers if( file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES > 0 ) { FSeek(file.elf_header.e_shoff_SECTION_HEADER_OFFSET_IN_FILE); struct { if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { sec_tbl_cur_elem = 0; section_table_entry32_t section_table_element[file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES]; } else { sec_tbl_cur_elem = 0; section_table_entry64_t section_table_element[file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES]; } } section_header_table; } local int sym_sect; local int sym_name_sect; // Find the symbol section sym_sect = FindNamedSection( ".symtab" ); if( sym_sect >= 0 ) { getSymBySection = 1; sym_name_sect = file.section_header_table.section_table_element[sym_sect].s_link; symbol_name_block_off = file.section_header_table.section_table_element[sym_name_sect].s_offset; FSeek( file.section_header_table.section_table_element[sym_sect].s_offset ); struct { if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { Elf32_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf32_Sym_fixed)]; } else { Elf64_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf64_Sym_fixed)]; } } symbol_table; } // Find the dynamic symbol section sym_sect = FindNamedSection( ".dynsym" ); if( sym_sect >= 0 ) { getSymBySection = 1; sym_name_sect = file.section_header_table.section_table_element[sym_sect].s_link; symbol_name_block_off = file.section_header_table.section_table_element[sym_name_sect].s_offset; FSeek( file.section_header_table.section_table_element[sym_sect].s_offset ); struct { if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { Elf32_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf32_Sym_fixed)]; } else { Elf64_Sym symtab[file.section_header_table.section_table_element[sym_sect].s_size / sizeof(Elf64_Sym_fixed)]; } } dynamic_symbol_table; } local int dynIndex = FindSegmentByType(PT_DYNAMIC, 1); local int loadable1Index = FindSegmentByType(PT_LOAD, 1); if(loadable1Index >=0 ){ loadable1Vaddr = file.program_header_table.program_table_element[loadable1Index].p_vaddr_VIRTUAL_ADDRESS; loadable1FileOff = file.program_header_table.program_table_element[loadable1Index].p_offset_FROM_FILE_BEGIN; } local int loadable2Index = FindSegmentByType(PT_LOAD, 2); local int loadable2Vaddr; local int loadable2FileOff; if(loadable2Index >= 1){ loadable2Vaddr = file.program_header_table.program_table_element[loadable2Index].p_vaddr_VIRTUAL_ADDRESS; loadable2FileOff = file.program_header_table.program_table_element[loadable2Index].p_offset_FROM_FILE_BEGIN; } local Elf32_Addr initArrayPtr; local Elf32_Word initArraySize; local Elf32_Addr finiArrayPtr; local Elf32_Word finiArraySize; local Elf32_Addr dymOff; local Elf32_Word dymEntrySize; local Elf32_Word dymEntryCount; if(dynIndex >=0){ local Elf32_Off dynOff = file.program_header_table.program_table_element[dynIndex].p_offset_FROM_FILE_BEGIN; FSeek(dynOff); //local int dynSize = file.program_header_table.program_table_element[dynIndex].p_filesz_SEGMENT_FILE_LENGTH /sizeof(Elf32_Dyn); local int dynSize = file.program_header_table.program_table_element[dynIndex].p_filesz_SEGMENT_FILE_LENGTH /8; struct { local p_dyn_tag32 p_d_tag; for(dynIndex=0; dynIndex 0 && dtStrSize > 0 ){ local Elf32_Off dtStrFileOff; dtStrFileOff = dtStrOff - (loadable1Vaddr - loadable1FileOff); local quad off = FTell(); FSeek(dtStrFileOff); char dtStr[dtStrSize]; FSeek(off); } if(initArrayPtr > 0 && initArraySize > 0 ){ local int initArrayFilePtr; initArrayFilePtr = initArrayPtr - (loadable2Vaddr - loadable2FileOff); local quad off2 = FTell(); FSeek(initArrayFilePtr); Elf32_Addr initArray[initArraySize/sizeof(Elf32_Addr)]; FSeek(off2); } if(finiArrayPtr > 0 && finiArraySize > 0 ){ local int finiArrayFilePtr; finiArrayFilePtr = finiArrayPtr - (loadable2Vaddr - loadable2FileOff); local quad off3 = FTell(); FSeek(finiArrayFilePtr); Elf32_Addr finiArray[finiArraySize/sizeof(Elf32_Addr)]; FSeek(off3); } if(dymOff>0 && dymEntrySize >0 && dymEntryCount){ local quad off4 = FTell(); FSeek(dymOff); struct { if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 ) { Elf32_Sym symtab[dymEntryCount]; } else { Elf64_Sym symtab[dymEntryCount]; } } symbol_table2; FSeek(off4); } local int rel_sect; local int rel_size; local int rel_entry_size; rel_sect = FindSectionByNamePrefix(".rel.dyn"); if(rel_sect>=0){ rel_size = file.section_header_table.section_table_element[rel_sect].s_size; rel_entry_size = file.section_header_table.section_table_element[rel_sect].s_entsize; FSeek(file.section_header_table.section_table_element[rel_sect].s_offset); Elf32_Rel rel_dyn[rel_size/rel_entry_size]; } rel_sect = FindSectionByNamePrefix(".rel.plt"); if(rel_sect>=0){ rel_size = file.section_header_table.section_table_element[rel_sect].s_size; rel_entry_size = file.section_header_table.section_table_element[rel_sect].s_entsize; FSeek(file.section_header_table.section_table_element[rel_sect].s_offset); Elf32_Rel rel_plt[rel_size/rel_entry_size]; } } file;