2025年3月24日 星期一 甲辰(龙)年 月廿三 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 编译原理

关于Linux下gcc 编译 C 源文件时,生成的是Shared object file而不是Executable file

时间:07-30来源:作者:点击数:17

最近在Debian下写C时,发现用readelf命令查看编译后的可执行文件类型时,发现文件类型是DYN (Shared object file),而不是EXEC (Executable file)。

  • -> % readelf -h a.out
  • 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: DYN (Shared object file)
  • Machine: Advanced Micro Devices X86-64
  • Version: 0x1
  • Entry point address: 0x580
  • Start of program headers: 64 (bytes into file)
  • Start of section headers: 6656 (bytes into file)
  • Flags: 0x0
  • Size of this header: 64 (bytes)
  • Size of program headers: 56 (bytes)
  • Number of program headers: 9
  • Size of section headers: 64 (bytes)
  • Number of section headers: 31
  • Section header string table index: 30

多方查找,发现gcc默认加了

  • --enable-default-pie
选项

  • -> % gcc -v
  • Using built-in specs.
  • COLLECT_GCC=gcc
  • COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
  • Target: x86_64-linux-gnu
  • Configured with: ../src/configure -v --with-pkgversion='Debian 6.3.0-18+deb9u1' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
  • Thread model: posix
  • gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)

Position-Independent-Executable是Binutils,glibc和gcc的一个功能,能用来创建介于共享库和通常可执行代码之间的代码–能像共享库一样可重分配地址的程序,这种程序必须连接到Scrt1.o。标准的可执行程序需要固定的地址,并且只有被装载到这个地址时,程序才能正确执行。PIE能使程序像共享库一样在主存任何位置装载,这需要将程序编译成位置无关,并链接为ELF共享对象。

引入PIE的原因是让程序能装载在随机的地址,通常情况下,内核都在固定的地址运行,如果能改用位置无关,那攻击者就很难借助系统中的可执行码实施攻击了。类似缓冲区溢出之类的攻击将无法实施。而且这种安全提升的代价很小

因此,可以加上-no-pie 禁用掉该默认选项:

  • -> % readelf -h a.out
  • 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: 0x400450
  • Start of program headers: 64 (bytes into file)
  • Start of section headers: 6480 (bytes into file)
  • Flags: 0x0
  • Size of this header: 64 (bytes)
  • Size of program headers: 56 (bytes)
  • Number of program headers: 9
  • Size of section headers: 64 (bytes)
  • Number of section headers: 30
  • Section header string table index: 29

于是文件类型又变成了EXEC (Executable file)。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