This shows you the differences between two versions of the page.
so:curs:exec-process [2020/03/30 12:40] liza_elena.babu [Executabile statice și dinamice] |
so:curs:exec-process [2021/04/14 06:24] (current) razvan.deaconescu [Apelarea unor funcționalități ascunse] |
||
---|---|---|---|
Line 13: | Line 13: | ||
* [[https://beginners.re/|Reverse Engineering for Beginners]] | * [[https://beginners.re/|Reverse Engineering for Beginners]] | ||
* [[https://github.com/onethawt/reverseengineering-reading-list|Reverse Engineering Reading List]] | * [[https://github.com/onethawt/reverseengineering-reading-list|Reverse Engineering Reading List]] | ||
+ | |||
+ | * Filmări | ||
+ | * 3CA: https://web.microsoftstream.com/video/f0316c59-353b-4675-a5f4-d268b9d512ac | ||
+ | * 3CC curs 10, partea 1: https://web.microsoftstream.com/video/5ffc701c-343d-4aad-8528-beb1bb5d11f0 | ||
+ | * 3CC curs 10, partea a 2-a: https://web.microsoftstream.com/video/9152c7c0-0d89-4a5a-a4c6-cab016038242 | ||
+ | |||
+ | * Curs CA [[https://www.slideshare.net/alexandruradovici/sisteme-de-operare-analiza-executabilelor-i-proceselor|slideshare]] | ||
===== Demo-uri ===== | ===== Demo-uri ===== | ||
Line 25: | Line 32: | ||
Acum putem parcurge secțiunile cu demo-uri de mai jos. | Acum putem parcurge secțiunile cu demo-uri de mai jos. | ||
+ | |||
+ | ==== Secțiuni și adrese în cadrul unui fișier executabil ==== | ||
+ | |||
+ | Dorim să urmărim adresele secțiunilor și simbolurilor în cadrul unui fișier executabil de tip ELF (//Executable and Linking Format//). Pentru aceasta accesăm subdirectorul ''exec-addr/''; urmărim conținutul fișierului ''exec-addr.c''. În acest fișier definim variabile globale și afișăm adresele acestor variabile și a funcțiilor din modul. Vom observa că adresele variabilelor globale și a funcțiior sunt cunoscute de la link-time, în momentul link-editării și a obținerii executabilului. | ||
+ | |||
+ | Compilăm programul folosind ''make''. | ||
+ | |||
+ | Pentru început investigăm simbolurile din executabil. Ne interesează variabilele globale și funcțiile așa că vom rula comanda de afișare a simbolurilor din care vom extrage liniile de interes:<code bash> | ||
+ | user@host:$ objdump --syms exec-addr | grep '\(exec_\| main\|simple_func\)' | ||
+ | 0000000000600da0 l O .data 0000000000000004 exec_static_int_global | ||
+ | 000000000040076b l F .text 000000000000001a simple_func | ||
+ | 0000000000600dc4 g O .bss 0000000000000004 exec_int_global_noinit | ||
+ | 0000000000600da4 g O .data 0000000000000004 exec_int_global | ||
+ | 00000000004008b8 g O .rodata 0000000000000006 exec_array_ro | ||
+ | 0000000000400785 g F .text 000000000000009c main | ||
+ | </code> | ||
+ | |||
+ | Prin rularea comenzii objdump de mai sus afișăm informații despre simboluri, în format pe coloane, astfel: | ||
+ | * În prima coloană sunt adresele simbolurilor. Aceste adrese se vor regăsi întocmai în proces (vom vedea în continuare). Adresele pot să difere în cazul obținerii executabilului pe alt sistem. | ||
+ | * A doua coloană este tipul simbolului. Simbolurile statice sunt marcate cu ''l'' (//local//) pentru că vor fi locale modulului. Celelalte sunt marcate cu ''g'' (//global//) și vor putea fi exportate în alte module. | ||
+ | * A patra coloană este secțiunea din executabil unde este alocat simbolul. Simbolul este alocat în modul încă de la compile-time. Secțiunile sunt după cum urmează: | ||
+ | * ''.data'': variabile globale inițializate | ||
+ | * ''.bss'': variabile globale neinițializate | ||
+ | * ''.rodata'': variabile globale de tip read-only | ||
+ | * ''.text'': zonă de cod/instrucțiuni (pentru funcții) | ||
+ | * A cincea coloană este spațiul ocupat de simbol. Variabilele întregi ocupă ''sizeof(int) = 4'' octeți, șirul de caractere ocupă 6 octeți (incluzând NUL-terminatorul) iar funcțiile ocupă spațiul dat de codul acestora. | ||
+ | |||
+ | Observăm că zona de date read-only (''.rodata'') este apropiată de zona de cod (''.text'') ambele fiind zone care nu pot fi scrise. | ||
+ | |||
+ | Ca să verificăm faptul că adresele precizate în executabil se vor regăsi și în momentul rulării procesului, la run-time, rulăm executabilul:<code bash> | ||
+ | $ ./exec-addr | ||
+ | Inside simple_func | ||
+ | |||
+ | Run-time addresses are: | ||
+ | &exec_static_int_global: 0x600da0 | ||
+ | &exec_int_global: 0x600da4 | ||
+ | &exec_int_global_noinit: 0x600dc4 | ||
+ | &exec_array_ro: 0x4008b8 | ||
+ | &simple_func: 0x40076b | ||
+ | &main: 0x400785 | ||
+ | |||
+ | Run `pmap -p $(pidof exec-addr)' to show process map. | ||
+ | |||
+ | Press ENTER to continue ... | ||
+ | </code> | ||
+ | |||
+ | Observăm din rezultatul rulării că adresele de la run-time sunt aceleași cu cele din executabil. | ||
+ | |||
+ | După cum ni se indică la rulare, vom rula ''pmap'' pentru a consulta spațiul virtual de adresă al procesului:<code bash> | ||
+ | $ pmap -p $(pidof exec-addr) | ||
+ | 13545: ./exec-addr | ||
+ | 0000000000400000 4K r-x-- /home/razvan/school/2011-2012/so/git-repos/cursuri.git/curs-07-demo/exec-addr/exec-addr | ||
+ | 0000000000600000 4K rw--- /home/razvan/school/2011-2012/so/git-repos/cursuri.git/curs-07-demo/exec-addr/exec-addr | ||
+ | 00007fd884842000 1664K r-x-- /lib/x86_64-linux-gnu/libc-2.18.so | ||
+ | 00007fd8849e2000 2044K ----- /lib/x86_64-linux-gnu/libc-2.18.so | ||
+ | 00007fd884be1000 16K r---- /lib/x86_64-linux-gnu/libc-2.18.so | ||
+ | 00007fd884be5000 8K rw--- /lib/x86_64-linux-gnu/libc-2.18.so | ||
+ | 00007fd884be7000 16K rw--- [ anon ] | ||
+ | 00007fd884beb000 128K r-x-- /lib/x86_64-linux-gnu/ld-2.18.so | ||
+ | 00007fd884dcf000 12K rw--- [ anon ] | ||
+ | 00007fd884e06000 16K rw--- [ anon ] | ||
+ | 00007fd884e0a000 4K r---- /lib/x86_64-linux-gnu/ld-2.18.so | ||
+ | 00007fd884e0b000 4K rw--- /lib/x86_64-linux-gnu/ld-2.18.so | ||
+ | 00007fd884e0c000 4K rw--- [ anon ] | ||
+ | 00007fffb51d1000 132K rw--- [ stack ] | ||
+ | 00007fffb51fe000 8K r-x-- [ anon ] | ||
+ | ffffffffff600000 4K r-x-- [ anon ] | ||
+ | total 4068K | ||
+ | </code> | ||
+ | |||
+ | Legat de partea de executabil, observăm că avem două pagini (''4K'') mapate din executabilul ''exec-addr''. Una este readable/executable (''r-x'') și începe de la adresa ''0x400000'', iar alta este readable/writable (''rw-'') și începe de la adresa ''0x600000''. În prima pagină sunt mapate secțiunile ''.text'' și ''.rodata'', iar în cealaltă sunt mapate secțiunile ''.data'' și ''.bss''; observăm acest lucru pe baza adreselor. | ||
==== Executabile statice și dinamice ==== | ==== Executabile statice și dinamice ==== | ||
Line 44: | Line 122: | ||
Sumarizând, executabilele statice și dinamice au următoarele avantaje: | Sumarizând, executabilele statice și dinamice au următoarele avantaje: | ||
- | * Executabilele dinamice ocupă mai puțin spațiu pe disc, iar procesele aferente ocupă mai puțină memorie fizică, partajând zonele read-only (''.text'', ''.rodata'') din bibilioteci cu alte procese obținute din executabile dinamice care folosesc aceleași biblioteci. | + | * Executabilele dinamice ocupă mai puțin spațiu pe disc, iar procesele aferente ocupă mai puțină memorie fizică, partajând zonele read-only și read-execute (''.text'', ''.rodata'') din bibilioteci cu alte procese obținute din executabile dinamice care folosesc aceleași biblioteci. |
- | * Executabilele statice sunt portabile, pot fi transferate pe un alt sistem fără a fi nevoie de prezența unor biblioteci sau biblioteci compatibile. Lansarea lor în execuție (//loading//) este mai rapidă, nefiind nevoie de rezolvarea referințelor (//dynamic binding//); toate referințele au fost rezolvate la link time. | + | * Executabilele statice sunt portabile, pot fi transferate pe un alt sistem (cu aceeași arhitectură a sistemului pentru care a fost compilat binarul) fără a fi nevoie de prezența unor biblioteci sau biblioteci compatibile. Lansarea lor în execuție (//loading//) este mai rapidă, nefiind nevoie de rezolvarea referințelor (//dynamic binding//); toate referințele au fost rezolvate la link time. |
În subdirectorul ''static-dynamic/'' se găsește fișierul sursă ''hello.c'' și un fișier ''Makefile'' pe care îl folosim pentru a compila un executabil static (''hello-static'') și unul dinamic (''hello-dynamic''): | În subdirectorul ''static-dynamic/'' se găsește fișierul sursă ''hello.c'' și un fișier ''Makefile'' pe care îl folosim pentru a compila un executabil static (''hello-static'') și unul dinamic (''hello-dynamic''): | ||
Line 64: | Line 142: | ||
<code> | <code> | ||
$ ls -lh hello-* | $ ls -lh hello-* | ||
- | -rwxr-xr-x 1 student sstudent 8.4K Mar 29 21:57 hello-dynamic | + | -rwxr-xr-x 1 student student 8.4K Mar 29 21:57 hello-dynamic |
-rwxr-xr-x 1 student student 826K Mar 29 21:57 hello-static | -rwxr-xr-x 1 student student 826K Mar 29 21:57 hello-static | ||
Line 425: | Line 503: | ||
PEDA este o versiune mai puțin menținută curentă, dar cu o istorie mai lungă în comunitatea de securitatea. pwndbg și GEF sunt proiecte mai recente, cu funcționalități mai multe și comunități active de dezvoltare. | PEDA este o versiune mai puțin menținută curentă, dar cu o istorie mai lungă în comunitatea de securitatea. pwndbg și GEF sunt proiecte mai recente, cu funcționalități mai multe și comunități active de dezvoltare. | ||
- | Cele trei proiecte pot fi configurate să fie prezente simultan (dar folosite alternativ) în GDB, așa cum este descris [[https://medium.com/bugbountywriteup/pwndbg-gef-peda-one-for-all-and-all-for-one-714d71bf36b8|aici]]. | + | Cele trei proiecte pot fi configurate să fie prezente simultan (dar folosite alternativ) în GDB, așa cum este descris [[https://infosecwriteups.com/pwndbg-gef-peda-one-for-all-and-all-for-one-714d71bf36b8|aici]] (și configurat automat cu [[https://github.com/apogiatzis/gdb-peda-pwndbg-gef|acest repository]]). |
</note> | </note> | ||