User Tools

Site Tools


laboratoare:laborator-08

This is an old revision of the document!


A PCRE internal error occured. This might be caused by a faulty plugin

====== Laborator 8: 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. ===== Interfața în linia de comanda ===== Deși folosirea unui mediu grafic pentru programare poate părea mai atractivă, de multe ori folosirea liniei de comandă oferă mai multă putere și control asupra a ceea ce vrem să facem. În plus, folosirea utilitarelor din linia de comandă în scripturi poate facilita automatizarea unor task-uri, lucru care ne va face viața mai ușoară în nenumărate cazuri. În cadrul acestui laborator, vom folosi utilitare în linia de comandă atât pentru asamblarea și link-editarea fișierelor sursă, cât și pentru analiza statică și dinamică a programelor obținute din parcurgerea tutorialelor și a exercițiilor. ===== Analiza statică ===== Analiza statică a unui program constă în inspectarea diferitelor aspecte din fișierul obiect sau executabil. Câteve din programele utile pentru analiza statică pe care le vom folosi și în cadrul tutorialelor/exercițiilor sunt: * **nm** - utilitar folosit pentru insepctarea simbolurilor și secțiunilor din executabile * **objdump** - program folosit pentru dezasamblarea (traducerea din cod-mașină în limbaj de asamblare) programelor binare * **IDA** - o unealtă foarte puternică pentru dezasamblarea și inspectarea fișierelor obiect și executabile ===== Analiza dinamică ===== Spre deosebire de analiza statică, analiza dinamică constă în inspectarea unui program aflat în execuție. Practic, analiza dinamică se face la //runtime//. 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 ===== În cadrul exercițiilor vom folosi arhiva de laborator. Descărcați arhiva, decomprimați-o și accesați directorul aferent. <note warning> Decât dacă se specifică altfel în cerință, toate utilitarele vor fi rulate din linia de comandă. Bineînțeles, puteți folosi orice editor text pentru a rezolva exercițiile (chiar și SASM), însă asamblarea, link-editarea etc. vor fi făcute din interfața în linia de comandă. </note> ==== [0.5p] 1. Tutorial: Asamblarea din linia de comandă ==== Deschideți fișierul ''hello-world.asm'' din arhivă și înțelegeți codul. <note> Observați că atât funcțiile externe cât și funcția ''main'' sunt precedate de ''_'' (underscore). Aceasta este utilizarea standard pe Windows. Înainte funcționau ''printf'' și alte funcții externe deoarece erau de fapt doar macro-uri la funcțiile prefixate cu underscore, definite în ''io.inc''. De asemenea, CMAIN era doar un macro la ''_main''. </note> Primul pas este să pornim un shell (Command Prompt, PowerShell sau MSYS, dacă este instalat). După ce avem linia de comandă vom naviga în directorul cu task-urile acestui laborator. Pentru a asambla fișierul ''hello-world.asm'', vom folosi utilitarul ''nasm.exe'' (program care este folosit în spate și de către SASM). Acesta se află în subdirectorul NASM, unde este instalat SASM pe sistemul vostru. Dacă folosim Command Prompt avem: <code> "C:\Program Files (x86)\SASM\NASM\nasm.exe" -g -f win32 hello-world.asm -o hello-world.obj </code> <note> ''-g'' spune asamblorului să adauge simboluri de debug în fișierul obiect rezultat ''-f'' menționează formatul executabilului (în cazul nostru ''win32'') </note> Pentru a verifica "corectitudinea" asamblării, haideți să dezasamblăm fișierul ''hello-world.obj'' folosind utilitarul ''objdump.exe'', astfel: <code> "C:\Program Files (x86)\SASM\MinGW\bin\objdump.exe" -d hello-world.obj </code> Putem observa similaritatea dintre codul inițial și codul dezasamblat, mai puțin la instrucțiunea ''call'', unde adresa pare greșită. Acest fapt se întâmplă din cauza faptului că fișierul obiect obținut nu "știe" cine este printf. Acest lucru se va afla la pasul de link-editare, iar adresa va fi modificată la cea corespunzătoare. ==== [0.5p] 2. Tutorial: Link-editarea unui fișier obiect ==== Link-editarea unuia sau mai multor fișiere obiect constă în rezolvarea tuturor simbolurilor externe și crearea unui singur fișier executabil din toate fișiere primite la intrare. Pentru link-editare vom folosi ''gcc.exe''. De asemenea și gcc este folosit de SASM pentru link-editarea fișierelor obiect. <code> "C:\Program Files (x86)\SASM\MinGW\bin\gcc.exe" -g -m32 hello-world.obj -o hello-world.exe </code> <note> ''-g'' este folosit cu același scop ca la nasm.exe, de a introduce simboluri de debug în executabil ''-m32'' specifică arhitectura pentru care executabilul este generat (în cazul nostru, arhitectură pe 32 biți) </note> Acum puteți rula executabilul pentru a vedea că toți pașii au funcționat. Pentru lansarea în execuție din linie de comandă folosiți construcția <code> .\hello-world.exe </code> Ar trebui să vi se afișeze pe ecran ''Hello, World''. ==== [1.5p] 3. Implementare minimală ''cat'' ==== Pornind de la fișierul hello-world.asm, va trebui să implementați funcționalitatea de bază a utilitarului cat: citește o singură linie de la intrarea standard și o afișează la ieșirea standard. <note> Folosiți funcțiile ''gets'' și ''puts'' pentru a nu mai adăuga șiruri de formatare pentru scanf și printf. </note> După ce ați terminat de implementat, asamblați fișierul sursă și link-editați fișierul obiect obținut din asamblare, pentru a obține un executabil. Pentru a primi punctajul aferent exercițiului, trebuie să prezentați atât codul cât și funcționalitatea programului când este în execuție. ==== [0.5p] 4. Tutorial: Link-editarea mai multor fișiere obiect ==== Ce facem atunci când vrem să modularizăm programul și să avem mai multe fișiere sursă, fiecare cu un anume rol? Practic va trebui să creăm pentru fiecare fișier sursă, fișierul obiect corespunzător, iar apoi să link-edităm toate fișierele obiect obținute într-un singur executabil care să conțină tot codul. În directorul ''linking-multiple'' avem două fișiere: ''main.asm'' și ''helpers.asm''. Deschideți ambele fișiere și observați "legătura" dintre ele (cine apelează ce funcție și din ce fișier). După ce ați înțeles flow-ul programului asamblați fiecare fișier în parte, pentru a obține două fișiere obiect: ''main.obj'' și ''helpers.obj''. Pentru link-editarea multiplă se folosește aceeași comandă gcc, numai că se dau mai multe fișiere de intrare. Spre exemplu: <code> "C:\Program Files (x86)\SASM\MinGW\bin\gcc.exe" -g -m32 main.obj helpers.obj -o palindrome.exe </code> ==== [1.5p] 5. Completarea fișierului cu funț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//. Aveți (pseudo-)codul în C care ar face acest lucru: <code C> void reverse(char *s) { int n = strlen(s); int i; char tmp; for (i = 0; i < n / 2; ++i) { tmp = s[i]; s[i] = s[n - i - 1]; s[n - i - 1] = tmp; } } </code> ==== [1p] 6. Tutorial: GDB ==== ==== [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 ==== ==== [0.5p] 9. Tutorial: Depanarea unui Segfault folosind GDB ==== ==== [1.5p] 10. Rezolvarea unui Segfault ==== ==== [1p] 11. Tutorial: IDA ==== ==== [1.5p] Bonus: Modificarea control-flow-ului unui program folosind GDB ==== ==== [2p] Bonus: Decompilarea unui program folosind IDA ====

laboratoare/laborator-08.1449018710.txt.gz · Last modified: 2015/12/02 03:11 by adrian.bogatu