Writeup: FlareOn 2020: 003 - wednesday
1. TLDR
2. Dane wejściowe
Plik z zadaniem znajduje się tutaj. Hasło: flare.
Przedmiot zadania stanowi gra platformowa mydude.exe
:
Zgodnie z treścią zadania, podejrzałem plik README.txt
:
██╗ ██╗███████╗██████╗ ███╗ ██╗███████╗███████╗██████╗ █████╗ ██╗ ██╗
██║ ██║██╔════╝██╔══██╗████╗ ██║██╔════╝██╔════╝██╔══██╗██╔══██╗╚██╗ ██╔╝
██║ █╗ ██║█████╗ ██║ ██║██╔██╗ ██║█████╗ ███████╗██║ ██║███████║ ╚████╔╝
██║███╗██║██╔══╝ ██║ ██║██║╚██╗██║██╔══╝ ╚════██║██║ ██║██╔══██║ ╚██╔╝
╚███╔███╔╝███████╗██████╔╝██║ ╚████║███████╗███████║██████╔╝██║ ██║ ██║
╚══╝╚══╝ ╚══════╝╚═════╝ ╚═╝ ╚═══╝╚══════╝╚══════╝╚═════╝ ╚═╝ ╚═╝ ╚═╝
--- BE THE WEDNESDAY ---
S
M
T
DUDE
T
F
S
--- Enable accelerated graphics in VM ---
--- Attach sound card device to VM ---
--- Only reverse mydude.exe ---
--- Enjoy it my dudes ---
Nie znalazłem tutaj istotnych wskazówek oprócz tych, które ułatwiają uruchomienie gry na maszynie wirtualnej.
3. Inspekcja pliku mydude.exe
Zweryfikowałem plik narzędziem file
:
$ file mydude.exe
mydude.exe: PE32 executable (console) Intel 80386, for MS Windows
Gra polegała na zbieraniu punktów, które były naliczane po udanym ominięciu przeszkody przez żabę. Gracz mógł wymusić podskok lub przykucnięcie żaby:
Porażkę gracza powodowała kolizja żaby i przeszkody. W momencie rozpoczęcia rozgrywki oraz porażki uruchamiana była animacja, przedstawiająca zmniejszający się okrąg:
4. Analiza statyczna
W związku z tym, że porażkę gracza powodowała kolizja z obiektem ze świata gry, postanowiłem rozpocząć poszukiwania fragmentu kodu odpowiedzialnego za detekcję kolizji. Analiza zdesaemblowanego kodu pozwoliła na identyfikację funkcji @play__ekc9cEXgy7z9cRAqIYID39ccg@8
, która była odpowiedzialna za odtworzenie animacji okręgu. Dlaczego zainteresowała mnie ta funkcja? Animacja okręgu każdorazowo pojawiała się w trakcie restartu gry po porażce gracza. A porażka gracza była nieuchronnie efektem kolizji.
Funkcja @play__ekc9cEXgy7z9cRAqIYID39ccg@8
wywoływana była w trzech miejscach:
Dwa wywołania tej funkcji znajdowały się w funkcji @onCollide__9byAjE9cSmbSbow3F9cTFQfLg@8
, która odpowiedzialna była za obsługę kolizji:
- @onCollide__9byAjE9cSmbSbow3F9cTFQfLg@8+137
Za wysterowanie licznika rozkazów do bloku wywołującego funkcję play, odpowiedzialny był zaznaczony skok, zapisany jako:
- @onCollide__9byAjE9cSmbSbow3F9cTFQfLg@8+260
Za wysterowanie licznika rozkazów do bloku wywołującego funkcję play, odpowiedzialny był zaznaczony skok, zapisany jako:
5. Modyfikacja kodu
W celu włączenia nieśmiertelności żaby, wykonałem modyfikacje opisanych wyżej fragmentów funkcji @onCollide__9byAjE9cSmbSbow3F9cTFQfLg@8
:
5.1 Modyfikacja w pobliżu @onCollide__9byAjE9cSmbSbow3F9cTFQfLg@8+137
Zmieniłem instrukcję
.text:00432232 js loc_4321A2
zapisaną jako
na dwie instrukcje
.text:00432232 nop
.text:00432233 jmp loc_4321A2
poprzez modyfikację bajtów jak poniżej:
5.2 Modyfikacja w pobliżu @onCollide__9byAjE9cSmbSbow3F9cTFQfLg@8+260
Zmieniłem instrukcję
.text:00432358 jz loc_432261
zapisaną jako
na dwie instrukcje
.text:00432358 nop
.text:00432359 jmp loc_432261
poprzez modyfikację bajtów jak poniżej:
5.3 Wprowadzenie zmian
Poniżej przedstawiłem wprowadzone modyfikacje pliku wykonywalnego:
Następnie zatwierdziłem zmiany:
6. Odczytanie flagi
Pozostało uruchomić program, zrobić kawę lub herbatę oraz w międzyczasie poczekać aż żaba ominie bez kolizji wszystkie przeszkody i nazbiera 296 punktów: