Inżynieria wsteczna, część 2 — analiza dynamiczna¶
Data: 17.11.2020, 19.11.2020
Treść
Narzędzia¶
gdb (debugger)
Python 3
Obsługa gdb¶
Uruchomienie gdb:
gdb ./program
Najważniejsze polecenia:
help: listuje poleceniahelp <nazwa polecenia>: pokazuje dokumentację do poleceniabreak nazwa_funkcji: ustawia breakpoint na daną funkcjębreak *0x12345: ustawia breakpoint na dany adreshbreak nazwa_funkcji: ustawia breakpoint na daną funkcję używając breakpointa sprzętowegoattach <pid>: wpina debugger w już uruchomiony programrun: uruchamia programrun abc def: uruchamia program z argumentamirun <wejscie >wyjscie: uruchamia program z przekierowanym wejściem / wyjściemstart: jakrun, ale zatrzymuje program na funkcjimain(nie działa, jeśli nie mamy symboli)p wyrażenie: drukuje wartość wyrażenia (składnia jak w C), oprócz funkcjonalności języka C można również używać wartości rejestrów (np. pisząc$rax)p/x wyrażenie: drukuje wartość wyrażenia jako liczbę szesnastkowąx/20bx adres: pokazuje zawartość pamięci pod danym adresem, jako 20 bajtów w systemie szesnastkowymx/10gx adres: jak wyżej, ale jako 10 liczb 64-bitowychx/10i adres: disassembluje 10 instrukcji pod danym adresemx/s adres: pokazuje null-terminated string pod danym adresemdisplay: działa dokładnie jakx, ale wykonuje się samo po każdym wykonaniu kodu (w szczególności polecamdisplay/20i $pc, aby mieć podgląd wykonywanych instrukcji)c: kontynuuje wykonanie aż do następnego breakpointasi: wykonuje jedną instrukcję procesorani: jaksi, ale w przypadku instrukcjicallwykonuje całą funkcję na razs: wykonuje jedną linijkę kodu źródłowego (nie działa, jeśli program nie był skompilowany z informacjami dla debuggera)n: ma się dosjaknidosifin: wykonuje program aż do momentu, gdy aktualna funkcja się zakończybt: pokazuje stos wywołań funkcjiframe <numer ramki z bt>: ustawia kontekst na daną ramkę ze stosu wywołań (ewaluacja wyrażeń będzie używała zmiennych z danej ramki)set <zmienna lub $rejestr> = <wyrażenie>: ustawia wartość zmiennej bądź rejestrukill: przerywa debugowany program (przydatne, jeżeli nieodwracalnie go popsuliśmy)Ctrl-Cgdy program jest wykonywany: zatrzymuje wykonanie tak, jakby został trafiony breakpoint
Pełna dokumentacja: https://sourceware.org/gdb/current/onlinedocs/gdb/
Mechanizm LD_PRELOAD¶
Przy analizie dynamicznej przydatna bywa możliwość dołączenia własnego kodu
do istniejącego programu. Służy do tego mechanizm LD_PRELOAD — jest to
zmienna środowiskowa, którą możemy ustawić na ścieżkę do naszej biblioteki
współdzielonej. Przy uruchamianiu dowolnego programu zlinkowanego dynamicznie
ta biblioteka będzie automatycznie ładowana razem z programem.
W takiej bibliotece możemy:
definiować własne funkcje (które będą przesłaniać funkcje z biblioteki systemowej)
jeśli chcemy użyć przesłonionych funkcji, możemy użyć
dlsymzRTLD_NEXTwykonać dodatkowy kod przed startem programu, prze zawarcie go w funkcji bez argumentów oznaczonej przez
__attribute__((constructor))
Przykład: zeszłoroczne zadanie zaliczeniowe¶
Program: bsk01
Zadanie: znaleźć poprawne hasło do programu.