Chinaunix首页 | 论坛 | 博客
  • 博客访问: 247664
  • 博文数量: 33
  • 博客积分: 246
  • 博客等级: 二等列兵
  • 技术积分: 918
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-31 16:37
文章分类

全部博文(33)

文章存档

2014年(4)

2013年(7)

2012年(22)

分类: Android平台

2014-03-11 14:58:35

在Android 4.1之后,开始支持PIE,而且默认是PIE,具体请参考Android NDK中的Application.mk:
===========================================

APP_PIE

Starting from Jelly Bean (4.1), Android's dynamic linker supports position-independent executables (PIE), which are built with -fPIE. This flag makes it harder to exploit memory corruption bugs by randomization the location of the code. By default, ndk-build will automatically set this value to 'true' if your project targets android-16 or higher. You may set it manually to either 'true' or 'false'.

IMPORTANT: PIE executables cannot run on Android releases prior to 4.1.

Note that this only applies to executables. It has no effect when building shared or static libraries.
===========================================
话说跟Security有关系,具体请参考Loda大神的一篇博客(btw,之前跟此大神是同事:))
如果在link的时候,如果此选项为true,Build出来为PIE Image,具体可以通过readelf来看;
readelf -h xxxx
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x3198
  Start of program headers:          52 (bytes into file)
  Start of section headers:          193888 (bytes into file)
  Flags:                             0x5000000, Version5 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         8
  Size of section headers:           40 (bytes)
  Number of section headers:         34
  Section header string table index: 33
另外,正如Google Doc提到,如果这个Image放到4.1之前的系统中,是无法正常运行的,在我的手机上,Linker这就会当掉:
 signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00007d68
  r0 b00094c4  r1 2a000134  r2 b0006acc  r3 00007d68
  r4 b00099d0  r5 70000001  r6 00000042  r7 b0009acc
  r8 00000000  r9 00000000  10 00000000  fp 00000000
  ip b0009ac8  sp befb7c28  lr b0005259  pc b0004d1e  cpsr 00000030
          #00  pc b0004d1e  /system/bin/linker
          #01  lr b0005259  /system/bin/linker
Linker在4.1之前不Support PIE,具体请参考Google的Patch: 

Add linker support for PIE

Modify the dynamic linker so that executables can be loaded
at locations other than 0x00000000.

Modify crtbegin* so that non-PIC compilant "thumb interwork
veneers" are not created by the linker.


今天要讨论的是一个问题,是如果一个EXE file(即PIE为false的时候Build出来的File),,放在4.1系统上运行的时候,debuggerd backtrace是存在问题的(Android系统上Native 发生Exception的时候,debuggerd会接手处理后事)。
以下面这个简单的测试用例来看
如果在4.1之前的系统,发生native exception,


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. static void generateException()
  4. {
  5.     int *pointer = NULL;
  6.     *pointer = 0x1234;
  7.     
  8. }

  9. int main(int argc,char* argv[])
  10. {
  11.     printf("Main starts...");

  12.     generateException();

  13.     printf("Main exits...");
  14.     return 0;
  15. }
Debuggerd会正常dump出backtrace;
下面是tombstone;

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'yusu/ztemt73v2/ztemt73v2:2.3.6/GRK39F/eng.mtk70823.1369363976:eng/release-keys'
pid: 1196, tid: 1196  >>> ./SimpleTest <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
 r0 0000000e  r1 12000000  r2 00000000  r3 00001234
 r4 000084a4  r5 00000001  r6 afd41524  r7 bec09cbc
 r8 00000000  r9 00000000  10 00000000  fp bec09c64
 ip 80000000  sp bec09c58  lr 000084cc  pc 00008494  cpsr 00000010
         #00  pc 00008494  /data/gettop/SimpleTest   //使用addr2line可以解析出
         #01  pc 000084c8  /data/gettop/SimpleTest
         #02  pc 00014dfc  /system/lib/libc.so

\lib\obj\local\armeabi>addr2line -e SimpleTest 0x8494
\lib/jni/SimpleTest.cpp:7
\lib\obj\local\armeabi>addr2line -e SimpleTest 0x84c8
\lib/jni/SimpleTest.cpp:15

如果放在4.1之后的系统上,得到的tombstone是:
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'samsung/m0xx/m0:4.1.1/JRO03C/I9300XXDLIB:user/release-keys'
Revision: '12'
pid: 27536, tid: 27536, name: SimpleTest  >>> ./SimpleTest <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
    r0 0000000e  r1 00009b28  r2 00000000  r3 00001234
    r4 000084a4  r5 be943ae4  r6 00000001  r7 be943aec
    r8 00000000  r9 00000000  sl 00000000  fp be943a9c
    ip 0000002e  sp be943a90  lr 000084cc  pc 00008494  cpsr 60030010
    d0  617473206e696172  d1  0000000000000074
    d2  0000000000000073  d3  000000000000002e
    d4  0000000000000000  d5  0000000000000000
    d6  0000000000000000  d7  ee1ab3ec00000000
    d8  0000000000000000  d9  0000000000000000
    d10 0000000000000000  d11 0000000000000000
    d12 0000000000000000  d13 0000000000000000
    d14 0000000000000000  d15 0000000000000000
    d16 c1b1e54c14e49ba6  d17 3f50624dd2f1a9fc
    d18 41c4b42231800000  d19 0000000000000000
    d20 0000000000000000  d21 0000000000000000
    d22 0000000000000000  d23 0000000000000000
    d24 0000000000000000  d25 0000000000000000
    d26 0000000000000000  d27 0000000000000000
    d28 0000000000000000  d29 0000000000000000
    d30 0000000000000000  d31 0000000000000000
    scr 00000010


backtrace:
    #00  pc 00000494  /data/gettop/SimpleTest         //Debuggerd dump出的是一个Offset。
                                                     //可能是debuggerd将Image看做了DYN (Shared object file)
                                                     //具体请看platform/system/core/libcorkscrew/backtrace.c

    #01  pc 000004c8  /data/gettop/SimpleTest
    #02  pc 0001272b  /system/lib/libc.so (__libc_init+38)
    #03  pc 0000043c  /data/gettop/SimpleTest

readelf -h SimpleTest
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x83e4                           
  Start of program headers:          52 (bytes into file)
  Start of section headers:          38196 (bytes into file)
  Flags:                             0x5000000, Version5 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         8
  Size of section headers:           40 (bytes)
  Number of section headers:         33
  Section header string table index: 32

这样再去使用addr2line解析symbol是无法得到debug信息的。

阅读(5083) | 评论(0) | 转发(0) |
0

上一篇:安装apk时选择错误的CPU_ABI

下一篇:没有了

给主人留下些什么吧!~~