PB173 - Binární programování Linux III. Binární objektové soubory Jiri Slabý ITI, Fakulta informatiky 1. 10. 2013 J. Slabý (ITI, Fl) PB173/07 1. 10. 2013 1 /16 Objektové soubory • Vznikají při překladu i linkování • Výstup překladače (gcc -c) • Výstup linkeru jako: • Dynamická knihovna • Spustitelná binárka • Literatura • System V Application Binary Interface (ELF) J. Slabý (ITI, Fl) Obsah objektových souborů Obvykle • Informace o souboru • Cílová architektura, struktura,... • Kód • Data • Ostatní informace potřebné k běhu/linkování • Relokace, informace o symbolech atd. Ale také např. • Ladicí informace • Informace o překladači Tyto informace v oddílech (sekcích) J. Slabý (ITI, Fl) Formáty objektových souborů o Několik forem/standardů • a.out (UNIX/starý Linux) a ELF (Linux) 0 COM (DOS, čistě kód+data, nic víc) • COFF (UNIX, ELF ho převálcoval) • MZ (DOS .exe) • PE (Windows .exe, vychází z COFF) Demo: DosBox a reboot přes COM (ea fO ff 00 f 0) J. Slabý (ITI, Fl) PB173/07 1. 10. 2013 4/ 16 Úkol Práce s PE O Stáhněte si nějakou Windows aplikaci • Cokoliv, co je .exe (PE) Q Vypište si informace společné formátům (objdump -f) 0 Vypište si informace závislé na formátu (objdump -p) • Zjistěte DLL, na kterých váš program závisí O Porovnejte sekce s nějakým ELFem (objdump -h) • Jakákoliv binárka z /usr/bin J. Slabý (ITI, Fl) PB173/07 1. 10. 2013 5/ 16 ELF Executable and Linkable Formát • Hlavní souborový formát na Linuxu a Přenositelný, relokovatelný, rozšiřitelný • Struktura • ELF hlavička • Hlavičky programové • Při spouštění • Hlavičky sekcí • Při linkování, ladění apod. • Sekce • Odkazovány z obou typů hlaviček a readelf je speciální objdump pro ELF J. Slabý (ITI, Fl) PB173/07 1.10.2013 6/ 16 ELF hlavička • readelf -h • Magické číslo (0x7f ,e,,l,,F') • Cílová architektura a stroj a Počty hlaviček Úkol: výpis ELF hlavičky a zjištění počtu obou typů hlaviček J. Slabý (ITI, Fl) PB173/07 1. 10. 2013 7/ 16 Sekce • readelf -S (obsah sekce: readelf -x) • Vytvářené překladačem/linkerem • Čtené překladačem/linkerem/interpretrem a Předdefinované sekce: • .text: kód 0 .data: nekonstantní data (proměnné) • .rodata: konstantní data (řetězce apod.) o .bss: data, která se inicializují na 0 • .interp: interpretr • . symtab: tabulka symbolů pro ladění (strip) • .dynsym: tabulka symbolů pro dynamický linker • .gnu_debugiink: odkaz na soubor s ladicími informacemi Demo: ukázka sekcí J. Slabý (ITI, Fl) PB173/07 1. 10. 2013 8/ 16 Úkol Práce se sekcemi O Vytvořte si soubor s puts ("hello") a puts ("world") Q Vytvořte si vlastní sekci s daty int ..attribute.. ((section(".data.my.section"))) x = 3; O Vytvořte si vlastní sekci s funkcí (.text.my_section) O Přeložte do .o a poté i slinkujte O Vypište si seznam sekcí v obou souborech (readelf -s) O Vypište si obsah sekcí (readelf -x) • .rodata (zkuste ireadelf -p) • V .o: .data.my_section • V .o: .text.my_section (zkuste i objdump -d) Pozn.: tyto soubory nezahazujte. J. Slabý (ITI, Fl) PB173/07 1. 10. 2013 9/ 16 libbfd • Knihovna pro práci s různými binárními formáty (bfd.h) • a.out, ELF, PE, binární, ... • Seznam: const char **bfd_target_list() • A různými architekturami • Seznam: const char **bfd_arch_list() a Dokumentace • https://sourceware.org/binutils/docs/bfd/ o Některá užitečná makra bez dokumentace (jen v bfd.h) • Knihovny při překladu: gcc ... -lbfd -liberty -ldl -lz • První je třeba volat void bfd_init() J. Slabý (ITI, Fl) PB173/07 1. 10. 2013 10/16 libbfd: chyby Jak zjistit, co se stalo? • Poslední chyba:bfd_error_type bfd_get_error() a Převod na text: const char *bfd_errmsg(bfd_error_type error_tag) Typicky: if (! bfdJunction (...) ) errx(1, "bfdJunction: %s", bfd.errmsg(bfd.get.error())); J. Slabý (ITI, Fl) PB173/07 1. 10. 2013 11/16 Úkol Vypište všechny formáty podporované vaší libbf d O Nezapomeňte bfd_init O Zavolejte bf d_target_list O Vypište v cyklu O Zavolejte bfd_arch_list O Vypište v cyklu O Ověřujte návratové hodnoty podle manuálu o Vypisujte chyby při neúspěchu O Přeložte a spusťte J. Slabý (ITI, Fl) PB173/07 1. 10. 2013 12/16 libbf d: soubory • Otevření • bfd *bfd_openr(const char *file, const char *target) • bfd *bfd_openw(const char *file, const char *target) • target je NULL a Ověření • Nutné před prací se souborem • bfd_boolean bfd_check_format(bfd *abfd, bfd_format format) • f ormat J6 bf d_object a Zavření 9 bfd_boolean bfd_close(bfd *abfd) Bez ověření chyb: abfd = bfd.openr(file , NULL); bfd.check.format(abfd, bfd.object); bfd-dose(abfd); J. Slabý (ITI, Fl) PB173/07 1. 10. 2013 13/16 Úkol Doplňte otevírání souboru zadaného jako parametr O Zavolejte bf d_openr Q Zavolejte bf d_check_f ormat Q Zavolejte bf d_close O Ověřujte návratové hodnoty podle manuálu O Přeložte a spusťte J. Slabý (ITI, Fl) PB173/07 I. 10. 2013 14/16 libbfd: sekce • Iterace: bfd_map_over_sections • Velikost: bf d_get_section_size • Obsah:bfd_get_section_contents • Vytvoření: bf d_make_section_witli_f lags 9 Nastavení velikosti: bf d_set_section_size • Nastavení obsahu: bf d_set_section_contents J. Slabý (ITI, Fl) PB173/07 1. 10. 2013 15/16 Úkol Hexdump sekcí Q Iterujte přes sekce (bf d_map_over_sections) O Vypište údaje o každé sekci • Název • Velikosti • Flagy • Hexdump prvních 16 bytů obsahu O Přeložte O Spusťte o Pro ELF 0 Pro PE J. Slabý (ITI, Fl)