Linux系统--ELF文件之可重定位文件(Relocatable file)解析

    Linux下ELF文件类型分为以下几种:

    1、可重定位文件,例如SimpleSection.o;

    2、可执行文件,例如/bin/bash;

    3、共享目标文件,例如/lib/libc.so。


    本文章中,我们会使用objdump,readelf,hexdump,nm等来分析一个linux中可重定位文件SimpleSection.o。


    首先附上SimpleSection.c源代码:

[cpp]  view plain  copy
  1. int printf( const char* format, ... );  
  2.   
  3.   
  4. int global_init_var = 84;  
  5. int global_uninit_var;  
  6.   
  7. void func1( int i )  
  8. {  
  9.     printf( "%d\n", i );  
  10. }  
  11.   
  12. int main(void)  
  13. {  
  14.     static int static_var = 85;  
  15.     static int static_var2;  
  16.   
  17.     int a = 1;  
  18.     int b;  
  19.   
  20.     func1( static_var + static_var2 + a + b );  
  21.           
  22.     return a;  
  23. }  
    使用命令:

    gcc -c SimpleSection.c

    得到SimpleSection.o,下面我们首先附上SimpleSection.o的二进制内容以及整体轮廓。


    使用命令:

    hexdump -C SimpleSection.o,得到SimpleSection.o的二进制内容。

    计算机科学中,二进制0 1可以代表代码,字母,数字(十进制数和十六进制数)。

