PB173 - Binární programování Linux VII. Cbezlibc Jiri Slabý Fakulta informatiky Masarykova univerzita 4. 11. 2014 Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 1/15 C a libc « libc se stará o komunikaci s OS (jádrem) • Jádro poskytuje pouze „základní" funkcionalitu • libc poskytuje spoustu nadstaveb o Soubory: fopen, fread, fwrite, fclose, .. . • Síť: getaddrinfo, ntoh*, hton* • Více vláken (libpthread): pthread_* (včetně zamykání) • A spoustu dalšího (celý POSIX), ... Bez libc nic z toho nemáme Jak teď ale např. otevřu soubor? Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 2/ 15 Komunikace s jádrem • Sdílená paměť • Jádro zapisuje, uživatel čte a naopak a V jednom z dalších cvičení • Systémová volání • Podobné jako zavolání funkce • Ale program a jádro běží v jiných kontextech a Přepnutí kontextu • Uložení a změna stavu procesoru • Relativně drahá operace • Uvidíme dnes dále Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 3/ 15 Systémová volání • Volání funkce • Instrukcí procesoru • Závislé na architektuře • Softwarové přerušení (x86_32: číslo 0x80) • Speciální instrukce (x86_32: sysenter, x86_64: syscall) • Demo: implementace syscall z glibc • Systémová volání jsou očíslovaná • Do jednoho registru číslo • Čísla __nr_* definovaná jádrem (pro každou architekturu) 9 sys/syscall.h • Např. (x86_64): __nr_write (1), __nr_exit (60) Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 4/ 15 Úkol libc o úroveň níže O Zavolejte systémová volání a write s nějakým textem • exit O Pomocí funkce syscali z libc • Viz man 2 syscall • První argument: číslo systémového volání 9 Další argumenty: odpovídají už danému volání O Např. syscall(__NR_kill, -1, SIGKILL) O Přeložte a vyzkoušejte Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 5/ 15 C bez libc • Žádné hlavičkové soubory z libc • Jen to, co poskytuje jádro (/usr/inciude/iinux/) • Při linkování: gcc -nostdlib ... • gcc stále může vkládat volání memset apod. Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 6/ 15 Volací konvence Volací konvence Parametr Registry Systémová volání Uživatelský prostor Í386 x86_64 Í386 x86_64 1. EBX RDI EAX RDI 2. ECX RSI EDX RSI 3. EDX R DX Zásobník RDX 4. ESI R10 Zásobník RCX 5. EDI R8 Zásobník R8 6. EBP R9 Zásobník R9 7. Jen 6 parametrů Zásobník Zásobník 8. Zásobník Zásobník Návratová EAX RAX EAX RAX Pozn.: Í386 a -mregparm Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 7/ 15 Úkol Systémová volání bez libc O Otevřete a projděte si pbi73-bin/07/ O Zavolejte • fork • Z potomka: write • Z rodiče: read 16 bytů a jejich write • Z obou potom: exit 0 Přeložte a spusťte • gcc -nostdlib ... Jiri Slabý (Fakulta informatiky, MU) Data z jádra • Jádro předává • Parametry programu 9 Proměnné prostředí • Rozšiřující vektor a Vše na zásobníku • Formát zásobníku je pevně daný Jiri Slabý (Fakulta informatiky, MU) Formát zásobníku Formát zásobníku Počet parametrů long 1. parametr char * char * m-tý parametr char * Konec parametrů OUL 1. proměnná prostředí char * char * n-tá proměnná prostředí char * Konec proměnných prostředí OUL Rozšiřující vektor 1 struct { long type, val; } struct { long type, val; } Rozšiřující vektor o struct { long type, val; } Konec rozšiřujících vektorů {ATJJULL, ? } Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 10/15 Rozšiřující vektor Typ záznamů struct { long type; long value; }; • Typy: at_null, at_entry, at_RAND0M, ... • Pole struktur zakončuje typ at_null Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 11/15 Úkol Zjištění názvu programu a platformy O Vypište první parametr programu • Tj. název samotného programu O Dále iterujte přes zásobník až k rozšiřujícímu vektoru O Tam najděte typ at_platform O Vypište hodnotu jako řetězec O Přeložte (bez libc) a spusťte Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 12/15 Virtuální systémová volání vsyscall • Jen na některých architekturách • Neprobíhá přepnutí kontextu • Speciální stránka(y) s kódem namapovaným jádrem • Podpora jen 3 funkcí • gettimeofday: aktuální Čas (Oxffffffffff600000) • time: čas v sekundách od Epochy (Oxffffffffff 600400) • getcpu: Číslo CPU a NUMA uzlu (Oxffffffffff600800) • Demo: /proc/self/maps Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 13/15 Úkol Volání time Z vsyscall O Zavolejte adresu s time O Vypište hodnotu O Přeložte a spusťte několikrát Jiri Slabý (Fakulta informatiky, MU) Virtuální dynamická knihovna vdso • Speciální knihovna přilinkovaná jádrem • Podpora také závislá na architektuře • Podobná vsyscali, ale více flexibilní • Navíc obsahuje jen ciock_gettime • Demo: ldd a readelf • Knihovna v ELF formátu 9 Adresa začátku v auxv: getauxval (at_sysinfo_ehdr) • Dále se přečte ELF pomocí libelf • Ukázkový kód: Documentation/vDSO/parse_vdso . c Úkol: domácí úkol Jiri Slabý (Fakulta informatiky, MU) PB173/03 4.11.2014 15/15