* objdump * gdb * vim
We kwamen er al snel achter dat het argument van phase_1 van de stack werd gehaald, en zagen onze ingevoerde waarde verschijnen in gdb (x/s). Op dezelfde manier hebben we de juiste waarde gevonden om de eerste fase onschadelijk te maken: er bleek een statisch adres in de assembly code te staan. Door middel van een breakpoint stopte we het programma net voordat de invoer vergeleken werd, en lazen we het antwoord uit van het juiste geheugenadres.
De invoer moest aan de volgende eisen voldoen: Het moesten 6 characters van het type nummer zijn. Dit wordt gecontroleerd door read_six_numbers, welke 6 integers retourneerd. In read_six_numbers wordt sscanf aangeroepen. Door een breakpoint net voor de sscanf de plaatsen lazen we een constant adres uit wat ons bekend voorkwam. Dit zag er uit als een "formatting string", en zag er zo uit: "%d %d %d %d %d %d". De invoer moet dus uit een string van 6 integers bestaan. Dus wisten we dat we niet alleen zes getallen moesten invoeren, maar dat tussen die getalen ook moesten voorkomen.
Tevens wordt er in een loop per integer gechecked of deze kleiner of gelijk als 2 is.
Er wordt weer gebruikt gemaakt van sscanf om de invoer te scheiden naar twee integers. De twee integers komen respectievelijk in register 4(%ebp) en 8(%ebp) te staan. Ze zijn dus beiden van het type word (16 bits).
Door structureel breakpoints aan te maken kwamen we er achter aan welke condities de twee integers moesten voldoen. De eerste compare functie controleerd of de eerste integer van de invoer kleiner dan 7 is. Wat natuurlijk het aantal oplossingen aanzienlijk verkleind. Verderop in de code wordt de eerste integer van de invoer vergeleken met 5. Dit komt goed uit want het moest kleiner dan 7 zijn.
De tweede integer van de invoer wordt gecontroleerd met register %ebx welke we met een breakpoint vlak voor de compare hebben uitgelezen. Eerst dachten we dat het een geheugenlocatie was maar het bleek gewoon de vereiste waarde te zijn. Gelukkig gaf "gdb" ons ook de decimale waarde van het register en dit bleek deze fase te ontmantelen.
In fase 4 staat een aanroep naar een functie, func4. Deze wordt aangeroepen met als argument de invoer van de gebruiker.
Func4 was in het begin een totaal mysterie voor ons, want er is sprake van recursie, zelfs dubbele recursie. Gelukkig bleek het achteraf allemaal wel mee te vallen en was het gewoon de aloude Fibonacci reeks.
De Fibonacci reeks is een reeks getallen waarvan elk getal de som is van zijn twee voorgangers:
F(n) = F(n-1) + F(n-2)
Dit levert de volgende reeks op:
1-1-2-3-5-8-13-21-34-45-79-144
(de eerste twee getallen van deze reeks zijn beide gedefinieerd op 1)
De invoer van de bomb bepaalde het aantal iteraties. Na de func4 aanroep moest er een register op 0x90 uitkomen, decimaal is dat 144. De Fibonacci reeks stuit op 144 als deze 11 keer ittereert. Het antwoord was dus 11.
Na een hoop geploeter kwamen we er eindelijk achter dat de notatie (%ebx, %eax, 4) staat voor een array lookup, m.a.w. het opvragen van een element uit een array.
Dit gebeurd in een while loop met een teller. Het indexnummer dat uit de array wordt opgevraagd is het vorige element (en de eerste invoer van de gebruiker bij de eerste iteratie). Er wordt uit de loop gesprongen als het element 15 is opgevraagd.
Maar als de while loop niet exact 11 (10 als je vanaf nul telt...) iteraties heeft doorlopen, dan ontploft de bom.
Het was dus zaak om zo'n invoer te vinden, dat als het element met 15 wordt opgevraagd, er precies 11 iteraties zijn doorlopen. Deze invoer hebben we gevonden door terug te rekenen. We hebben de hele array opgevraagd (16 elementen) in gdb met het commando "x/16c", gevolgd door het geheugenadres van de array. Vervolgens zijn we vanaf 15 terug gaan rekenen, met 11 stappen. Zo kregen we een reeks en het eerste getal uit deze reeks is de eerste invoer, namelijk 13.
De tweede invoer moet gelijk zijn aan de som van alle opgevraagde elementen. Bij iedere iteratie wordt het verkregen element bij het register %ecx opgeteld. Na de loop wordt dit register vergeleken met de tweede invoer. Dit getal was makkelijk te berekenen: de reeks die we al eerder gemaakt hadden sommeerde we simpelweg, dit gaf 69 (exclusief het allereerst getal van de reeks, die komt immers niet uit de array maar geeft aan waar we moeten beginnen).
0x804a4bc <node1>: "o\003"
Dit "node1" doet ons geloven dat hier linked lists worden gebruikt.
Door de tijdnood kijken we voor deze fase nu even naar een decompiler. Hoewel we er drie gevonden hebben, zijn ze allemaal voor/door DOS/Windows? gebruikers gemaakt (bestandsnamen met hoofdletters), en het is te kort tijd om daar mee aan het werkt te gaan (compilen van decompiler...).