btparser/cparser/ELFTemplate.bt

795 lines
26 KiB
Plaintext

//----------------------------------------
//--- 010 Editor v2.0 Binary Template
//
// File: ELFTemplate.bt
// Author: 010Editor (Unknown?)
// Tim "diff" Strazzere <diff@lookout.com> <strazz@gmail.com>
// 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];
typedef enum <uchar> {
ELFCLASSNONE =0,
ELFCLASS32 =1,
ELFCLASS64 =2
}ei_class_2_e;
typedef enum <uchar> {
ELFDATAONE =0,
ELFDATA2LSB =1,
ELFDATA2MSB =2
}ei_data_e;
typedef enum <uchar> {
E_NONE =0,
E_CURRENT =1
}ei_version_e;
typedef enum <uchar> {
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 <read=VAddr32>;
typedef uint16 Elf32_Half;
typedef uint32 Elf32_Xword;
//64 bit
typedef uint32 Elf64_Word;
typedef uint64 Elf64_Off;
typedef uint64 Elf64_Addr <read=VAddr64>;
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 <Elf32_Half> {
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 <Elf32_Half> { // 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 <Elf32_Word> {
EV_NONE =0,
EV_CURRENT =1
} e_version32_e;
typedef e_version32_e e_version64_e;
// Program Header Types
typedef enum <Elf32_Word> {
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 <Elf32_Word> {
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 <Elf32_Word> {
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 <Elf32_Word> {
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 <format=hex>;
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);
char p_data[p_filesz_SEGMENT_FILE_LENGTH];
}
FSeek(off + file.elf_header.e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE);
} program_table_entry32_t <read=ProgramInfo32,optimize=false>;
typedef struct { //64bit
local quad off = FTell();
p_type64_e p_type;
p_flags64_e p_flags;
Elf64_Off p_offset_FROM_FILE_BEGIN <format=hex>;
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 <read=ProgramInfo64,optimize=false>;
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 <Elf32_Xword> {
SF32_None =0,
SF32_Exec =1,
SF32_Alloc =2,
SF32_Alloc_Exec =3,
SF32_Write =4,
SF32_Write_Exec =5,
SF32_Write_Alloc =6,
SF32_Write_Alloc_Exec =7
} s_flags32_e;
typedef enum <Elf64_Xword> {
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 <format=hex>;
local quad off = FTell();
FSeek( section_name_block_off + s_name_off );
string s_name_str;
FSeek( off );
} s_name32_t <read=SectionName>;
typedef s_name32_t s_name64_t;
string SectionName( s_name32_t &sect ) {
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 <format=hex>; /* 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 <optimize=false>;
// 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 <format=hex>; /* 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);
char s_data[s_size];
}
FSeek(off + file.elf_header.e_shentzise_SECTION_HEADER_ENTRY_SIZE);
} section_table_entry32_t <read=SectionName32,optimize=false>;
string SectionName64( section_table_entry64_t &sect ) {
return SectionName( sect.s_name );
}
string SectionName32( section_table_entry32_t &sect ) {
return SectionName( sect.s_name );
}
// ************************************** Symbol Table ***************************************
local quad symbol_name_block_off;
typedef struct {
Elf32_Word sym_name_off <format=hex>; /* 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 <read=SymbolName,optimize=false>;
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 "<Undefined>";
}
typedef enum <unsigned char> {
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 <unsigned char> {
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 <read=SymInfoEnums>;
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;
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 && SectionHasData( sym_shndx ) ) {
local quad off = FTell();
FSeek( SectionVAddrOffset( sym_shndx, sym_value ) );
char sym_data[sym_size];
FSeek( off );
}
} Elf64_Sym <read=SymbolName64,optimize=false>;
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 && SectionHasData( sym_shndx ) ) {
local quad off = FTell();
FSeek( SectionVAddrOffset( sym_shndx, sym_value ) );
char sym_data[sym_size];
FSeek( off );
}
} Elf32_Sym <read=SymbolName32,optimize=false>;
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 );
}
// **************************************** ELF File *****************************************
local int iter;
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;
}
quad FindNamedSectionBlock( string sect ) {
local int off = FindNamedSection( sect );
if( off != -1 )
return file.section_header_table.section_table_element[off].s_offset;
return -1;
}
int SectionHasData( Elf64_Half s_index ) {
// This is ridiculously slow for some reason, so cache our results in an array
if( sec_tbl_elem[s_index] == -1 ) {
sec_tbl_elem[s_index] = exists( file.section_header_table.section_table_element[s_index].s_data );
}
return sec_tbl_elem[s_index];
}
quad SectionVAddrOffset( Elf64_Half s_index, Elf64_Addr s_vaddr ) {
if( s_index < file.elf_header.e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES ) {
return file.section_header_table.section_table_element[s_index].s_offset + s_vaddr -
file.section_header_table.section_table_element[s_index].s_addr;
}
return 0;
}
// Structure of elf
struct {
local int i;
for( i=0; i<255; i++ ) {
sec_tbl_elem[i] = -1;
}
struct {
e_ident_t e_ident;
if (file.elf_header.e_ident.ei_class_2 == ELFCLASS32 )
{
//32-Bit definitions of ELF Header
e_type32_e e_type;
e_machine32_e e_machine;
e_version32_e e_version;
Elf32_Addr e_entry_START_ADDRESS;
Elf32_Off e_phoff_PROGRAM_HEADER_OFFSET_IN_FILE;
Elf32_Off e_shoff_SECTION_HEADER_OFFSET_IN_FILE;
Elf32_Word e_flags;
Elf32_Half e_ehsize_ELF_HEADER_SIZE;
Elf32_Half e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE;
Elf32_Half e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES;
Elf32_Half e_shentzise_SECTION_HEADER_ENTRY_SIZE;
Elf32_Half e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES;
Elf32_Half e_shtrndx_STRING_TABLE_INDEX;
}
else
{
//64-Bit definitions of ELF Header
e_type64_e e_type;
e_machine64_e e_machine;
e_version64_e e_version;
Elf64_Addr e_entry_START_ADDRESS;
Elf64_Off e_phoff_PROGRAM_HEADER_OFFSET_IN_FILE;
Elf64_Off e_shoff_SECTION_HEADER_OFFSET_IN_FILE;
Elf32_Word e_flags;
Elf64_Half e_ehsize_ELF_HEADER_SIZE;
Elf64_Half e_phentsize_PROGRAM_HEADER_ENTRY_SIZE_IN_FILE;
Elf64_Half e_phnum_NUMBER_OF_PROGRAM_HEADER_ENTRIES;
Elf64_Half e_shentzise_SECTION_HEADER_ENTRY_SIZE;
Elf64_Half e_shnum_NUMBER_OF_SECTION_HEADER_ENTRIES;
Elf64_Half e_shtrndx_STRING_TABLE_INDEX;
}
} elf_header;
// 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 ) {
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 ) {
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;
}
} file;