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 instrukcjicall
wykonuje 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ę dos
jakni
dosi
fin
: 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-C
gdy 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ć
dlsym
zRTLD_NEXT
wykonać 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.