LINUX.ORG.RU

Как определить собраны ли исполняемые файлы с реализацией технологии PIE или нет

 , ,


0

2

Дано — ОС FreeBSD 14.1-current amd64

В ports/Mk/bsd.serenity.mk есть строка  
WITH_PIE=	yes
Собираю порт sysutils/kdialog и сохраняю отдельно.

В файле  ports/Mk/bsd.serenity.mk в строку WITHOUT_PIE_PORTS=	добавляю sysutils/kdialog

Собираю заново и сравниваю с предыдущим вариантом — в папке stage все файлы одинаковы. Повторяю тоже самое для пакета math/kcalc. Тут тоже все файлы одинаковы, кроме файлов index.cache.bz2 в stage/usr/local/share/doc/HTML/<ca,de,en,…,uk>.

Вот и возник вопрос — так собираются ли файлы с реализацией технологии PIE или нет, если их значение не меняется от указания собирать с PIE или без.

Пошёл далее - такое же сделал с пакетом editors/vim — тут бинарные файлы отличаются друг от друга, более того для варианта, что собирался с поддержкой PIE технологии получаю  
$ readelf -a vim |grep PIE
0x000000006ffffffb FLAGS_1              PIE

Под Linux можно было бы радоваться, но под FreeBSD не всё так просто (если верить результатам гугления) — и я решил проверить ещё.

Сделал программу helloworld и собрал её с ключиком -fPIE и с ключом -fno-PIE. Результат просмотрел с помощью readelf — в обоих случаях флаг PIE не установлен, хотя дизассемлирование и просмотр кода явно показывает отличие в коде.

00000000002017b0 <main>:
  2017b0: 55                           	push	rbp
  2017b1: 48 89 e5                     	mov	rbp, rsp
  2017b4: 48 83 ec 10                  	sub	rsp, 0x10
  2017b8: 48 8d 7d f0                  	lea	rdi, [rbp - 0x10]
  2017bc: e8 1f 01 00 00               	call	0x2018e0 <time@plt>
  2017c1: bf 99 05 20 00               	mov	edi, 0x200599
  2017c6: e8 25 01 00 00               	call	0x2018f0 <puts@plt>
  2017cb: bf 99 05 20 00               	mov	edi, 0x200599

======

00000000002017b0 <main>:
  2017b0: 55                           	push	rbp
  2017b1: 48 89 e5                     	mov	rbp, rsp
  2017b4: 53                           	push	rbx
  2017b5: 48 83 ec 18                  	sub	rsp, 0x18
  2017b9: 48 8d 7d e8                  	lea	rdi, [rbp - 0x18]
  2017bd: e8 0e 01 00 00               	call	0x2018d0 <time@plt>
  2017c2: 48 8d 1d d0 ed ff ff         	lea	rbx, [rip - 0x1230]     # 0x200599 <.rodata+0x1>
  2017c9: 48 89 df                     	mov	rdi, rbx
Но может ли это отличие быть однозначно показывать на использование технологии PIE — не ясно.  

Пробовал разобраться с помощью пакета radare2 — но там тоже самое, что и с readelf, objdump и elfdump — сплошная неопределённость — не ясно собран бинарник с реализацией технологии PIE или нет



Последнее исправление: le_cha_sever (всего исправлений: 1)

Пробовал разобраться с помощью пакета radare2 — но там тоже самое, что и с readelf, objdump и elfdump — сплошная неопределённость — не ясно собран бинарник с реализацией технологии PIE или нет

Не знаю как на FreeBSD но в Linux бинарник без PIC имеет тип «executable» («EXEC (Executable file)»), а с PIC тип «shared object» («DYN (Shared object file)»).

Также без PIC адрес «Entry point» начинается примерно с 0x400000, тогда как с PIC с 0x0.

V1KT0P ★★
()
Ответ на: комментарий от router

В линуксе в заголовке elf файла есть бит, который показывает про поддержку PIE. Во FreeBSD нет такого. По крайней мере я такую информацию находил. К сожалению file не помог:

$ file ./helloworld
./helloworld: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 14.1, FreeBSD-style, with debug_info, not stripped
$ file ./helloworldPIE
./helloworldPIE: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 14.1, FreeBSD-style, with debug_info, not stripped
le_cha_sever
() автор топика
Ответ на: комментарий от le_cha_sever

ЕМНИП, это одно и то же, только с разных точек зрения

position-independent code is generally called PIC and programs that all code/data are position-independent are called position-independent executable(PIE)

router ★★★★★
()
Ответ на: комментарий от anonymous

checksec нет, но есть readelf, на основе которого checksec и работает. Но, повторюсь, «В линуксе в заголовке elf файла есть бит, который показывает про поддержку PIE. Во FreeBSD нет такого»

le_cha_sever
() автор топика

в обоих случаях флаг PIE не установлен

Репорт во FreeBSD делал? Очевидно что флаг должен быть установлен. Если они по каким-то причинам это не делают, то было бы интересно услышать их аргументацию.

EXL ★★★★★
()
Ответ на: комментарий от le_cha_sever

Похоже ты просто не правильно компилируешь, так как у меня все показывает правильно(даже понятнее чем на Linux: executable и pie executable соответственно):

user@:~/share $ gcc -no-pie -o helloworld_nopie helloworld.c
user@:~/share $ gcc -fPIE -pie -o helloworld_pie helloworld.c
user@:~/share $ file helloworld_nopie
helloworld_nopie: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 14.1, FreeBSD-style, with debug_info, not stripped
user@:~/share $ file helloworld_pie
helloworld_pie: ELF 64-bit LSB pie executable, x86-64, version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, for FreeBSD 14.1, FreeBSD-style, with debug_info, not stripped
user@:~/share $ readelf -h helloworld_nopie
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 09 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            FreeBSD
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices x86-64
  Version:                           0x1
  Entry point address:               0x400490
  Start of program headers:          64 (bytes into file)
  Start of section headers:          6032 (bytes into file)
  Flags:                             0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         8
  Size of section headers:           64 (bytes)
  Number of section headers:         34
  Section header string table index: 33
user@:~/share $ readelf -h helloworld_pie
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 09 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            FreeBSD
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices x86-64
  Version:                           0x1
  Entry point address:               0x550
  Start of program headers:          64 (bytes into file)
  Start of section headers:          6336 (bytes into file)
  Flags:                             0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         8
  Size of section headers:           64 (bytes)
  Number of section headers:         35
  Section header string table index: 34

V1KT0P ★★
()
Ответ на: комментарий от le_cha_sever

Кстати, почитал скрипт анонимуса и вспомнил, что в нашем линуксе есть как минимум 2 разных readelf (binutils) и eu-readelf (elfutils). И у них сильно разные возможности и поведение (особенно заметно, например, на crash dump)

Может и во фряхе тоже?

router ★★★★★
()
Ответ на: комментарий от V1KT0P

СПАСИБО! Ключ -pie нужен, чтобы file показывал pie ex…

По поводу readelf (binutils) и eu-readelf (elfutils) - смотрел оба, да разные возможности имеют, но в данном случае не помогли

le_cha_sever
() автор топика