W tym laboratorium wykonasz prostą różnicę z kodem pokazanym wcześniej w sekcji „Różnice aplikacji”. Pliki binarne ELF name i name2 mają zostać porównane. Plik name jest plikiem bez poprawki, a name2 jest plikiem z poprawką. Najpierw musisz uruchomić bezpłatną aplikację IDA 5.0, którą wcześniej zainstalowałeś. Po jej uruchomieniu przejdź do Plik | Nowy, wybierz kartę Unix z wyskakującego okienka i kliknij opcję ELF po lewej stronie, jak pokazano tutaj, a następnie kliknij OK.
Przejdź do folderu C:\grayhat\app_diff\ i wybierz plik „name”. Zaakceptuj domyślne opcje, które się pojawią. IDA powinna szybko zakończyć swoją autoanalizę, domyślnie wybierając funkcję main() w oknie demontażu, jak pokazano poniżej.
Naciśnij CTRL-F11, aby wyświetlić wyskakujące okienko turbodiff. Jeśli się nie pojawi, wróć i upewnij się, że poprawnie skopiowałeś niezbędne pliki dla turbodiff. Gdy okno turbodiff jest na ekranie, wybierz opcję „pobierz informacje z tego idb” i kliknij OK, a następnie kliknij OK. Następnie przejdź do Plik | Nowy, a pojawi się wyskakujące okienko z pytaniem, czy chcesz zapisać bazę danych. Zaakceptuj ustawienia domyślne i kliknij OK. Powtórz kroki wybierania karty Unix | ELF Executable, a następnie kliknij OK. Otwórz plik binarny ELF name2 i zaakceptuj ustawienia domyślne. Powtórz kroki otwierania wyskakującego okienka turbodiff i wybierania opcji „pobierz informacje z tego idb”. Teraz, gdy wykonałeś to dla obu plików, naciśnij ponownie CTRL-F11, gdy plik name2 jest nadal otwarty w IDA. Wybierz opcję „porównaj z…” i kliknij OK. Wybierz plik name.idb i kliknij OK, a następnie kliknij OK. Powinno pojawić się poniższe pole (aby uzyskać dokładny obraz, konieczne może być sortowanie według kategorii).
Należy pamiętać, że funkcja getName() jest oznaczona jako „podejrzana ++”. Kliknij dwukrotnie funkcję getName(), aby wyświetlić następujące okno:
Na tym obrazku lewe okno pokazuje poprawioną funkcję, a prawe okno pokazuje niepoprawioną funkcję. Niepoprawiony blok używa funkcji gets(), która nie zapewnia sprawdzania granic. Poprawiony blok używa funkcji fgets(), która wymaga argumentu size, aby pomóc zapobiec przepełnieniom bufora. Poprawiona dezasemblacja jest pokazana tutaj:
W obu funkcjach było kilka dodatkowych bloków kodu, ale są one białe i nie zawierają żadnego zmienionego kodu. Są po prostu kodem ochronnym stack-smashing, który weryfikuje stack canaries, po którym następuje epilog funkcji. W tym momencie ukończyłeś laboratorium. Idąc dalej, przyjrzymy się różnicom w świecie rzeczywistym.