这里先定义数据的表示形式
Name Size Alignment
ELF32_Addr 4B 4B
ELF32_Half 4B 2B
ELF32_Off 4B 4B
ELF32_Sword 4B 4B
ELF32_Word 4B 4B
unsigned char 1B 1B
在elf文件中,都是使用的这几种数据类型。
下面介绍elf header。定义如下:
下面的信息来自/usr/include/elf.h
/* The ELF file header. This appears at the start of every ELF file. */
#define EI_NIDENT (16)
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
Elf32_Addr e_entry; /* Entry point virtual address */
Elf32_Off e_phoff; /* Program header table file offset */
Elf32_Off e_shoff; /* Section header table file offset */
Elf32_Word e_flags; /* Processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size in bytes */
Elf32_Half e_phentsize; /* Program header table entry size */
Elf32_Half e_phnum; /* Program header table entry count */
Elf32_Half e_shentsize; /* Section header table entry size */
Elf32_Half e_shnum; /* Section header table entry count */
Elf32_Half e_shstrndx; /* Section header string table index */
} Elf32_Ehdr;
先看Elf32_Ehdr,这个结构体的大小是52B,可以由上面定义的数据类型的大小计算出来。接下来一个一个看看Elf32_Ehdr的结构成员。
e_ident[EI_NIDENT]: 这个是elf identification.
前四个字节EI_MAG) ~ EI_MAG3, 内容目前固定为'0x7f','E','L','F'.
第五个字节EI_CLASS的内容指明该文件的种类,有三种情况:
ELFCLASSNONE
0
Invalid calss
ELFCLASS32
1
32-bit bojects
ELFCLASS64
2
64-bit objexts
第六个字节EI_DATA指明data encoding,即是LSB, 还是MSB.
第七个字节EI_VERSION指明文件的版本。
第八个字节EI_PAD指明在e_ident中未使用字节的开始处,这些都是保留字节,且被设置为零。
e_type:指明目标该文件的类型
Name
Value
Meaning
e_machine:指明可以在哪种机器结构中运行。
e_version:指明版本信息
e_entry:指明系统运行该程序时将控制权转交到的虚拟地址的值,如果没有则为零。
e_phoff: program header table在文件中的字节(Byte)偏移offset,如果没有program header table, 则该值为零。
e_shoff: section header table在文件中的字节偏移,如果没有section header table, 则该值为零
e_flags: 有关处理器的信息
e_ehsize: elf header的大小,单位:字节
e_phentsize: 在program header table中一个entry的大小,前面提到过,program header table & section header table都是数组,所以它们的每一个元素,即每一个entry的大小,都是一样的。
e_phnum: program header table中元素的个数,即entry的个数。
e_shentsize: section header table每一个entry的大小,与e_phentsize类似。
e_shnum: section header table中元素的个数,即entry的个数。可以看出来,这个program header table或者section header table的大小可以用entry的个数乘以每一个entry的大小得到。
e_shstrndx: 指明string name table在section header table中的index。
例子程序:
#include stdio.h>
#include elf.h>
int main(int ac, char **av)
{
FILE *fp;
Elf32_Ehdr elfheader;
if(ac != 2) {
printf("usage: av[0] elf_filename\n");
exit(-1);
}
fp = fopen(av[1], "r");
if(fp == NULL) {
printf("open file error %s\n", av[1]);
exit(-2);
}
fread(&elfheader, sizeof(char), sizeof(elfheader), fp);
/*print out the elf header infomation here*/
}
在linux 2.4.20下编译通过,并可正确执行。
当然,为了理解深刻,也可以这样写程序
typedef union _int4
{
unsigned char a[4];
unsigned int size;
} INT4;
typedef union _int2
{
unsigned char a[2];
unsigned short int size;
}INT2;
unsigned char elf_header[52];/*因为elf_header是52B*/
/*elf_header中的所有元素都在这52个字节中了,可以得到header中的所有东西,只是要注意LSB和MSB的区别*/
Name Size Alignment
ELF32_Addr 4B 4B
ELF32_Half 4B 2B
ELF32_Off 4B 4B
ELF32_Sword 4B 4B
ELF32_Word 4B 4B
unsigned char 1B 1B
在elf文件中,都是使用的这几种数据类型。
下面介绍elf header。定义如下:
下面的信息来自/usr/include/elf.h
/* The ELF file header. This appears at the start of every ELF file. */
#define EI_NIDENT (16)
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
Elf32_Addr e_entry; /* Entry point virtual address */
Elf32_Off e_phoff; /* Program header table file offset */
Elf32_Off e_shoff; /* Section header table file offset */
Elf32_Word e_flags; /* Processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size in bytes */
Elf32_Half e_phentsize; /* Program header table entry size */
Elf32_Half e_phnum; /* Program header table entry count */
Elf32_Half e_shentsize; /* Section header table entry size */
Elf32_Half e_shnum; /* Section header table entry count */
Elf32_Half e_shstrndx; /* Section header string table index */
} Elf32_Ehdr;
先看Elf32_Ehdr,这个结构体的大小是52B,可以由上面定义的数据类型的大小计算出来。接下来一个一个看看Elf32_Ehdr的结构成员。
e_ident[EI_NIDENT]: 这个是elf identification.
前四个字节EI_MAG) ~ EI_MAG3, 内容目前固定为'0x7f','E','L','F'.
第五个字节EI_CLASS的内容指明该文件的种类,有三种情况:
ELFCLASSNONE
0
Invalid calss
ELFCLASS32
1
32-bit bojects
ELFCLASS64
2
64-bit objexts
第六个字节EI_DATA指明data encoding,即是LSB, 还是MSB.
第七个字节EI_VERSION指明文件的版本。
第八个字节EI_PAD指明在e_ident中未使用字节的开始处,这些都是保留字节,且被设置为零。
e_type:指明目标该文件的类型
Name
Value
Meaning
e_machine:指明可以在哪种机器结构中运行。
e_version:指明版本信息
e_entry:指明系统运行该程序时将控制权转交到的虚拟地址的值,如果没有则为零。
e_phoff: program header table在文件中的字节(Byte)偏移offset,如果没有program header table, 则该值为零。
e_shoff: section header table在文件中的字节偏移,如果没有section header table, 则该值为零
e_flags: 有关处理器的信息
e_ehsize: elf header的大小,单位:字节
e_phentsize: 在program header table中一个entry的大小,前面提到过,program header table & section header table都是数组,所以它们的每一个元素,即每一个entry的大小,都是一样的。
e_phnum: program header table中元素的个数,即entry的个数。
e_shentsize: section header table每一个entry的大小,与e_phentsize类似。
e_shnum: section header table中元素的个数,即entry的个数。可以看出来,这个program header table或者section header table的大小可以用entry的个数乘以每一个entry的大小得到。
e_shstrndx: 指明string name table在section header table中的index。
例子程序:
#include stdio.h>
#include elf.h>
int main(int ac, char **av)
{
FILE *fp;
Elf32_Ehdr elfheader;
if(ac != 2) {
printf("usage: av[0] elf_filename\n");
exit(-1);
}
fp = fopen(av[1], "r");
if(fp == NULL) {
printf("open file error %s\n", av[1]);
exit(-2);
}
fread(&elfheader, sizeof(char), sizeof(elfheader), fp);
/*print out the elf header infomation here*/
}
在linux 2.4.20下编译通过,并可正确执行。
当然,为了理解深刻,也可以这样写程序
typedef union _int4
{
unsigned char a[4];
unsigned int size;
} INT4;
typedef union _int2
{
unsigned char a[2];
unsigned short int size;
}INT2;
unsigned char elf_header[52];/*因为elf_header是52B*/
/*elf_header中的所有元素都在这52个字节中了,可以得到header中的所有东西,只是要注意LSB和MSB的区别*/