Dinamikusból statikusba

Fórumok

Van egy bináris alkalmazásom - aminek nincs meg a forrása -, amely a mai szokásoknak megfelelően egymillió poncsót használ (.so) - legalábbis ldd szerint. Én viszont szeretnék belőle statikusat csinálni. (Ezzel pl. elérve azt, hogy a ma épp még támogatott rendszerre írt alkalmazás 30 év múlva is futhasson az akkori támogatott rendszeren, még akkor is, ha az alkalmazás eredeti fejlesztője rég megszünteti az alkalmazást.)

Ennek mi a menete? Van-e hozzá eszköz (pl: d2s lo lo.static - stílusban), vagy valami nem túl bonyolult vagy épp nagyon bonyolult módon lehet megcsinálni. De legfőképp hogyan? (Eddig az ld scriptek írásától megkímélt az ég, és nagyon szeretném, ha erre  most se kerülne sor - mondjuk mert más már megírta.)

A környezet értelemszerűen FreeBSD (ma már clang-gal, mint alapértelmezett fordítókörnyezettel), de értelemszerűen linuxos, GCC-s megoldás is lehet segítség.

Hozzászólások

Én olyant láttam hogy LD_PRELOAD=/opt/app/libs /opt/app/app
Ki is rázott a hideg tőle :)

Mi vele a baj ?
start.sh:

#!/usr/bin/env bash

basedir="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"

dirname='current'

export QT_PLUGIN_PATH="$basedir/$dirname/plugins"
export LD_LIBRARY_PATH="$basedir/$dirname/libs"
# export QT_DEBUG_PLUGINS=1

"$basedir/$dirname/server" "$@" --nogui -platform offscreen

Nem tudom statikusan fordítani a licens miatt ezért én is ezt használom. A current/libs alatt van minden függőség.

Szerkesztve: 2024. 03. 28., cs – 12:22

Nem hiszem, hogy a forrás (de legalábbis a fordításkori .o objektum fájlok) hiányában ez maradéktalanul megoldható.

Sok múlik azon, miként lett forgatva az a bizonyos bináris, ha pl ELF plt rekordokkal linkeli futás időben (lazy dynamic) és nem ELF interperterrel betöltéskor, akkor az eléggé szopóroller lesz. Ha meg libdl is bejön a képbe, akkor végleg felejtős.
Esetleg egy readelf kimenetet be tudsz illeszteni (különös tekintettel az interpreter és DT_DYNAMIC program header-ökre)?

Otthoni környezetben majd generálok neked ilyeneket.

Addig is, tudnál adni még kulcsszavakat? (Mondjuk a futás közbeni libdl-es betöltés pl. eszembe se jutott.)

Amúgy első körben némi általános infó kéne (mint amilyen ez a plt rekord is volt), mert ennyire sose mélyedtem bele az ELF-be, amikor utoljára ezzel kellett foglalkozzak, akkor COFF és a.out volt használatban (és azokat az infókat is nagyrészt elfelejtettem). Amúgy ami utólag még eszembe jutott, az néhány régebbi játék, ahol érdekességképpen lehetne azzal vacakolni, hogy a mondjuk - 4-es RedHat-hez készített alkalmazást egy VM-be telepített 4-es RH-en ilyen módon átalakítani. Más kérdés, hogy jelenleg nem ez a fő csapásirány. Persze az is lehet, hogy ha értelmetlenül bonyolult, akkor hagyom a francba és csak reménykedek, hogy amíg nekem a szoftver kell (és úgy működik, ahogy), addig megoldható lesz a futtatása e nélkül a borzalom nélkül, :-)

Hát, ami még eszembe jut ilyesmi, az a GOT. Ebből akkor lehet probléma, ha bss-be kerül és a binárisban már csak program header-ök vannak, section-önök nélkül. Ez ugye azért gond, mert ilyenkor mindenképp nullára lesz inicializálva, a statikushoz meg az kéne, hogy előre feltöltsd címekkel, ehhez meg át kell rakni az inicializált szegmensbe, ami section-ök nélkül nem lehetséges. Vagy esetleg a GOT-relatív relokációs rekordokat kell lecserélni sima relokációkra (ez attól is függ, milyen relokációk generálódtak bele).

Egyébként ezt javaslom átböngészésre: https://refspecs.linuxbase.org/elf/x86_64-SysV-psABI.pdf Ebben szépen csoportosítva le van írva minden, jól érthető, és tele van konkrét példákkal.
Ez persze jóval bővebb, mint ami Neked kell, szerintem első nekifutásra elég a Chapter 5. Program Loading and Dynamic Linking-et elolvasni belőle. Ez a legjobb általános infó forrás szvsz.

Én is ilyesmit javasolnék, Snap, docker, stb. Kifelé pont olyan függőségei lesznek, mint ha statikussá alakítanád (ha minden poncsót mellé raksz, akkor szerintem a Linuxot fogja hívogatni csak, amire az az ígéret, hogy nem fogják megtörni). Ha meg a Linux binary API-t is megtörik, akkor jöhet a VM.

Alapvetoen en is a libek archivalasa, docker image meg VM kozul valasztanek.

Igazabol attol is fugg, mik a fuggosegei, meg milyen eroforrasigenye van. Ha pl. valami jatek, ami 3D grafikat hasznal, nehezebb az ugy. Addig minden letezo API torni fog (X, OpenGL), de talan egy akkori gepnek nem fog gondot okozni meg egy VM sem.

Ha GUIt hasznal, de amugy nem nagy dolog, akkor a VM talan a legjobb.

Ha parancssoros, es szinten kisigenyu, valoszinuleg mindegyiket eltennem (vagy mondjuk a VM-et, amibol igeny szerint kesobb is kinyerhetoek a libek).

Ha parancssoros, es durva szamitasokat vegez, talan a libekkel jarsz jobban.

30 evvel szamolsz, szoval ha ugy fog fejlodni, mint 30 evvel ezelottol mostanaig, a kerdes az lesz, hogy egy 1994-es (Win95 elotti) alkalmazast el tudsz-e inditani forras nelkul. A valasz, hogy valoszinuleg igen, ha DOS-os, pl. DOSBOX-ban gond nelkul megy, meg a sebessege is allithato - pl. aminek a fontossagaval akkoriban nem szamoltak. VM-be Win 3.1 is felteheto, csak ossze kell szedni valami abandonware oldalrol telepitot (lehet, hogy a MS is kiadta mar, nem emlekszem).

Sima statikus linkelesben en nem biznek. Mi van, ha atter 5 ev mulva mindenki Waylandre (vagy valami hasonlora), aztan 30 ev mulva ott teker az X-es programod, hogy szeretne csatlakozni az X serveredhez, de mar 20 eve kiszedtek a kompatibilitasi reteget alola?

Esetleg a VM melle egy FreeBSD telepitot is eltennek, hatha valtozik a VM formatuma (vagy kihal az adott gyarto).

A strange game. The only winning move is not to play. How about a nice game of chess?

Mellékes infó: glibc-t gyakorlatilag nem lehet statikusan linkelni. Cserébe kompatibilis az újabb runtime a régebbi glibc-vel fordított binárissal.

Szerkesztve: 2024. 03. 28., cs – 21:18

Anno csinaltam ilyet, de elegge megbizhatatlan volt. A nevere mar nem emlekszem, meg mivel 2000 kornyeken tortent, nem hiszem, hogy hasznalhato lenne.

itt van egy par ajanlas, de ez is bazi regi.

Egy jail-ban összerakni, hogy működjön, aztán frissítés nélkül csak hordozni a jail-t?