GCC中的pie和fpie选项

http://www.lingcc.com/2010/01/08/10609/

 

GCC中的pie和fpie选项

 

 

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

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

谈到PIE就不得不说说Pax和Grsec内核。这两个东西都是为了构建坚不可摧到安全系统而准备的。PaX是Linux内核安全增强补丁,它能在两方面保证安全性,一是ASLR(Address Space Layout Randomization,地址空间分布随机化),这是一种将所有数据装载到内存时都随机化地址的方式,当使用PIE选项编译应用时,PaX能将应用的地址做随机加法;二是能提供不可执行的内存空间,这样就能使得攻击者放入内存中的恶意代码不可执行。不过PaX官网上能支持的最新内核是2.6.27,已经是一年前的更新了。Grsec也时类似的内核补丁,更新较为频繁能支持最新的2.6.32内核。这两种方式都能将内核完全位置无关,除了Grub和Glibc中无法位置无关的汇编码。

PIE最早由RedHat的人实现,他在连接起上增加了-pie选项,这样使用-fPIE编译的对象就能通过连接器得到位置无关可执行程序。fPIE和fPIC有些不同。可以参考Gcc和Open64中的-fPIC选项.

gcc中的-fpic选项,使用于在目标机支持时,编译共享库时使用。编译出的代码将通过全局偏移表(Global Offset Table)中的常数地址访存,动态装载器将在程序开始执行时解析GOT表项(注意,动态装载器操作系统的一部分,连接器是GCC的一部分).而gcc中的-fPIC选项则是针对某些特殊机型做了特殊处理,比如适合动态链接并能避免超出GOT大小限制之类的错误。而Open64仅仅支持不会导致GOT表溢出的PIC编译。
gcc中的-fpie和-fPIE选项和fpic及fPIC很相似,但不同的是,除了生成为位置无关代码外,还能假定代码是属于本程序。通常这些选项会和GCC链接时的-pie选项一起使用。fPIE选项仅能在编译可执行码时用,不能用于编译库。所以,如果想要PIE的程序,需要你除了在gcc增加-fPIE选项外,还需要在ld时增加-pie选项才能产生这种代码。即gcc -fpie -pie来编译程序。单独使用哪一个都无法达到效果。
你可以使用file命令来查看当前的可执行文件是不是PIE的。

下面是本博编译helloword的显示。可以看出,可执行文件属性从executable变成了shared object.
$ gcc  helloworld.c
$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
$ gcc -fpie -pie helloworld.c
$ file a.out
a.out: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

接下来,我们就能实验了,使用strace命令来查看这两个a.out执行情况了。关于strace命令,可以参考strace命令介绍
在博主电脑上,有PIE时,执行第一个brk(0)系统调用时,返回的地址一直是变化的。而无PIE时,brk(O)系统调用返回地址一直不变。内容太多,不再贴出。

注:
linux系统调用brk():
linux系统内部分配内存的系统调用,malloc()其实也是调用的brk().直接修改堆的大小,返回新内存区域的结束地址。

参考:
http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
http://www.linuxfromscratch.org/hlfs/view/unstable/glibc-2.6/chapter02/pie.html
http://www.gentoo.org/proj/en/hardened/hardened-toolchain.xml
http://www.gentoo.org/proj/en/hardened/pax-quickstart.xml
http://www.kernel.org/doc/man-pages/online/pages/man2/brk.2.html
<Understanding Linux Kernel> 3rd Edition Page32 , Page395

展开阅读全文

没有更多推荐了,返回首页