This shows you the differences between two versions of the page.
so:curs:exec-process [2020/03/30 00:44] razvan.deaconescu |
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 39: | Line 117: | ||
Un executabil dinamic nu include în secțiunile sale părțile corespunzătoare din biblioteci. Aceste biblioteci sunt biblioteci dinamice și vor fi adăugate în spațiul virtual de adrese al procesului după încărcare (//loading//), fără a încărca executabilul. | Un executabil dinamic nu include în secțiunile sale părțile corespunzătoare din biblioteci. Aceste biblioteci sunt biblioteci dinamice și vor fi adăugate în spațiul virtual de adrese al procesului după încărcare (//loading//), fără a încărca executabilul. | ||
- | Astfel, un executabil dinamic va fi semnificativ mai mic decât un executabil dinamic. Pe lângă dimensiunea redusă a executabilului, un alt avantaj este partajarea zonelor de cod din cadrul bibliotecilor dinamice cu alte procese. Întrucât aceste zone nu sunt modificate, sunt mapate în spațiul virtual al tuturor proceselor care le foloesc. De exemplu, în cazul bibliotecii standard C, folosită de toate procesele sistemului, zona sa de cod este prezentă o singură dată în memoria RAM și mapată in spațiul virtual de adrese al tuturor proceselor provenite din executabile dinamice. Un proces obținut dintr-un executabil static nu poate partaja nici o parte din zona sa cu alte procese obținute din executabile static, însemnând un consum mai mare de memorie. Bibliotecile dinamice, partajabile, poartă în Linux denumirea de ''shared objects''; de aici și extensia fișierelor de tip bibliotecă dinamică ''.so''. | + | Astfel, un executabil dinamic va fi semnificativ mai mic decât un executabil static. Pe lângă dimensiunea redusă a executabilului, un alt avantaj este partajarea zonelor de cod din cadrul bibliotecilor dinamice cu alte procese. Întrucât aceste zone nu sunt modificate, sunt mapate în spațiul virtual al tuturor proceselor care le foloesc. De exemplu, în cazul bibliotecii standard C, folosită de toate procesele sistemului, zona sa de cod este prezentă o singură dată în memoria RAM și mapată în spațiul virtual de adrese al tuturor proceselor provenite din executabile dinamice. Un proces obținut dintr-un executabil static nu poate partaja nici o parte din zona sa cu alte procese obținute din executabile static, însemnând un consum mai mare de memorie. Bibliotecile dinamice, partajabile, poartă în Linux denumirea de ''shared objects''; de aici și extensia fișierelor de tip bibliotecă dinamică ''.so''. |
- | Executabilele dinamice au dezavantajul unui timp mai mare de încărcare. La orice lansare în execuție a executabilului trebuie realizată procesul de rezolvare a referințelor, numit //dynamic binding//. Suplimentar, dacă un executabil dinamic este transferat pe un sistem unde nu este prezentă o bibliotecă dinamică de care are nevoie, sau este prezentă o versiune incompatibilă, acesta nu va rula. | + | Executabilele dinamice au dezavantajul unui timp mai mare de încărcare. La orice lansare în execuție a executabilului trebuie realizat procesul de rezolvare a referințelor, numit //dynamic binding//. Suplimentar, dacă un executabil dinamic este transferat pe un sistem unde nu este prezentă o bibliotecă dinamică de care are nevoie, sau este prezentă o versiune incompatibilă, acesta nu va rula. |
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> | ||