PIE程序的入口点地址

时间:2018-03-16 21:52:25

标签: linker elf position-independent-code

如何知道Linux / Android上PIE程序的实际入口点地址?

我可以使用readelf -l读取入口点地址,但对于编译并与-pie-fPIE链接的精灵,实际入口点地址将与之不同。我怎样才能在运行时获得这样的地址?也就是说,知道程序加载到内存的位置。

1 个答案:

答案 0 :(得分:2)

程序的入口点始终可用作地址 符号_start

<强>的main.c

#include <stdio.h>

extern char _start;
int main()
{
    printf("&_start = %p\n",&_start);
    return 0;
}

编译并链接-no-pie

$ gcc -no-pie main.c

然后我们看到:

$ nm a.out | grep '_start'
0000000000601030 B __bss_start
0000000000601020 D __data_start
0000000000601020 W data_start
                 w __gmon_start__
0000000000600e10 t __init_array_start
                 U __libc_start_main@@GLIBC_2.2.5
0000000000400400 T _start
          ^^^^^^^^^^^^^^^

$ readelf -h a.out | grep Entry
  Entry point address:               0x400400

和:

$ ./a.out 
&_start = 0x400400

编译并链接-pie

$ gcc -pie main.c

然后我们看到:

$ nm a.out | grep '_start'
0000000000201010 B __bss_start
0000000000201000 D __data_start
0000000000201000 W data_start
                 w __gmon_start__
0000000000200db8 t __init_array_start
                 U __libc_start_main@@GLIBC_2.2.5
0000000000000540 T _start
             ^^^^^^^^^^^^

$ readelf -h a.out | grep Entry
  Entry point address:               0x540

$ ./a.out 
&_start = 0x560a8dc5e540
                     ^^^

因此PIE程序在其名义入口点0x540加上0x560a8dc5e000输入。