一个obj elf文件的分析 1/2

来源:互联网 发布:国泰安数据库百科 编辑:程序博客网 时间:2024/05/16 01:53

 

1         术语:

 

2         摘要:

本文分析了linux下的obj的二进制文件的layout

 

Linux下的obj文件是一种elf格式,包含了编译、链接过程中的相关信息,如ELF头、段表、重定位表、字符串表、符号表、debug信息表等诸多数据段,本文通过一个简单的c函数编译出来的obj文件,分析上述各段的相互关系以及在obj内部的layout情况。

 

3         数据结构

 

3.1       通用数据结构

 

/* Type for a 16-bit quantity.  */

typedef uint16_t Elf32_Half;

typedef uint16_t Elf64_Half;

 

/* Types for signed and unsigned 32-bit quantities.  */

typedef uint32_t Elf32_Word;

typedef    int32_t  Elf32_Sword;

typedef uint32_t Elf64_Word;

typedef    int32_t  Elf64_Sword;

 

/* Types for signed and unsigned 64-bit quantities.  */

typedef uint64_t Elf32_Xword;

typedef    int64_t  Elf32_Sxword;

typedef uint64_t Elf64_Xword;

typedef    int64_t  Elf64_Sxword;

 

/* Type of addresses.  */

typedef uint32_t Elf32_Addr;

typedef uint64_t Elf64_Addr;

 

/* Type of file offsets.  */

typedef uint32_t Elf32_Off;

typedef uint64_t Elf64_Off;

 

/* Type for section indices, which are 16-bit quantities.  */

typedef uint16_t Elf32_Section;

typedef uint16_t Elf64_Section;

 

/* Type for version symbol information.  */

typedef Elf32_Half Elf32_Versym;

typedef Elf64_Half Elf64_Versym;

 

 

/* The ELF file header.  This appears at the start of every ELF file.  */

 

#define EI_NIDENT (16)

 

 

4         Obj目标文件实例分析:

 

4.1       使用的函数

4.1.1         Helloworld.c

 

#include<stdio.h>

 

int main()

{

printf("Hello world\n");

 

return 0;

 

}

 

4.1.2         Tsection.c

 

#include<stdio.h>

 

int global_init_1 = 77;

int global_uninit_2;

 

void func1(int i)

{

printf("Hello world %d\n", i);

}

 

int main()

{

static s_init = 99;

static s_uninit;

 

int a = 1;

int b;

 

func1(s_init+global_init_1);

 

return 0;

 

}

 

 

4.2       ELF header

4.2.1         数据结构

 

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; (占用52个字节)

 

typedef struct

{

  unsigned char     e_ident[EI_NIDENT];   /* Magic number and other info */

  Elf64_Half  e_type;                  /* Object file type */

  Elf64_Half  e_machine;            /* Architecture */

  Elf64_Word       e_version;              /* Object file version */

  Elf64_Addr e_entry;          /* Entry point virtual address */

  Elf64_Off   e_phoff;         /* Program header table file offset */

  Elf64_Off   e_shoff;          /* Section header table file offset */

  Elf64_Word       e_flags;          /* Processor-specific flags */

  Elf64_Half  e_ehsize;        /* ELF header size in bytes */

  Elf64_Half  e_phentsize;           /* Program header table entry size */

  Elf64_Half  e_phnum;              /* Program header table entry count */

  Elf64_Half  e_shentsize;           /* Section header table entry size */

  Elf64_Half  e_shnum;        /* Section header table entry count */

  Elf64_Half  e_shstrndx;            /* Section header string table index */

} Elf64_Ehdr; (占用64个字节)

 

 

1.1.1         实例分析

 

O文件的二进制内容:

 

通过readelf得到的头信息:

 

从中可以看出,该O文件为ELF64的,对应的数据结构应该为Elf64_Ehdr;(占用64个字节),从上图黄色框部分可以印证size。图中红色框部分属于magic里面的内容,各字节含义即后面的描述。

ELF headerO文件中占用了0-0x3f这个区域。

 

1.1       段表

 

1.1.1         数据结构

/* Section header.  */

 

typedef struct

{

  Elf32_Word       sh_name;        /* Section name (string tbl index) */

  Elf32_Word       sh_type;         /* Section type */

  Elf32_Word       sh_flags;         /* Section flags */

  Elf32_Addr sh_addr;         /* Section virtual addr at execution */

  Elf32_Off   sh_offset;              /* Section file offset */

  Elf32_Word       sh_size;          /* Section size in bytes */

  Elf32_Word       sh_link;          /* Link to another section */

  Elf32_Word       sh_info;          /* Additional section information */

  Elf32_Word       sh_addralign;         /* Section alignment */

  Elf32_Word       sh_entsize;             /* Entry size if section holds table */

} Elf32_Shdr; (占用40个字节)

 

typedef struct

{

  Elf64_Word       sh_name;        /* Section name (string tbl index) */

  Elf64_Word       sh_type;         /* Section type */

  Elf64_Xword     sh_flags;         /* Section flags */

  Elf64_Addr sh_addr;         /* Section virtual addr at execution */

  Elf64_Off   sh_offset;              /* Section file offset */

  Elf64_Xword     sh_size;          /* Section size in bytes */

  Elf64_Word       sh_link;          /* Link to another section */

  Elf64_Word       sh_info;          /* Additional section information */

  Elf64_Xword     sh_addralign;         /* Section alignment */

  Elf64_Xword     sh_entsize;             /* Entry size if section holds table */

} Elf64_Shdr; (占用64个字节)

 

1.1.2         实例分析

O文件二进制内容,根据elf header得出的段表的起始offset 为0x128,根据段结构,将text段表标记如下:

 

 

段表里的name只是一个offset,它指明在.shstrtab里面对应的字符串位置。

通过readelf得出的段表信息:

 

 

通过以上信息,我们可以得出这个OBJ文件的layout信息如下:

 

 

 

1.1       重定位表

 

1.1.1         数据结构

 

 

/* Relocation table entry without addend (in section of type SHT_REL).  */

 

typedef struct

{

  Elf32_Addr       r_offset;         /* Address */

  Elf32_Word      r_info;                  /* Relocation type and symbol index */

} Elf32_Rel; (占用8个字节)

 

/* I have seen two different definitions of the Elf64_Rel and

   Elf64_Rela structures, so we'll leave them out until Novell (or

   whoever) gets their act together.  */

/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */

 

typedef struct

{

  Elf64_Addr r_offset;         /* Address */

  Elf64_Xword     r_info;                  /* Relocation type and symbol index */

} Elf64_Rel; (占用16个字节)

 

/* Relocation table entry with addend (in section of type SHT_RELA).  */

 

typedef struct

{

  Elf32_Addr r_offset;         /* Address */

  Elf32_Word       r_info;                  /* Relocation type and symbol index */

  Elf32_Sword      r_addend;              /* Addend */

} Elf32_Rela; (占用12个字节)

 

typedef struct

{

  Elf64_Addr r_offset;         /* Address */

  Elf64_Xword     r_info;                  /* Relocation type and symbol index */

  Elf64_Sxword    r_addend;              /* Addend */

} Elf64_Rela; (占用24个字节)

 

 

 

 

 

 

 

 

 

 

 

原创粉丝点击