User Tools

Site Tools


laboratoare:laborator-08

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision Both sides next revision
laboratoare:laborator-08 [2015/12/02 03:11]
adrian.bogatu
laboratoare:laborator-08 [2015/12/02 04:34]
adrian.bogatu
Line 24: Line 24:
  
 Unul dintre cele mai folosite programe pentru analiză dinamică este **gdb**. Acesta oferă o gamă largă de operații ce pot fi făcute, de la inspectarea memoriei, la schimbarea control flow-ului și până la modificarea registrelor de pe procesor, în timpul rulării unui program. Unul dintre cele mai folosite programe pentru analiză dinamică este **gdb**. Acesta oferă o gamă largă de operații ce pot fi făcute, de la inspectarea memoriei, la schimbarea control flow-ului și până la modificarea registrelor de pe procesor, în timpul rulării unui program.
- 
-  * command parameters and file redirect (run) 
-  * break 
-  * step by step (step, next, continue) 
-  * disassemble (must mention intel syntax v at&t) 
-  * print/​display register values, flags 
-  * print/​display integers 
-  * break and compute address from registers, memory zones, etc. 
-  * print strings 
-  * print instructions,​ current instructions 
-  * print stack 
-  * present peda python thingie 
-  * as zice debug program (dar ar fi practic sa existe cate un exercitiu de genu' la fiecare din comenzile mentionate anterior, mai ales la partile care incep cu "print something"​) 
-  * debug segfault 
  
 ===== Tutoriale și exerciții ===== ===== Tutoriale și exerciții =====
Line 127: Line 113:
 </​code>​ </​code>​
  
-==== [1.5p] 5. Completarea fișierului cu funții ajutătoare ====+==== [1.5p] 5. Completarea fișierului cu funcții ajutătoare ====
  
 După cum probabil ați observat, funcția ''​reverse''​ din ''​helpers.asm''​ nu face nimic. În cadrul acestui exercițiu, va trebui să implementați corpul funcției, unde este comentariul TODO, astfel încât șirul de caractere care a fost trimis ca parametru să fie întors //​in-place//​. După cum probabil ați observat, funcția ''​reverse''​ din ''​helpers.asm''​ nu face nimic. În cadrul acestui exercițiu, va trebui să implementați corpul funcției, unde este comentariul TODO, astfel încât șirul de caractere care a fost trimis ca parametru să fie întors //​in-place//​.
Line 146: Line 132:
 } }
 </​code>​ </​code>​
 +
 +După implementare va trebui să asamblați și link-editați programul.
  
 ==== [1p] 6. Tutorial: GDB ==== ==== [1p] 6. Tutorial: GDB ====
 +
 +GDB este o unealtă foarte utilă pentru analiza dinamică a programelor. Acesta este folosit foarte des pentru găsirea cauzelor care duc la erori într-un program. În continuare vă vom prezenta câteva dintre comenzile cele mai importante.
 +
 +Primul pas este să urmăriți și să înțelegeți codul din ''​gdb-tutorial.asm''​. Pe scurt, programul primește un parametru ''​index''​ și citește de la tastatură o linie. Programul afișează doar un caracter, mai exact al ''​index''​-lea caracter din șirul dat la intrare.
 +
 +După ce ați citit codul sursă, asamblați și link-editați fișierul. După ce ați obținut executabilul ''​gdb-tutorial.exe''​ (sau ce nume i-ați dat), vom porni GDB-ul cu acel fișier:
 +
 +<​code>​
 +"​C:​\Program Files (x86)\SASM\MinGW\bin\gdb.exe"​ gdb-tutorial.exe
 +</​code>​
 +
 +După ce ați pornit programul gdb, toată interacțiunea cu acesta se face prin prompt-ul de gdb.
 +
 +=== Lansarea în execuție a programului ===
 +
 +Pentru a lansa programul urmărit în execuție există două comenzi:
 +  * **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
 +
 +Aceste două comenzi mai pot fi folosite în două feluri:
 +
 +  - <​code>​start 1 2 3 4</​code>​
 +  - <​code>​start < file.in</​code>​
 +
 +Utilizarea aceasta este similară cu execuția programului direct din linia de comandă (fără GDB), prima variantă însemnând că se trimit 4 parametri (1, 2, 3 și 4) programului,​ iar a doua, că ''​file.in''​ se redirectează ca intrare standard pentru program.
 +
 +Lansați programul în execuție folosind comanda GDB ''​run''​. Ce observați? Rulați din nou programul, de data aceasta dând comenzii run parametrul corespunzător.
 +
 +GDB se blochează la citirile de la input. Haideți să corectăm asta folosind un fișier de intrare. Creați un fișier (spre exemplu text.in) în directorul cu executabilul care să conțină textul "ana are mere". Porniți din nou GDB și lansați în execuție programul cu parametrul de intrare ''​11''​ și cu fișierul ''​text.in'',​ redirectat.
 +
 +Ce observați? Programul își termină execuția cu succes. Deoarece nu a existat niciun breakpoint setat în program, programul nu s-a oprit din execuție decât când a terminat treaba.
 +
 +În cazul pornirii programului,​ puteți folosi instrucțiunea ''​start''​ care va opri execuția după intrarea în main.
 +
 +=== Breakpoints ===
 +
 +Elementul esențial al GDB-ului este //​breakpoint-ul//​. Practic, un //​breakpoint//​ setat la o anumită instrucțiune face ca execuția programului să se oprească de fiecare dată când se ajunge la acest punct.
 +
 +Adăugarea unui breakpoint se face cu construcția
 +
 +<​code>​break [location]</​code>​
 +
 +, unde ''​location''​ poate fi numele unei funcții sau o adresă din zona .text. În cazul cel din urmă, adresa trebuie să fie precedată de ''​*''​ (star). Exemplu: ''​break *0x004013af''​.
 +
 +Pentru continuarea programului după eventuala sa oprire într-un breakpoint, puteți folosi comanda ''​continue''​.
 +
 +=== Parcurgerea instrucțiunilor ===
 +
 +Atunci când execuția programului este oprită (de exemplu la un breakpoint),​ putem da comenzi care continuă execuția "pas cu pas". Pentru a face asta, cel mai des sunt folosite două comenzi:
 +
 +  * **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''​)
 +
 +=== Dezasamblarea programului ===
 +
 +Pentru a dezasambla o porțiune de executabil, se poate folosi comanda ''​disassemble''​ din GDB. Dacă aceasta nu primește niciun parametru, va afișa dezasamblarea funcției curente din cadrul execuției.
 +
 +<​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''​.
 +</​note>​
 +
 +=== 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 inspectarea memoriei se folosește comanda ''​x''​ (examine). Modul de folosire al acestei comenzi este următorul:
 +<​code>​
 +x/nfu address
 +</​code>​
 +, unde:
 +  * ''​n''​ este numărul de elemente afișate
 +  * ''​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)
 +
 ==== [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 ====
 ==== [1p] 8. Afișarea adresei de retur a unei funcții ==== ==== [1p] 8. Afișarea adresei de retur a unei funcții ====
Line 155: Line 217:
 ==== [1.5p] Bonus: Modificarea control-flow-ului unui program folosind GDB ==== ==== [1.5p] Bonus: Modificarea control-flow-ului unui program folosind GDB ====
 ==== [2p] Bonus: Decompilarea unui program folosind IDA ==== ==== [2p] Bonus: Decompilarea unui program folosind IDA ====
- 
- 
  
laboratoare/laborator-08.txt · Last modified: 2015/12/02 12:31 by vladimir.diaconescu