如何编译缺少符号的 C 程序?

逆向工程 小精灵 符号 海湾合作委员会
2021-07-10 09:44:28

瑞恩“elfmaster”奥尼尔的学习 Linux 二进制分析中在第 33 页,作者编译了一个带有符号引用且没有定义的程序,

我们来看一下源码:

_start()
  {
    foo();
  }

我们看到它调用了 foo() 函数。但是, foo() 函数并不直接位于该源代码文件中;因此,在编译时,将创建一个重定位条目,这是以后满足符号引用所必需的:

$ objdump -d obj1.o
obj1.o:
file format elf32-i386
Disassembly of section .text:
00000000 <func>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 08 sub $0x8,%esp
6: e8 fc ff ff ff call 7 <func+0x7>
b: c9 leave
c: c3 ret

**即使更改_start() {}void start() {},我使用什么标志来编译相同的东西?当我尝试时,我得到..

gcc -nostdlib app.c -o test
app.c: In function ‘_start’:
app.c:3:3: warning: implicit declaration of function ‘foo’ [-Wimplicit-function-declaration]
   foo();
   ^~~
/tmp/ccMBITVZ.o: In function `_start':
app.c:(.text+0xa): undefined reference to `foo'
collect2: error: ld returned 1 exit status
1个回答

像这样编译源代码文件还涉及调用链接器——请记住,“gcc”程序只是编译器前端程序,它根据需要调用预处理器、编译器传递、汇编器和链接器。

您可以使用“-c”编译器选项获取目标文件“app.o”,如下所示:

gcc -nostdlib -c app.c -o app.o

使用“-c”命令编译器在生成目标文件后停止,从而不调用链接器。要生成可执行的 ELF 文件,您必须单独调用链接器(app.o 是默认输出文件名,因此可以省略“-o app.o”参数)。