h5 Binääri tässä, missä koodit?
Päivämäärä: 18.9.2026
Tekijä: Aleksi Pamilo
Ympäristöt:
- Kali Linux 2026.2 (x86_64, UTM/QEMU macOS)
- Kali Linux 2026.2 (x86_64, VirtualBox), Ryzen 7 9800x3d, Nvidia RTX 5070 TI
- Kali Linux 2026.2 (x86_64), Intel i3-1115G4
Kokeilin tehtäviä useammalla koneella. Aloitin lab0:n tunnilla macOS:llä, mutta emuloitu amd64-Kali ei jaksanut pyörittää GDB:tä, vaan jäätyi continue-komennon jälkeen. Tehokkaimmista koneista huolimatta natiivisti asennettu Kali i3-kannettavalla toimi parhaiten, joten tein loput tehtävät sillä. Jokaisen tehtävän alussa on merkitty ympäristö, jossa raportin kuvakaappaukset ja tulokset on tehty.
lab0
Ympäristö: 2 (aloitettu ympäristössä 1)
-
Aloitin asentamalla tiedostot hakemistoon
~/Desktop/challenges/Dynaaminen analyysija purkamalla neunzip '*.zip'-komennolla. -
Siirryin lab0 kansioon
cd lab0ja avasin gdb näkymängdb ./buggy_program. -
Komennolla
listnähdään koodi.

-
Lisään breakpointin riville 4
b 4, jar-komennolla käynnistän sovelluksen. -
watch ijawatch sizekomennoilla saan selville jokaisella kierroksella, mitä nämä muuttujat pitää sisällään. -
continuekomentoa käyttämällä näen jokaisen kierroksen
-
Tästä nähdään, että viimeisellä kierroksella
New value = 6. Eli<=aiheuttaa sen, että ohjelma pyörii yhden kerran liikaa. -
Nyt voin korjata koodin vaihtamalla pienempi tai yhtä suuri kuin merkin pienempi kuin merkiksi.
-
nano ./buggy_program.c// Rikkinäinen funktio void buggy_function(int *arr, int size) { for (int i = 0; i <= size; i++) { // Huomaa: <= aiheuttaa puskuriylivuodon printf("Element %d: %d\n", i, arr[i]); } } // Korjattu funktio, kun <= -merkki vaihdetaan < -merkiksi void buggy_function(int *arr, int size) { for (int i = 0; i < size; i++) { printf("Element %d: %d\n", i, arr[i]); } } -
make-komennolla saan käännettyä sovelluksen uudelleen. -
Nyt ohjelma pysähtyy viidenteen numeroon.

-
Ennen ja jälkeen:


lab1
Ympäristö: 3
- Siirryin edellisestä tehtävästä lab1 tehtävään komennolla
cd ../lab1. - Avaan gdb näkymän komennolla
gdb ./gdb_example1. - Ajan ohjelman komennolla
r. Gdb kertoo suoraan, että ohjelma kaatuuSegmentation faultvirheeseen, ja että tämä tapahtuu rivillä 7.

- Ohjelman voi korjata ohittamalla
NULLviestit.#include "stdio.h" void print_scrambled(char *message) { // Lisätään koodiin if-lause, joka tarkistaa, että onko message NULL, jos on, tämä viesti ohitetaan. if (message == NULL) { return; } register int i = 3; do { printf("%c", (*message)+i); } while (*++message); printf("\n"); } int main() { char * bad_message = NULL; char * good_message = "Hello, world."; print_scrambled(good_message); print_scrambled(bad_message); } - Nyt ohjelma voidaan suorittaa onnistuneesti.

lab2
Ympäristö: 3
- Siirryn tehtäväkansioon komennolla
cd ~/Desktop/challenges/Dynaaminen\ analyysi/lab2/passtr. - Kansiossa on kaksi binääriä,
passtrjapasstr2o. Tehtävänä on murtaapasstr2o, jonka lähdekoodia ei ole, joten avaan sen GDB:hen komennollagdb ./passtr2o. info functionskomennolla löytyy kaikki ohjelman funktiot ja symbolit.disas main-komennolla saan purettua main funktion.- Tämä ei vielä kerro hirveästi, kokeillaan purkaa funktio
mAsdf3a, ja asetetaan breakpoint funktion alkuunb *mAsdf3a. - Tästä näkyy
mov %rdi,%rbpjamov %rsi,%rbx. Käynnistän ohjelmanr, ja syötän salasanaksitesti. - Ohjelma pysähtyy breakpointtiin, printataan
rsijardimuuntamalla ne ensin char muotoonprint (char*) $rsi,print (char*) $rdi. - Tämä paljastaa, että
$rsion käyttäjän syöte, ja$rdion oletettavasti salasana.

