(Ne)zabudnute schopnosti: qemu + binfmt_misc + chroot

29.05.2011 04:26 | kabel

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
Argumenty -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
dostaneme samozrejme hlasenie o nepodporovanom binarnom formate, pretoze moja platforma mi ARM binarku nespusti. A teraz je cas nato, aby sme vyuzili binfmt_misc.

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
a potom mu povedat, aby ARM ELF binarky spustal skrz 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
Po uspesnom vykonani tohto prikazu by sa Little Endian ELF binarne subory mali interpretovat skrz 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
a voala - nejde to. Preco? binfmt_misc totiz pri spustani interpretera povazuje za korenovy adresar korenovy adresar procesu volajuceho execve. Kedze execve je volane z procesu 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
Nakoniec este musime zabezpecit, aby linker nasiel potrebne kniznice (najjedoduchsie vsetko z /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
Mission completed.

    • Re: Zabudnute schopnosti: qemu + binfmt_misc + chroot 31.05.2011 | 16:46
      Avatar blackhole_bwpow   Používateľ

      Toto nie su zabudnute schopnosti. To su skor doteraz neobjavene.

      Prisiel som, videl som, hmm...

      Prisiel som, videl som, hmm...
      • Re: Zabudnute schopnosti: qemu + binfmt_misc + chroot 31.05.2011 | 20:01
        Avatar kabel   Používateľ

        Titulok a anotacia zmenene