Адрес точки входа программы PIE

Как узнать фактический адрес точки входа программы PIE в Linux/Android?

Я могу прочитать адрес точки входа, используя readelf -l, но для эльфа, скомпилированного и связанного с -pie или -fPIE, фактический адрес точки входа будет отличаться от него. Как я могу получить такой адрес во время выполнения? То есть зная, где программа загружается в память.


person Gabriel    schedule 16.03.2018    source источник


Ответы (1)


Точка входа программы всегда доступна ей как адрес символа _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.

person Mike Kinghan    schedule 17.03.2018