Mierne ozivenie ventYlovych Zabudnutych schopnosti, aj ked tentokrat skor doteraz neobjavene schopnosti, vyuzivajuce najma genialitu cloveka, ktory sa vola Fabrice Bellard. Jednym z jeho najvacsich vytvorov je snad vsetkym znamy QEMU, najefektivnejsi, najportabilnejsi a najviac slobodny procesorovy emulator (najdite si dokazy na tieto tvrdenia sami).
Okrem toho, ze QEMU vie emulovat to mnozstvo zariadeni, ktore vie emulovat, vie emulovat aj user space prostredia (Linuxove snad na vsetkych platformach a BSD na niektorych). To znamena, ze vieme QEMU pouzit ako interpreter na ELF binarne subory skompilovane pre inu platformu, ako tu, na ktorej teraz bezime (s tym, ze systemove volania su samozrejme volane kernelu, nie emulovane).
Napriklad mame ELF binarny subor program
skompilovany pre ARM, konkretne procesor cortex-a8:
qemu-arm -cpu cortex-a8 program -arg1 -arg2
-cpu cortex-a8
mozeme samozrejme vynechat, tymto QEMU povieme iba to, aby podporoval spravanie specificke pre procesor cortex-a8 (vyhodne pouzit vtedy, ked bola binarka skompilovana tak, aby vyuzivala spravanie specificke pre tento procesor - napriklad gcc-cku to poviem skrz -mcpu=cortex-a8
).
Predstavme si teraz, ze mame image root filesystemu nejakeho ARM zariadenia (napriklad u mna to je image Meego systemu pre Nokiu N900 odtial). Tento image mame mountnuty napriklad na /meego
a potrebujeme sa chrootnut do tohoto systemu (dovod si najdite sami). Ked urobime
chroot /meego
binfmt_misc je cast Linuxoveho virtualneho suboroveho systemu umoznujuca spustat subory nejakeho (uzivatelom urceneho) typu skrz interpreter. To znamena, ze zavolanim systemoveho volania execve na tento subor sa v skutocnosti spusti uzivatelnom definovany program, ktoremu bude predana informacia o tom, ktoryze to subor mal byt spusteny. Najprv si binfmt_misc musime zapnut (ak ho zapnuty nemame):
mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
qemu-arm
:cd /proc/sys/fs/binfmt_misc
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm:' >register
qemu-arm
. (Ak by niekto chcel interpreteru predat aj nejake argumenty navyse, napriklad hore spominanu specifikaciu konkretneho procesora, riesenie je vytvorit skript, ktory spusti interpreter s danymi argumentami, a binfmt_misc nastavit tak, aby spustal tento skript.)
Teraz mozme s chutou vykonat
chroot /meego
chroot
az PO samotnej zmene korenoveho adresara, binarka /usr/bin/qemu-arm
sa hlada uz v korenovom adresari /meego
a tam sa samozrejme nenajde (za predpokladu, ze tam nie je). Mohli by sme teda skopirovat binarku /usr/bin/qemu-arm
do /meego/usr/bin
, a s nou aj vsetky potrebne kniznice, ktore tato binarka potrebuje (co by mala byt ista podmnozina kniznic z /lib
, respektive /lib64
na x86_64).
UPDATE: Kniznice, na ktorych je qemu-arm
zavisla, zistime takto:
ldd /usr/bin/qemu-arm
Ak su vsetky podporne kniznice pre
qemu-arm
v /lib64
, riesenie je jednoduche (skopirovat cele /lib64
do /meego
). Ak su ale podporne kniznice v /lib
, s najvacsou pravdepodobnostou ich do /meego/lib
skopirovat nemozme, pretoze by prepisali ARM kniznice.
Riesenie
Skopirujeme si binarku qemu-arm
do /meego
a editujeme ju editorom, ktory zachovava binarne znaky (napriklad mcedit
). Hladame prvy vyskyt retazca ld-linux
. Najdeme nieco ako /lib64/ld-linux-x86-64.so.2
, a okolo toho nulove bajty. Tento retazec je absolutna cesta k suboru, ktory sa ma pouzit ako linker - program, ktory nacita vsetky potrebne kniznice. V jeho ceste urobime mensiu zmenu. Zmenime napriklad druhe lomitko za pomlcku a dostaneme /lib64-ld-linux-x86-64.so.2
. Tuto zmenu ulozime. Nasledne skopirujeme subor /lib64/ld-linux-x86-64.so.2
(v pripade, ze je to symbolicky odkaz na iny subor, narpiklad u mna na ld-2.13.so
, tak skopirujeme cielovy subor, nie symbolicky odkaz) do /meego/lib64-ld-linux-x86-64.so.2
. Po spusteny binarky qemu-arm
v koreni /meego
sa teraz pouzije spravny linker. binfmt_misc musi vediet o tom, ze uz nechceme ako interpreter /usr/bin/qemu-arm
, ale /qemu-arm
, preto:
cd /proc/sys/fs/binfmt_misc
echo -1 >arm
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/qemu-arm:' >register
/lib
okrem podadresarov). Skopirujeme ich do /meego/libHOST
. Ako bude linker vediet, ze ich ma hladat v tomto adresari? Povieme mu to cez LD_LIBRARY_PATH
, a to tak, ze chroot
spustime nasledovne:LD_LIBRARY_PATH=/libHOST chroot /meego
Toto nie su zabudnute schopnosti. To su skor doteraz neobjavene.
Prisiel som, videl som, hmm...
Titulok a anotacia zmenene