gcc的编译过程

举报
黄生 发表于 2022/12/22 21:07:57 2022/12/22
【摘要】 Pwn在俚语中代表:攻破、获取权限。由own这个词引申而来。在CTF夺旗赛中代表溢出类的题目。//file: h.c#include <stdio.h>int main(){ printf("hi,world\n");}从一个C程序的编译开始看起gcc h.c -o h -save-temps --verbose /usr/libexec/gcc/x86_64-redhat-linux/4...

Pwn在俚语中代表:攻破、获取权限。由own这个词引申而来。
CTF夺旗赛中代表溢出类的题目。

//file: h.c
#include <stdio.h>
int main(){
  printf("hi,world\n");
}

从一个C程序的编译开始看起

gcc h.c -o h -save-temps --verbose

 /usr/libexec/gcc/x86_64-redhat-linux/4.8.5/cc1 -E -quiet -v h.c -mtune=generic -march=x86-64 -fpch-preprocess -o h.i
 /usr/libexec/gcc/x86_64-redhat-linux/4.8.5/cc1 -fpreprocessed h.i -quiet -dumpbase h.c -mtune=generic -march=x86-64 -auxbase h -version -o h.s

 as -v --64 -o h.o h.s
 /usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o h /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../.. h.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o


1. 预处理 -E ;递归处理#include, 展开#define 宏定义,处理预处理指令#if等,.i文件还是比较难看明白的。
2. 编译 -S 包含词法分析、语法分析、语义分析、生成汇编代码;编译阶段生成了汇编代码.s文件,有说gcc将printf优化为puts,但我这边没有碰到
gcc -S h.i -o h2.s -masm=intel -fno-asynchronous-unwind-tables
gcc默认使用AT&T格式的汇编语言,可以指定为我们熟悉的intel格式,fno-async...用于生成没有cfi宏的汇编指令,提高可读性。
3. 汇编
汇编器根据汇编指令与机器指令的对照表进行翻译,将.s汇编成目标文件.o
此时.o是一个Relocatable File

[root@ecs-d589 gcc]# file h.o
h.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

[root@ecs-d589 gcc]# objdump -sd h.o -M intel

h.o:     file format elf64-x86-64

Contents of section .text:
 0000 554889e5 bf000000 00b80000 0000e800  UH..............
 0010 000000b8 00000000 5dc3               ........].

Contents of section .rodata: #还没有链接,所以对象中符号的虚拟地址没有确定,比如字符串的地址是0
 0000 68692c20 776f726c 6400               hi, world.

Contents of section .comment:
 0000 00474343 3a202847 4e552920 382e352e  .GCC: (GNU) 8.5.
 0010 30203230 32313035 31342028 52656420  0 20210514 (Red
 0020 48617420 382e352e 302d3133 2900      Hat 8.5.0-13).
Contents of section .eh_frame:
 0000 14000000 00000000 017a5200 01781001  .........zR..x..
 0010 1b0c0708 90010000 1c000000 1c000000  ................
 0020 00000000 1a000000 00410e10 8602430d  .........A....C.
 0030 06550c07 08000000                    .U......

Disassembly of section .text:

0000000000000000 <main>:
   0:   55                      push   rbp
   1:   48 89 e5                mov    rbp,rsp
   4:   bf 00 00 00 00          mov    edi,0x0
   9:   b8 00 00 00 00          mov    eax,0x0
   e:   e8 00 00 00 00          call   13 <main+0x13>
  13:   b8 00 00 00 00          mov    eax,0x0
  18:   5d                      pop    rbp
  19:   c3                      ret


yum install glibc-static
[root@ecs-d589 ~]#gcc h.o -o hs -static

[root@ecs-d589 gcc]# file hs
hs: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=fa343358607174281203fbfbf1ac49f14017b254, not stripped, too many notes (256)

使用相同的objdump,内容输出相当多

Contents of section .rodata:
 47e6a0 01000200 00000000 00000000 00000000  ................
 47e6b0 68692c20 776f726c 64000000 00000000  hi, world.......
 47e6c0 b328f8ff d528f8ff da28f8ff ed28f8ff  .(...(...(...(..

0000000000400ac5 <main>:
  400ac5:   55                      push   rbp
  400ac6:   48 89 e5                mov    rbp,rsp
  400ac9:   bf b0 e6 47 00          mov    edi,0x47e6b0
  400ace:   b8 00 00 00 00          mov    eax,0x0
  400ad3:   e8 a8 81 00 00          call   408c80 <_IO_printf>
  400ad8:   b8 00 00 00 00          mov    eax,0x0
  400add:   5d                      pop    rbp
  400ade:   c3                      ret
  400adf:   90                      nop

0000000000408c80 <_IO_printf>:
  408c80:   f3 0f 1e fa             endbr64
  408c84:   48 81 ec d8 00 00 00    sub    rsp,0xd8
  408c8b:   48 89 74 24 28          mov    QWORD PTR [rsp+0x28],rsi
  408c90:   48 89 54 24 30          mov    QWORD PTR [rsp+0x30],rdx
  408c95:   48 89 4c 24 38          mov    QWORD PTR [rsp+0x38],rcx
  408c9a:   4c 89 44 24 40          mov    QWORD PTR [rsp+0x40],r8
  408c9f:   4c 89 4c 24 48          mov    QWORD PTR [rsp+0x48],r9
  408ca4:   84 c0                   test   al,al
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。