anLTj4u8ei kuitenkaan ole ohjelman hyväksymä salasana, joten sille todennäköisesti tehdään jotain, tai se ei ole etsimämme salasana.
Tekoälyn käyttö: Jäin jumiin funktion
mAsdf3aassemblyn tulkinnassa ja käytin tästä eteenpäin apuna tekoälyä (Claude). Tekoäly selitti käskyjen merkityksen (silmukka, parillisuustarkistustest $0x1,%alsekäadd $0x3/sub $0x7-muunnokset) ja ehdotti GDB:ncommands-ominaisuutta odotettujen merkkien tulostamiseen. Ajoin komennot, otin kuvakaappaukset ja varmistin salasanan ja lipun itse.
- Puretaan funktio
disas mAsdf3a.

- Funktio toimii näin:
call strlenkahdesti jacmp %r12d,%edx: salasanan ja tallennetun merkkijonon pituuden pitää olla sama, eli 8 merkkiä.- Silmukassa luetaan tallennettu merkki
edx:ään ja syötteen merkkiecx:ään. test $0x1,%altarkistaa, onko indeksi pariton. Parillisessa indeksissä tallennettuun merkkiin lisätään 3 (add $0x3,%edx), parittomassa vähennetään 7 (sub $0x7,%edx).cmp %ecx,%edxvertaa muunnettua merkkiä syötteeseen. Jos ne eroavat, funktio palauttaa -1.
- Salasana on siis
anLTj4u8, jonka merkkejä on muunnettu. Muunnetut merkit saa selville GDB:llä pysäyttämällä ohjelman vertailukohtaanmAsdf3a+66. - Asetan breakpointin ja liitän siihen komennot, jotka tulostavat odotetun merkin ja kopioivat sen syötteen merkin tilalle. Näin silmukka ei katkea ensimmäiseen väärään merkkiin:
b *mAsdf3a+66 commands silent p/c $edx set $ecx = $edx c end - Käynnistän ohjelman
rja syötän minkä tahansa 8-merkkisen salasanan, esim.aaaaaaaa. - GDB tulostaa jokaisella kierroksella odotetun merkin:

- Merkit yhdistämällä salasanaksi saadaan
dgOMm-x1. - Ajetaan ohjelma ilman debuggeria
./passtr2oja syötetään salasana. Ohjelma tulostaa lipunFLAG{Lari-rsvRDx04WMBZpuwg4qfYwzdcvVa0oym}.
Mitä uutta opin GDB:stä
info functions: ohjelman funktioiden listaus, kun lähdekoodia ei ole.disas: funktion purkaminen assemblyksi.b *funktio+offset: breakpoint tiettyyn käskyyn eikä rivinumeroon.print (char*) $rdi: rekisterin tulkitseminen merkkijonona. x86-64:ssä funktion argumentit kulkevat järjestyksessärdi,rsi,rdx…p/c $edx: rekisterin arvo merkkinä.set $rekisteri = arvo: rekisterin muuttaminen kesken ajon.commands ... end: komennot, jotka ajetaan automaattisesti breakpointissa.
lab3
Ympäristö: 3
- Valitsin tehtäväksi
crackme01.64. Kansionlab3/crackmesREADME:n mukaan tavoitteena on saada ohjelma päättymään paluuarvoon 0. Lähdekoodia (crackme01.c) en lukenut. - Siirryn kansioon komennolla
cd ~/Desktop/challenges/Dynaaminen\ analyysi/lab3/crackmes. stringsei ollut asennettuna. Se kuuluubinutils-pakettiin, joten asensin sen komennollasudo apt install binutils.strings crackme01.64-komento listaa binäärin tulostettavat merkkijonot. Niiden joukosta löytyypassword1, joka on todennäköinen salasana.- Varmistan GDB:llä, että ohjelma todella vertaa syötettä tähän merkkijonoon. Avaan ohjelman komennolla
gdb ./crackme01.64. disas main-komennolla näen, että ohjelma kutsuustrncmp-funktiota kohdassamain+30.- Asetan breakpointin kutsuun
b *main+30ja käynnistän ohjelman argumentillaakomennollar a. - Ohjelman pysähdyttyä tulostan
strncmp:n kaksi ensimmäistä argumenttia komennoillaprint (char*) $rdijaprint (char*) $rsi.$rdisisältää syötteeniaja$rsimerkkijononpassword1, joten ohjelma vertaa syötettä juuri siihen.

- Ajan ohjelman ilman debuggeria oikealla salasanalla ja tulostan paluuarvon:
./crackme01.64 password1; echo $?. - Ohjelma tulostaa
Yes, password1 is correct!ja paluuarvo on0, joten salasana onpassword1.
Lähteet
- Kurssitehtävä: Tero Karvinen: Application Hacking - h5 Binääri tässä, missä koodit?. Luettu: 18.9.2026.
- Claude (Anthropic): käytetty funktion
mAsdf3aassemblyn selittämiseen lab2-tehtävässä. Käytetty: 23.9.2026.