【问题标题】:Entry point address of a PIE programPIE 程序的入口点地址
【发布时间】:2018-03-16 21:52:24
【问题描述】:

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

我可以使用readelf -l读取入口点地址,但是对于使用-pie-fPIE编译和链接的elf,实际的入口点地址会有所不同。如何在运行时获得这样的地址?也就是说,知道程序在哪里加载到内存中。

【问题讨论】:

    标签: linker elf position-independent-code


    【解决方案1】:

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

    ma​​in.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 进入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-04
      相关资源
      最近更新 更多