Адрес точки входа программы PIE
Как узнать фактический адрес точки входа программы PIE в Linux/Android?
Я могу прочитать адрес точки входа, используя readelf -l
, но для эльфа, скомпилированного и связанного с -pie
или же -fPIE
, фактический адрес точки входа будет отличаться от него. Как я могу получить такой адрес во время выполнения? То есть, зная, где программа загружена в память.
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
,