.. _re1: ================================================ Inżynieria wsteczna, część 1 — analiza statyczna ================================================ Data: 05.11.2020, 10.11.2020 .. toctree:: .. contents:: Narzędzia ========= - GHIDRA: https://ghidra-sre.org/ (otwarty disassembler i dekompilator) - Python 3 .. _ghidra: Obsługa programu GHIDRA ----------------------- 1. Tworzymy nowy projekt 2. Importujemy program binarny (przycisk ``I``) 3. Otwieramy program binarny (podwójnym kliknięciem na plik w liście plików) 4. Uruchamiamy automatyczną analizę (domyślne ustawienia powinny działać) i czekamy na zakończenie 5. Przeglądamy kod, poprawiamy błędnie wywnioskowane informacje, dodajemy typy danych, nazywamy funkcje, ... Najważniejsze funkcje programu GHIDRA: - zmiana nazwy, parametrów i typu zwracanego funkcji: klikamy w nazwę funkcji w panelu disassemblera (pierwsze wystąpienie nazwy — drugie nie działa) i naciskamy ``F`` - zmiana typu zmiennej lokalnej: klikamy w nazwę zmiennej lokalnej w panelu dekompilacji, naciskamy ``Ctrl-L`` - zmiana nazwy zmiennej lokalnej: jak wyżej, naciskamy ``L`` Przykład 1: proste porównanie ============================= Program: :download:`simple` Zadanie: znaleźć poprawne hasło do programu. Jest kilka sposobów rozwiązania zadania: 1. Ładujemy do programu GHIDRA, czytamy funkcję ``main`` 2. Używamy polecenia ``strings`` i po prostu znajdujemy hasło Źródło: :download:`simple.c` Przykład 2: prosty szyfr ======================== Program: :download:`encrypted` Zadanie: znaleźć poprawne hasło do programu. 1. Ładujemy do programu GHIDRA 2. Czytamy funkcję ``main``, widzimy że właściwe sprawdzenie następuje znak po znaku w funkcji ``check`` 3. Czytamy i odwracamy funkcję ``check`` Źródło: :download:`encrypted.c` Przykład 3: obliczenia ====================== Program: :download:`key_checker` Zadanie: znaleźć poprawne hasło do programu. 1. Ładujemy do programu GHIDRA 2. Program nie ma symboli — znajdujemy i oznaczamy funkcję ``main`` przez popatrzenie na punkt wejścia programu i wzięcie pierwszego parametru do ``__libc_start_main`` 3. Zmieniamy nazwę zmiennej, do której ``scanf`` wczytuje hasło i poprawiamy jej typ na ``char[64]`` (GHIDRA nie radzie sobie z wykryciem rozmiaru sama) 4. Widzimy wywołania do trzech podfunkcji — pierwsza jest oczywista, druga wymaga odrobiny ręcznej analizy 5. W trzeciej podfunkcji widzimy, że wartość zwracana nie ma sensu — poprawiamy to, ustawiając typ zwracany na ``bool`` 6. Pierwsze dwie funkcje odwracamy ręcznie, do odwrócenia trzeciej używamy np. Pythona 3 z bilbioteką ``gmpy2``:: import gmpy2 print(int((gmpy2.invert(0x7b, 2**64) * -0x34306269e095bb9a) % 2 ** 64).to_bytes(8, 'little')) Przykład 4: struktury ===================== Program: :download:`structures` Zadanie: znaleźć poprawne hasło do programu.