全部博文(33)
分类: Android平台
2014-03-11 14:58:35
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:
今天要讨论的是一个问题,是如果一个EXE file(即PIE为false的时候Build出来的File),,放在4.1系统上运行的时候,debuggerd backtrace是存在问题的(Android系统上Native 发生Exception的时候,debuggerd会接手处理后事)。
以下面这个简单的测试用例来看
如果在4.1之前的系统,发生native exception,
Debuggerd会正常dump出backtrace;点击(此处)折叠或打开
- #include <stdio.h>
- #include <stdlib.h>
- static void generateException()
- {
- int *pointer = NULL;
- *pointer = 0x1234;
- }
- int main(int argc,char* argv[])
- {
- printf("Main starts...");
- generateException();
- printf("Main exits...");
- return 0;
- }
下面是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信息的。