android demo 的only position independent executables (PIE) are supported错误与GCC中的pie和fpie选项

在android 系统中,./ReadWriteProc.out  ./fanbingbing.jpg  ./fanbingbing.jpg                         <
"./ReadWriteProc.out": error: only position independent executables (PIE) are supported.

需要在编译中,设置-pie -fPIE flag。

下面是转发的博客内容,详细的描述了pie和fpie

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值