[plain]  view plain  copy
  1. 00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|  
  2. 00000010  01 00 3e 00 01 00 00 00  00 00 00 00 00 00 00 00  |..>.............|  
  3. 00000020  00 00 00 00 00 00 00 00  88 01 00 00 00 00 00 00  |................|  
  4. 00000030  00 00 00 00 40 00 00 00  00 00 40 00 0d 00 0a 00  |....@.....@.....|  
  5. 00000040  55 48 89 e5 48 83 ec 10  89 7d fc 8b 45 fc 89 c6  |UH..H....}..E...|  
  6. 00000050  bf 00 00 00 00 b8 00 00  00 00 e8 00 00 00 00 c9  |................|  
  7. 00000060  c3 55 48 89 e5 48 83 ec  10 c7 45 f8 01 00 00 00  |.UH..H....E.....|  
  8. 00000070  8b 15 00 00 00 00 8b 05  00 00 00 00 01 d0 03 45  |...............E|  
  9. 00000080  f8 03 45 fc 89 c7 e8 00  00 00 00 8b 45 f8 c9 c3  |..E.........E...|  
  10. 00000090  54 00 00 00 55 00 00 00  25 64 0a 00 00 47 43 43  |T...U...%d...GCC|  
  11. 000000a0  3a 20 28 55 62 75 6e 74  75 2f 4c 69 6e 61 72 6f  |: (Ubuntu/Linaro|  
  12. 000000b0  20 34 2e 36 2e 33 2d 31  75 62 75 6e 74 75 35 29  | 4.6.3-1ubuntu5)|  
  13. 000000c0  20 34 2e 36 2e 33 00 00  14 00 00 00 00 00 00 00  | 4.6.3..........|  
  14. 000000d0  01 7a 52 00 01 78 10 01  1b 0c 07 08 90 01 00 00  |.zR..x..........|  
  15. 000000e0  1c 00 00 00 1c 00 00 00  00 00 00 00 21 00 00 00  |............!...|  
  16. 000000f0  00 41 0e 10 86 02 43 0d  06 5c 0c 07 08 00 00 00  |.A....C..\......|  
  17. 00000100  1c 00 00 00 3c 00 00 00  00 00 00 00 2f 00 00 00  |....<......./...|  
  18. 00000110  00 41 0e 10 86 02 43 0d  06 6a 0c 07 08 00 00 00  |.A....C..j......|  
  19. 00000120  00 2e 73 79 6d 74 61 62  00 2e 73 74 72 74 61 62  |..symtab..strtab|  
  20. 00000130  00 2e 73 68 73 74 72 74  61 62 00 2e 72 65 6c 61  |..shstrtab..rela|  
  21. 00000140  2e 74 65 78 74 00 2e 64  61 74 61 00 2e 62 73 73  |.text..data..bss|  
  22. 00000150  00 2e 72 6f 64 61 74 61  00 2e 63 6f 6d 6d 65 6e  |..rodata..commen|  
  23. 00000160  74 00 2e 6e 6f 74 65 2e  47 4e 55 2d 73 74 61 63  |t..note.GNU-stac|  
  24. 00000170  6b 00 2e 72 65 6c 61 2e  65 68 5f 66 72 61 6d 65  |k..rela.eh_frame|  
  25. 00000180  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  26. *  
  27. 000001c0  00 00 00 00 00 00 00 00  20 00 00 00 01 00 00 00  |........ .......|  
  28. 000001d0  06 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  29. 000001e0  40 00 00 00 00 00 00 00  50 00 00 00 00 00 00 00  |@.......P.......|  
  30. 000001f0  00 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|  
  31. 00000200  00 00 00 00 00 00 00 00  1b 00 00 00 04 00 00 00  |................|  
  32. 00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  33. 00000220  b0 06 00 00 00 00 00 00  78 00 00 00 00 00 00 00  |........x.......|  
  34. 00000230  0b 00 00 00 01 00 00 00  08 00 00 00 00 00 00 00  |................|  
  35. 00000240  18 00 00 00 00 00 00 00  26 00 00 00 01 00 00 00  |........&.......|  
  36. 00000250  03 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  37. 00000260  90 00 00 00 00 00 00 00  08 00 00 00 00 00 00 00  |................|  
  38. 00000270  00 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|  
  39. 00000280  00 00 00 00 00 00 00 00  2c 00 00 00 08 00 00 00  |........,.......|  
  40. 00000290  03 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  41. 000002a0  98 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|  
  42. 000002b0  00 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|  
  43. 000002c0  00 00 00 00 00 00 00 00  31 00 00 00 01 00 00 00  |........1.......|  
  44. 000002d0  02 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  45. 000002e0  98 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|  
  46. 000002f0  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|  
  47. 00000300  00 00 00 00 00 00 00 00  39 00 00 00 01 00 00 00  |........9.......|  
  48. 00000310  30 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |0...............|  
  49. 00000320  9c 00 00 00 00 00 00 00  2b 00 00 00 00 00 00 00  |........+.......|  
  50. 00000330  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|  
  51. 00000340  01 00 00 00 00 00 00 00  42 00 00 00 01 00 00 00  |........B.......|  
  52. 00000350  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  53. 00000360  c7 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  54. 00000370  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|  
  55. 00000380  00 00 00 00 00 00 00 00  57 00 00 00 01 00 00 00  |........W.......|  
  56. 00000390  02 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  57. 000003a0  c8 00 00 00 00 00 00 00  58 00 00 00 00 00 00 00  |........X.......|  
  58. 000003b0  00 00 00 00 00 00 00 00  08 00 00 00 00 00 00 00  |................|  
  59. 000003c0  00 00 00 00 00 00 00 00  52 00 00 00 04 00 00 00  |........R.......|  
  60. 000003d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  61. 000003e0  28 07 00 00 00 00 00 00  30 00 00 00 00 00 00 00  |(.......0.......|  
  62. 000003f0  0b 00 00 00 08 00 00 00  08 00 00 00 00 00 00 00  |................|  
  63. 00000400  18 00 00 00 00 00 00 00  11 00 00 00 03 00 00 00  |................|  
  64. 00000410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  65. 00000420  20 01 00 00 00 00 00 00  61 00 00 00 00 00 00 00  | .......a.......|  
  66. 00000430  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|  
  67. 00000440  00 00 00 00 00 00 00 00  01 00 00 00 02 00 00 00  |................|  
  68. 00000450  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  69. 00000460  c8 04 00 00 00 00 00 00  80 01 00 00 00 00 00 00  |................|  
  70. 00000470  0c 00 00 00 0b 00 00 00  08 00 00 00 00 00 00 00  |................|  
  71. 00000480  18 00 00 00 00 00 00 00  09 00 00 00 03 00 00 00  |................|  
  72. 00000490  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  73. 000004a0  48 06 00 00 00 00 00 00  66 00 00 00 00 00 00 00  |H.......f.......|  
  74. 000004b0  00 00 00 00 00 00 00 00  01 00 00 00 00 00 00 00  |................|  
  75. 000004c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  76. *  
  77. 000004e0  01 00 00 00 04 00 f1 ff  00 00 00 00 00 00 00 00  |................|  
  78. 000004f0  00 00 00 00 00 00 00 00  00 00 00 00 03 00 01 00  |................|  
  79. 00000500  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  80. 00000510  00 00 00 00 03 00 03 00  00 00 00 00 00 00 00 00  |................|  
  81. 00000520  00 00 00 00 00 00 00 00  00 00 00 00 03 00 04 00  |................|  
  82. 00000530  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  83. 00000540  00 00 00 00 03 00 05 00  00 00 00 00 00 00 00 00  |................|  
  84. 00000550  00 00 00 00 00 00 00 00  11 00 00 00 01 00 03 00  |................|  
  85. 00000560  04 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|  
  86. 00000570  21 00 00 00 01 00 04 00  00 00 00 00 00 00 00 00  |!...............|  
  87. 00000580  04 00 00 00 00 00 00 00  00 00 00 00 03 00 07 00  |................|  
  88. 00000590  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  89. 000005a0  00 00 00 00 03 00 08 00  00 00 00 00 00 00 00 00  |................|  
  90. 000005b0  00 00 00 00 00 00 00 00  00 00 00 00 03 00 06 00  |................|  
  91. 000005c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  92. 000005d0  32 00 00 00 11 00 03 00  00 00 00 00 00 00 00 00  |2...............|  
  93. 000005e0  04 00 00 00 00 00 00 00  42 00 00 00 11 00 f2 ff  |........B.......|  
  94. 000005f0  04 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|  
  95. 00000600  54 00 00 00 12 00 01 00  00 00 00 00 00 00 00 00  |T...............|  
  96. 00000610  21 00 00 00 00 00 00 00  5a 00 00 00 10 00 00 00  |!.......Z.......|  
  97. 00000620  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|  
  98. 00000630  61 00 00 00 12 00 01 00  21 00 00 00 00 00 00 00  |a.......!.......|  
  99. 00000640  2f 00 00 00 00 00 00 00  00 53 69 6d 70 6c 65 53  |/........SimpleS|  
  100. 00000650  65 63 74 69 6f 6e 2e 63  00 73 74 61 74 69 63 5f  |ection.c.static_|  
  101. 00000660  76 61 72 2e 31 35 39 34  00 73 74 61 74 69 63 5f  |var.1594.static_|  
  102. 00000670  76 61 72 32 2e 31 35 39  35 00 67 6c 6f 62 61 6c  |var2.1595.global|  
  103. 00000680  5f 69 6e 69 74 5f 76 61  72 00 67 6c 6f 62 61 6c  |_init_var.global|  
  104. 00000690  5f 75 6e 69 6e 69 74 5f  76 61 72 00 66 75 6e 63  |_uninit_var.func|  
  105. 000006a0  31 00 70 72 69 6e 74 66  00 6d 61 69 6e 00 00 00  |1.printf.main...|  
  106. 000006b0  11 00 00 00 00 00 00 00  0a 00 00 00 05 00 00 00  |................|  
  107. 000006c0  00 00 00 00 00 00 00 00  1b 00 00 00 00 00 00 00  |................|  
  108. 000006d0  02 00 00 00 0e 00 00 00  fc ff ff ff ff ff ff ff  |................|  
  109. 000006e0  32 00 00 00 00 00 00 00  02 00 00 00 03 00 00 00  |2...............|  
  110. 000006f0  00 00 00 00 00 00 00 00  38 00 00 00 00 00 00 00  |........8.......|  
  111. 00000700  02 00 00 00 04 00 00 00  fc ff ff ff ff ff ff ff  |................|  
  112. 00000710  47 00 00 00 00 00 00 00  02 00 00 00 0d 00 00 00  |G...............|  
  113. 00000720  fc ff ff ff ff ff ff ff  20 00 00 00 00 00 00 00  |........ .......|  
  114. 00000730  02 00 00 00 02 00 00 00  00 00 00 00 00 00 00 00  |................|  
  115. 00000740  40 00 00 00 00 00 00 00  02 00 00 00 02 00 00 00  |@...............|  
  116. 00000750  21 00 00 00 00 00 00 00                           |!.......|  

                                 图1


    使用命令ls -l SimpleSection.o,可以得到文件大小为1880字节,上面二进制内容正好也是1880个字节(0x758转换为十机制为1880)。


    SimpleSection.o的整体轮廓图如下,可能读者会想为什么会得到这样一张图,随着我们深入分析每个段的内容,答案自然会揭晓。
Linux系统--ELF文件之可重定位文件(Relocatable file)解析_第1张图片

                                                                     图 2


    我们看到0x758是所有段结束的位置,换算成十进制就是1880个字节。和我们刚才获取的文件大小一样。

   

    下面我们来利用命令来分析ELF文件结构的每个部分:

    1、ELF Header

    使用命令readelf -h SimpleSection.o,得到下图。

Linux系统--ELF文件之可重定位文件(Relocatable file)解析_第2张图片

                             图 3

    ELF文件头结构及相关参数被定义在“/usr/include/elf.h”中,如下:

[plain]  view plain  copy
  1. typedef struct  
  2. {  
  3.   unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */  
  4.   Elf32_Half    e_type;                 /* Object file type */  
  5.   Elf32_Half    e_machine;              /* Architecture */  
  6.   Elf32_Word    e_version;              /* Object file version */  
  7.   Elf32_Addr    e_entry;                /* Entry point virtual address */  
  8.   Elf32_Off     e_phoff;                /* Program header table file offset */  
  9.   Elf32_Off     e_shoff;                /* Section header table file offset */  
  10.   Elf32_Word    e_flags;                /* Processor-specific flags */  
  11.   Elf32_Half    e_ehsize;               /* ELF header size in bytes */  
  12.   Elf32_Half    e_phentsize;            /* Program header table entry size */  
  13.   Elf32_Half    e_phnum;                /* Program header table entry count */  
  14.   Elf32_Half    e_shentsize;            /* Section header table entry size */  
  15.   Elf32_Half    e_shnum;                /* Section header table entry count */  
  16.   Elf32_Half    e_shstrndx;             /* Section header string table index */  
  17. } Elf32_Ehdr;  
    Type:ELF文件类型,本例中为REL(Relocatable File),可重定位文件。

    Start of section headers,段表在文件中偏移,就是图2中Section Table的位置为392(0x188)。

    Size of section headers,ELF文件头的大小为64个字节。

    Number of section headers,ELF拥有多少个断,本例为13个段。见图 7。

    Section header string table index,段表字符串表所在的段在段表中的下标。本例中等于10,见图 7。


    2、.text

    使用命令:

    objdump -d SimpleSection.o,得到了下图,由于是代码段,所以二进制代表汇编代码。

Linux系统--ELF文件之可重定位文件(Relocatable file)解析_第3张图片

                            图 4     

 

    3、.data

    使用命令objdump -s SimpleSection.o,得到数据段,如下图:

Linux系统--ELF文件之可重定位文件(Relocatable file)解析_第4张图片

                       图 5


    本例中存入数据段的是

[plain]  view plain  copy
  1. int global_init_var = 84;  
  2. static int static_var = 85;  
    共8个字节,一个是0x00000054,十进制是84;一个是0x0000000055,十进制是85。     


    4、.bss

    使用命令objdump -h SimpleSection.o,得到下图:

Linux系统--ELF文件之可重定位文件(Relocatable file)解析_第5张图片

                      图 6

    本例中存入数据段的是

[plain]  view plain  copy
  1. static int static_var2;  
    大家会注意到int global_uninit_var;既没有在.data段中,也没有在.bss段中。如果在前面加上static,那么则存在.bss段中。


    5、.rodata

    .rodata存放的只读数据。25640a00,查看ASCII表代表的就是%d\n。


    6、.shstrtab(段表字符串表)

    如图1,存放的是

    ..symtab..strtab..shstrtab..rela.text..data..bs..rodata..comment..note.GNU-stak..rela.eh_frame


    7、.strtab(字符串表)

    如图1,存放的是

    SimpleSection.c.static_var.1594.static_var2.1595.global_init_var.global_uninit_var.func1.printf.main


    8、Section Table

    使用命令,readelf -S SimpleSection.o,得到下图:

Linux系统--ELF文件之可重定位文件(Relocatable file)解析_第6张图片

                           图 7

    这就解释了图1,为什么要那么画。

    Offset表示段偏移,Size表示段大小。

    Type,PROGBITS表示段,NOBITS表示不占空间,.RELA表示重定位段,STRTAB表示字符串表,SYMTAB表示符号表。

    EntSize表示如果段中有重复的内容,则表示重复内容大小。比如下面要介绍的符号表就是重复内容组成的。

    在TYPE为RELA时,Link表示该段所使用的相应符号表在段表中,本例中为11。Info表示该重定位表所作用的段在段表中的下标。.rela.text为1,.rela.eh_frame为8。    


    9、.symtab(符号表)

    使用命令,readelf -s SimpleSection.o,得到下图:

Linux系统--ELF文件之可重定位文件(Relocatable file)解析_第7张图片

                              图 8

    Name,表示字符串在字符串表中的下标;


    Ndx,SimpleSection.c为ABS,global_uninit_var为COM,表示这个变量是强引用或者弱引用,目前即不在.data段中,也不在.bss段中,等待链接时会确定。

    printf为UND,表示没有定义,即引用了外部的函数。

    global_init_var,NDX为3,表示在.data中,其余类似。表示符号所在的段在段表中的下标;参考图 7。


    Bind GLOBAL表示可以被外部引用或者引用外部的函数和变量。

    TYPE为OBJECT表示对象,FUNC表示函数,SECTION表示段,FILE表示文件,printf为NOTYPE,表示没有定义,是引用外部函数。

    SIZE表示大小。

    Value表示在本段中的偏移,比如static_var.1594表示在.data段中的偏移为4。 main在.data段中的偏移为21。


    最后介绍个命令,nm SimpleSection.o,结果如下:

Linux系统--ELF文件之可重定位文件(Relocatable file)解析_第8张图片

    可以看出示所有可以被外部引用或者引用外部的函数和变量。

    T表示text;D和d表示data;b表示bss,C表示Common,U表示Undef。

    程序中的非静态局部变量即不在数据段也不在代码段,可能在堆栈段。


    至此,所有段都分析完了。

你可能感兴趣的:(Linux,linux,ELF,可重定位文件)