This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
laboratoare:laborator-08 [2015/12/02 05:23] adrian.bogatu |
laboratoare:laborator-08 [2015/12/02 12:31] (current) vladimir.diaconescu OCD change |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Laborator 8: Interfața în linia de comandă, analiza statică și dinamică ====== | + | ====== Laborator 08: Interfața în linia de comandă, analiza statică și dinamică ====== |
După un scurt breviar care va explica noțiunile introduse în acest laborator, va urma o parte practică care alternează între secțiuni de tip tutorial, cu parcurgere pas cu pas și prezentarea soluției, și exerciții care trebuie să fie rezolvate. | După un scurt breviar care va explica noțiunile introduse în acest laborator, va urma o parte practică care alternează între secțiuni de tip tutorial, cu parcurgere pas cu pas și prezentarea soluției, și exerciții care trebuie să fie rezolvate. | ||
Line 27: | Line 27: | ||
===== Tutoriale și exerciții ===== | ===== Tutoriale și exerciții ===== | ||
- | În cadrul exercițiilor vom folosi arhiva de laborator. | + | În cadrul exercițiilor vom folosi {{laboratoare:lab-08-tasks.zip|arhiva de laborator}}. |
Descărcați arhiva, decomprimați-o și accesați directorul aferent. | Descărcați arhiva, decomprimați-o și accesați directorul aferent. | ||
Line 151: | Line 151: | ||
=== Lansarea în execuție a programului === | === Lansarea în execuție a programului === | ||
- | Pentru a lansa programul urmărit în execuție există două comenzi: | + | Pentru a lansa programul urmărit în execuție există două comenzi disponibile: |
* **run** - această comandă va lansa în execuție programul | * **run** - această comandă va lansa în execuție programul | ||
* **start** - spre deosebire de ''run'', această comandă va începe execuția programului, însă se va opri imediat după intrarea în main | * **start** - spre deosebire de ''run'', această comandă va începe execuția programului, însă se va opri imediat după intrarea în main | ||
Line 197: | Line 197: | ||
Pentru a nu rămâne blocat în breakpoint (spre exemplu dacă scrieți un script de gdb), puteți adăuga în blocul de instrucțiuni și comanda ''continue''. | Pentru a nu rămâne blocat în breakpoint (spre exemplu dacă scrieți un script de gdb), puteți adăuga în blocul de instrucțiuni și comanda ''continue''. | ||
+ | |||
+ | Haideți să adăugăm un breakpoint la label-ul ''ok''. Dacă dăm ''continue'', vom observa că programul s-a oprit în breakpoint-ul tocmai creat. | ||
+ | <note> | ||
+ | Variaţii:\\ | ||
+ | **break label** - breakpoint la labelul **label**\\ | ||
+ | **break *(label + <offset>)** - breakpoint la **label + offset**\\ | ||
+ | </note> | ||
=== Parcurgerea instrucțiunilor === | === Parcurgerea instrucțiunilor === | ||
Line 204: | Line 211: | ||
* **stepi** - care practic trimite o instrucțiune spre execuție și după execuția acesteia întoarce control-ul la debugger (programul se oprește) | * **stepi** - care practic trimite o instrucțiune spre execuție și după execuția acesteia întoarce control-ul la debugger (programul se oprește) | ||
* **nexti** - comandă similară cu ''stepi'', însă dacă instrucțiunea curentă este un apel de funcție, debugger-ul nu va intra în funcție (va chema funcția și se va opri la următoarea instrucțiune după ''call'') | * **nexti** - comandă similară cu ''stepi'', însă dacă instrucțiunea curentă este un apel de funcție, debugger-ul nu va intra în funcție (va chema funcția și se va opri la următoarea instrucțiune după ''call'') | ||
+ | |||
+ | Dacă emitem comanda ''stepi'', putem observa că se afișează instruction pointer-ul instrucțiunii următoare dupa cea la care am făcut break (prima de la label-ul ''ok''). | ||
=== Dezasamblarea programului === | === Dezasamblarea programului === | ||
Line 211: | Line 220: | ||
<note> | <note> | ||
Default, sintaxa folosită de GDB la dezasamblare este cea "AT&T". Pentru a folosi sintaxa cunoscută vouă (sintaxa intel), executați în GDB comanda ''set disassembly-flavor intel''. | Default, sintaxa folosită de GDB la dezasamblare este cea "AT&T". Pentru a folosi sintaxa cunoscută vouă (sintaxa intel), executați în GDB comanda ''set disassembly-flavor intel''. | ||
+ | </note> | ||
+ | |||
+ | În cadrul exemplului nostru, dacă cerem dezasamblarea funcției curente (folosind ''disassemble'' fără parametri) putem observa că ne aflăm la label-ul ''ok''. Observație: GDB iterpretează label-ul ''ok'' ca o funcție din cauza codului inițial, care este scris în limbaj de asamblare. | ||
+ | |||
+ | Pentru a vedea mai clar efectul ''stepi''/''nexti'' putem rula commanda ''disassemble'' înainte și după stepping. | ||
+ | |||
+ | <note> | ||
+ | Dacă ați intrat într-o funcție lungă și nu vreți să dați de ''nexti'' de foarte multe ori, vă recomandăm instrucțiunea GDB ''finish'', care "termină" o funcție. **Atenție** la funcțiile recursive. | ||
+ | </note> | ||
+ | <note> | ||
+ | **disassemble label, +<length>** - afişează <length> bytes de cod dezasamblat începând de la labelul **label**. | ||
</note> | </note> | ||
=== Inspectarea memoriei și a registrelor === | === Inspectarea memoriei și a registrelor === | ||
- | Pentru a afișa diferite valori accesiblie GDB-ului se folosește comanda ''print''. De exemplu, pentru a afișa valoarea unui registru (de exemplu eax), vom folosi contrucția ''print $eax''. | + | Pentru a afișa diferite valori accesibile GDB-ului se folosește comanda ''print''. De exemplu, pentru a afișa valoarea unui registru (de exemplu eax), vom folosi construcția ''print $eax''. |
Pentru inspectarea memoriei se folosește comanda ''x'' (examine). Modul de folosire al acestei comenzi este următorul: | Pentru inspectarea memoriei se folosește comanda ''x'' (examine). Modul de folosire al acestei comenzi este următorul: | ||
Line 225: | Line 245: | ||
* ''f'' este formatul de afișare (x pentru hexa, d pentru zecimal, s pentru șir de caractere și i pentru instrucțiuni) | * ''f'' este formatul de afișare (x pentru hexa, d pentru zecimal, s pentru șir de caractere și i pentru instrucțiuni) | ||
* ''u'' este dimensiunea unui element (b pentru 1 octet, h pentru 2, w pentru 4 și g pentru 8 octeți) | * ''u'' este dimensiunea unui element (b pentru 1 octet, h pentru 2, w pentru 4 și g pentru 8 octeți) | ||
+ | |||
+ | De exemplu, o funcționalitate similară cu ''disassemble'' o putem obține și folosind ''x'' unde formatul este instrucțiune. Astfel, putem afișa, de exemplu, 10 instrucțiuni începând de la instrucțiunea curentă cu construcția ''x/10i $eip''. | ||
==== [0.5p] 7. Afișarea unor informații la fiecare trecere printr-un breakpoint ==== | ==== [0.5p] 7. Afișarea unor informații la fiecare trecere printr-un breakpoint ==== | ||
- | Folosind executabilul creat la exercițiul anterior (''gdb-tutorial.asm''), trebuie să setați un breakpoint la intrare în bucla din program (când se mută în subregistrul ''al'' un caracter din șirul input). În plus, trebuie să adăugați o serie de comenzi astfel încât la fiecare intrare în buclă, GDB să afișeze valoarea subregistrului ''al''. **Hint!** folosiți comanda ''commands''. | + | Folosind executabilul creat la exercițiul anterior (''gdb-tutorial.asm''), trebuie să setați un breakpoint la intrare în bucla din program (când se mută în subregistrul ''al'' un caracter din șirul input). În plus, trebuie să adăugați o serie de comenzi astfel încât la fiecare intrare în buclă, GDB să afișeze valoarea subregistrului ''al'' și valoarea counter-ului (în cazul nostru ''ecx''). **Hint!** folosiți comanda ''commands''. |
==== [1p] 8. Afișarea adresei de retur ale unor funcții ==== | ==== [1p] 8. Afișarea adresei de retur ale unor funcții ==== | ||
Line 254: | Line 276: | ||
==== [1.5p] 10. Rezolvarea unui Segfault ==== | ==== [1.5p] 10. Rezolvarea unui Segfault ==== | ||
+ | Pornind de la executabilul ''segfault.exe'', rulat sub gdb, analizați atât backtrace-ul cât și pas cu pas codul pentru a identifica cauza care duce la Segmentation Fault. | ||
==== [1p] 11. Tutorial: IDA ==== | ==== [1p] 11. Tutorial: IDA ==== | ||
- | ==== [1.5p] Bonus: Modificarea control-flow-ului unui program folosind GDB ==== | + | |
+ | În această secțiune vom prezenta foarte pe scurt câteva dintre numeroasele aspecte ale programului IDA. | ||
+ | |||
+ | În primul rând va trebui să descărcați installer-ul de IDA de [[https://out7.hex-rays.com/files/idafree50.exe|aici]] și să-l instalați pe mașinile din laborator. După ce programul s-a instalat, porniți Ida Pro Free. La prompt-ul de welcome alegeți varianta ''[GO] Work on your own''. Din meniul de sus dați "Open..." și deschideți fișierul de la exercițiul 10 (''segfault.exe''). | ||
+ | |||
+ | Dintre numeroasele view-uri posibile din IDA, cele mai importante sunt: | ||
+ | |||
+ | * Control-flow graph-ul ce conține pentru fiecare bloc dezasamblarea sa | ||
+ | * **Names** care este o tabelă cu simbolurile din executabil | ||
+ | * **Functions** care conține toate informațiile despre o funcție (dacă e statică sau dintr-o bibliotecă; tipul funcției etc.) | ||
+ | |||
+ | Deși pot fi multe de spus despre IDA, în cadrul acestui laborator ne vom limita doar la capabilitățile de analiză statică ale sale. | ||
+ | <note> | ||
+ | IDA este destul de avansat încât are posibilitatea de a face tracking şi în Kernelul sistemului de operare. Motiv pentru care trebuie rulat cu drepturi de administrator pentru a putea dreptul la o resursă critică a sistemului. | ||
+ | </note> | ||
+ | ==== [2p] Bonus: Modificarea control-flow-ului unui program folosind GDB ==== | ||
+ | |||
+ | Pornind de la executabilul ''control-flow.exe'' rulat sub gdb, trebuie să găsiți o modalitate să se afișeze un flag. Până nu veți rezolva corect problema, se va afișa "No flag for you." | ||
==== [2p] Bonus: Decompilarea unui program folosind IDA ==== | ==== [2p] Bonus: Decompilarea unui program folosind IDA ==== | ||
+ | Pornind de la fișierul obiect ''decompile.obj'', treaba voastră este să reconstruiți codul sursa (scris în C) din care a provenit binarul. Puteți folosi orice utilitar de analiză statică, însă cel mai indicat pentru acest task este IDA, deoarece reprezintă foarte clar graful de control al execuției. |