.. _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.