返回介绍

5. 目标文件

发布于 2024-10-12 21:58:07 字数 5418 浏览 0 评论 0 收藏 0

现在流行的可执行文件(executable)格式基本都是 COFF(common file format)变种,如 Windows/PE、Linux/ELF 等。

$ file ./test

ELF 64-bit LSB executable, x86-64, version 1 (SYSV), 
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, 
for GNU/Linux 3.2.0, with debug_info, not stripped

示例:

#include <stdio.h>

int X = 1;
int Y;

void test()
{
    char *s = "X = %d, Y = %d\n";
    printf(s, X, Y);    
}

int main (int argc, char *argv[])
{
    test();
    return 0;
}
$ gcc -g -O2 -no-pie -o ./test main.c
$ readelf -h ./test

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x401080
  Start of program headers:          64 (bytes into file)
  Start of section headers:          18040 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         38
  Section header string table index: 37

目标文件由机器代码、数据、符号表、调试信息、字符串等内容组成。信息按不同属性,以段(section)方式分类存储。如果将整个文件看作一个数据库(database),那么每个段就相当于一个数据表(table)。

  • .text : 代码段。
  • .data : 已初始化的全局变量和静态局部变量(值存储)。
  • .bss : 未初始化的全局变量和静态局部变量(分配零值内存,但不占用文件空间)。
  • .rodata : 只读数据(比如字符串字面量和 const 修饰的只读变量)。
  • .symtab : 符号表(定义和引用的函数、全局变量信息)。
  • .debug : 调试信息(-g)。
$ size ./test

   text	   data	    bss	    dec	    hex	filename
   1370	    548	     12	   1930	    78a	./test
$ readelf -S ./test

There are 38 section headers, starting at offset 0x4678:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [15] .text             PROGBITS         0000000000401050  00001050
       00000000000001c5  0000000000000000  AX       0     0     16
  [17] .rodata           PROGBITS         0000000000402000  00002000
       0000000000000014  0000000000000000   A       0     0     4
  [25] .data             PROGBITS         0000000000404020  00003020
       0000000000000014  0000000000000000  WA       0     0     8
  [26] .bss              NOBITS           0000000000404034  00003034
       000000000000000c  0000000000000000  WA       0     0     4
  [29] .debug_info       PROGBITS         0000000000000000  0000309e
       000000000000048d  0000000000000000           0     0     1
  [35] .symtab           SYMTAB           0000000000000000  00003c48
       00000000000006d8  0000000000000018          36    52     8
       
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

查看符号表:

$ readelf -s ./test

Symbol table '.symtab' contains 73 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
    35: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main.c
    54: 0000000000404030     4 OBJECT  GLOBAL DEFAULT   25 X
    63: 0000000000404038     4 OBJECT  GLOBAL DEFAULT   26 Y
    68: 0000000000401050    46 FUNC    GLOBAL DEFAULT   15 main
    72: 0000000000401170    35 FUNC    GLOBAL DEFAULT   15 test

查看只读数据:

$ readelf -x .rodata ./test

Hex dump of section '.rodata':
  0x00402000 01000200 58203d20 25642c20 59203d20 ....X = %d, Y = 
  0x00402010 25640a00                            %d..

查看代码:

$ readelf -x .text ./test

Hex dump of section '.text':
  0x00401050 f30f1efa 4883ec08 8b0dda2f 00008b15 ....H....../....
  0x00401060 cc2f0000 31c0488d 35970f00 00bf0100 ./..1.H.5.......
  0x00401070 0000e8c9 ffffff31 c04883c4 08c36690 .......1.H....f.
  0x00401080 f30f1efa 31ed4989 d15e4889 e24883e4 ....1.I..^H..H..
  0x00401090 f0505449 c7c01012 400048c7 c1a01140 .PTI....@.H....@
  0x004010a0 0048c7c7 50104000 ff15422f 0000f490 .H..P.@...B/....


$ xxd -s 0x1050 -g 4 -l 100 ./test     // section offset

00001050: f30f1efa 4883ec08 8b0dda2f 00008b15  ....H....../....
00001060: cc2f0000 31c0488d 35970f00 00bf0100  ./..1.H.5.......
00001070: 0000e8c9 ffffff31 c04883c4 08c36690  .......1.H....f.
00001080: f30f1efa 31ed4989 d15e4889 e24883e4  ....1.I..^H..H..
00001090: f0505449 c7c01012 400048c7 c1a01140  .PTI....@.H....@
000010a0: 0048c7c7 50104000 ff15422f 0000f490  .H..P.@...B/....

可用 strip 删除符号表和调试段。使用 GNU 扩展 __attribute__((section("NAME"))) int x; 自定义段。或用 objcopy 将数据嵌入到自定义段内。

$ objcopy --add-section .abc=data.txt --set-section-flags .abc=noload,readonly src dst
$ objcopy --update-section .abc=data2.txt dst            
$ objcopy --rename-section .abc=.demo dst
$ objcopy --remove-section .demo dst

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文