GNU debugger (gdb)
Gdb (GNU debugger) je debugging alat koji se koristi za analizu binarnih datoteka. Nudi funkcionalnost pauziranja programa u određenim trenucima izvođenja, pregled memorije, registara, stoga, gomile itd… Njime je moguće izvesti disassemble nad strojnim kodom, odnosno, učiniti binarnu datoteku čitljivom.
U svrhe debuggiranja programa, izvorni kod se može kompilirati tako da I sami izvorni kod bude dostupan unutar binarne izvršne datoteke postavljanjem tzv. debugging simbola unutar simboličke tablice binarne datoteke. Time je vidljiv kroz debugging alate poput gdb-a. Npr.
gcc –g –o example example.c // (kompiliranje izvornog koda pisanog u c-u u svrhe debuggiranja radi se zastavicom –g)
U slučaju analize binarne izvršne datoteke u svrhe binarne eksploatacije, ova opcija najčešće neće biti uključena zbog čega je potrebno razumjeti asemblerski jezik.
#Sintaksa za naredbe: naziv_naredbe(kratica)
Pokretanje gdb-a:
gdb <binarna_datoteka>
Korisnik je predstavljen s interaktivnim sučeljem programa Poruka: (No debugging symbols found in binarna_datoteka) je pokazatelj da datoteka nije kompilirana s –g, time izvorni kod neće biti dostupan.
Zadavanje intel sintakse:
echo “set disassembly-flavor intel” > ~/.gdbinit //Unutar shell-a
Naredba za pomoć:
- help: funkcija za ispis naredbi
Izvođenja i tok programa:
- run(r) arg1 arg2…:
- Pokreće program sa zadanim argumentima
- break(b) function/address:
- Postavlja breakpoint (točku zaustavljanja) prije izvođenja neke instrukcije ili funkcije
Primjeri: break main break *main + 12 break *0x4017ba b *main + 27
- continue©:
- Nastavlja s izvođenjem programa ili do sljedećeg breakpointa ili do završetka programa
- delete(d) breakpoint#:
- Briše zadani breakpoint (numeriran nekim brojem).
- Enumeraciju breakpointa moguće je vidjeti s “info break” ili “i b”
- delete breakpoints:
- Za brisanje svih breakpointa
- stepi(si):
- Izvodi sljedeću instrukciju
- Ulazi u funkciju pri pozivu s call (tj. poziva njenu prvu instrukciju)
- step(s):
- Poziva iduću naredbu izvornog koda (koristi se ako je postavljena zastavica debugging zastavica)
- nexti(ni):
- Izvodi sljedeću instrukciju
- Ne ulazi u funkciju pri pozivu s call (gleda cijeli poziv kao jednu instrukciju)
- next(n):
- Poziva iduću naredbu izvornog koda (koristi se ako je postavljena zastavica debugging zastavica)
- kill(k):
- Prekida trenutni proces
Pregled memorije I registara:
- disassemble(disas) arg:
- Ispisuje zadani segment memorije u asemblerskom jeziku
- Argumenti mogu biti:
- Naziv funkcije: disas main
- Raspon adresa: disas 0x4017ba,0x4017db
- Naziv adrese s razmakom: disas *main+5
- Adresa: disas 0x4017 (disassemble and cijelom funkcijom kojoj pripada adresa)
- info(i) [arg]:
- Bez argumenta ispisuje sve opcije za argumente
- Korisni argumenti za funkciju info(i):
- register® [reg1] [reg2]:
- Ispisuje glavne registre ili samo navedene ako su zadani
- frame(f):
- Ispisuje informacije za trenutni okvir na stogu, pohranjene vrijednost, argumenti, lokalne varijable itd…
- functions:
- Ispisuje sve funkcije unutar programa
- Primjer:
- info register rip, rbp, rsp / (i r rip, rbp, rsp) - skraćeno
- i functions / (i f) - skraćeno
- backtrace(bt):
- Ispis svih funkcija na stogu
- where:
- Ispis adrese gdje se gdb trenutno nalazi
- X/nfu addr:
- Pregled memorije s opcijama [n] [f] i [u] na adresi addr
- Opcija n: Opisuje broj ponavljanja ispisa (default 1)
- Opcija f: Opisuje format ispisa (npr. x za heksadecimalno, s za string, I za instrukciju, d za decimalni broj)
- Opcija u: Veličina riječi (b – byte, h - halfword(2b), w - word(4b), g - giantword(8b))
- Primjeri poziva:
- x/200xb $rsp - *200 bajtova u heksadecimanom na adresi koju čuva rsp
- x/s 0x49800c - Ispis stringa na adresi 0x49800c
- x/10i *main+4 - Ispis 10 instrukcija od adrese *main+4
- ctrl+z / quit(q):
- Izlaz
Primjer:
Tajne vanilije
Pokretanje:
gdb main
Prikaz funkcije main:
disas main
Postavljanje breakpointa na adresu main + 49 (mov edi, 0x405098):
b *main + 49
Pokretanje programa:
r
Ispis vrijednosti registra edi:
i r edi //Rezultat je 0x407120
Izvođenje sljedeće instrukcije (mov edi, 0x405098)
ni
Ponovni ispis vrijednosti registra edi:
i r edi //Rezultat je 0x405098
Ispis funkcije provjeri_lozinku:
disas provjeri_lozinku
Postavljanje breakpointa na provjeri_lozinku + 58:
b *provjeri_lozinku + 107
Nastavak programa:
c
Username: “Username123”
Password: “mojalozinka123”
Ispis framea:
i f
Ispis memorije na stogu:
x/20xb $rsp
Ispis stringa na vrhu stoga:
x/s $rsp
Prekid proces:
k
Izlazak:
q