<summary><strong>Naucz się hakować AWS od zera do bohatera z</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Czy pracujesz w **firmie z branży cyberbezpieczeństwa**? Chcesz zobaczyć, jak Twoja **firma jest reklamowana na HackTricks**? lub chcesz mieć dostęp do **najnowszej wersji PEASS lub pobrać HackTricks w formacie PDF**? Sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* **Dołącz do** [**💬**](https://emojipedia.org/speech-balloon/) [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** mnie na **Twitterze** 🐦[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**repozytorium hacktricks**](https://github.com/carlospolop/hacktricks) **i** [**repozytorium hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
Poprzedni program ma **9 nagłówków programu**, następnie **mapowanie segmentów** wskazuje, w którym nagłówku programu (od 00 do 08) **znajduje się każda sekcja**.
Na przykład drugi ma rozmiar 0x1190, powinien znajdować się pod adresem 0x1fc48 z uprawnieniami do odczytu i zapisu oraz zostanie wypełniony wartościami 0x528 od przesunięcia 0xfc48 (nie wypełnia całej zarezerwowanej przestrzeni). Ta pamięć będzie zawierać sekcje `.init_array .fini_array .dynamic .got .data .bss`.
Wskazuje konfigurację RELRO (Relocation Read-Only) binarnego pliku. Ta ochrona oznacza jako tylko do odczytu pewne sekcje pamięci (takie jak `GOT` lub tabele `init` i `fini`) po załadowaniu programu i przed jego uruchomieniem.
W poprzednim przykładzie kopiowanych jest 0x3b8 bajtów do 0x1fc48 jako tylko do odczytu, wpływając na sekcje `.init_array .fini_array .dynamic .got .data .bss`.
Zauważ, że RELRO może być częściowy lub pełny, wersja częściowa nie chroni sekcji **`.plt.got`**, która jest używana do **opóźnionego wiązania** i wymaga, aby ta przestrzeń pamięci miała **uprawnienia do zapisu**, aby zapisać adresy bibliotek za pierwszym razem, gdy ich lokalizacja jest wyszukiwana.
* **Tabela ciągów**: Zawiera wszystkie ciągi potrzebne przez plik ELF (ale nie te, które faktycznie są używane przez program). Na przykład zawiera nazwy sekcji takie jak `.text` lub `.data`. Jeśli sekcja `.text` znajduje się na przesunięciu 45 w tabeli ciągów, użyje liczby **45** w polu **nazwa**.
* **`.data`**: Zmienne globalne zdefiniowane wartością w programie.
* **`.bss`**: Zmienne globalne pozostawione niezainicjowane (lub zainicjowane na zero). Zmienne tutaj są automatycznie inicjowane na zero, zapobiegając tym samym dodawaniu niepotrzebnych zer do pliku binarnego.
* **`.rodata`**: Stałe zmienne globalne (sekcja tylko do odczytu).
* **`.tdata`** i **`.tbss`**: Podobne do .data i .bss, gdy używane są zmienne lokalne wątku (`__thread_local` w C++ lub `__thread` w).
- **Atrybuty wiązania** (słabe, lokalne lub globalne): Symbol lokalny może być dostępny tylko przez program, podczas gdy symbole globalne są udostępniane poza programem. Obiekt słaby to na przykład funkcja, która może zostać zastąpiona inną.
- **Typ**: NOTYPE (brak określonego typu), OBJECT (zmienna danych globalnych), FUNC (funkcja), SECTION (sekcja), FILE (plik źródłowy dla debuggerów), TLS (zmienna lokalna wątku), GNU_IFUNC (funkcja pośrednia do relokacji)
Katalog NEEDED wskazuje, że program **musi załadować wymienioną bibliotekę**, aby kontynuować. Katalog NEEDED zostaje uzupełniony, gdy współdzielona **biblioteka jest w pełni operacyjna i gotowa do użycia**.
Ładowacz musi również przesunąć zależności po ich załadowaniu. Te przesunięcia są wskazane w tabeli przesunięć w formatach REL lub RELA, a liczba przesunięć jest podana w sekcjach dynamicznych RELSZ lub RELASZ.
Jeśli **program jest załadowany w innym miejscu** niż preferowany adres (zwykle 0x400000) z powodu zajęcia adresu lub z powodu **ASLR** lub innych powodów, statyczne przemieszczenie **poprawia wskaźniki**, które miały wartości oczekujące, że binarny zostanie załadowany w preferowanym adresie.
Przemieszczenie może również odnosić się do symbolu zewnętrznego (jak funkcja zależności). Na przykład funkcja malloc z libC. Wtedy, ładowacz podczas ładowania libC pod adresem sprawdzającym, gdzie jest załadowana funkcja malloc, zapisze ten adres w tabeli GOT (Global Offset Table) (wskazanej w tabeli przemieszczeń), gdzie powinien być określony adres malloc.
Więc gdy program wywołuje malloc, faktycznie wywołuje odpowiadającą lokalizację `malloc` w PLT (`malloc@plt`). Za pierwszym razem, gdy jest wywoływana, rozwiązuje adres `malloc` i przechowuje go, więc następnym razem, gdy jest wywoływana malloc, używany jest ten adres zamiast kodu PLT.
Po załadowaniu programu nadszedł czas na jego uruchomienie. Jednak pierwszy kod, który jest uruchamiany, **nie zawsze jest funkcją `main`**. Dzieje się tak na przykład w C++, gdy **zmienna globalna jest obiektem klasy**, ten obiekt musi być **zainicjowany****przed** uruchomieniem funkcji main, jak w:
Zauważ, że te zmienne globalne znajdują się w `.data` lub `.bss`, ale w listach `__CTOR_LIST__` i `__DTOR_LIST__` obiekty do zainicjowania i zniszczenia są przechowywane w celu śledzenia ich.
Z kodu C można uzyskać ten sam wynik, korzystając z rozszerzeń GNU:
```c
__attributte__((constructor)) //Add a constructor to execute before
__attributte__((destructor)) //Add to the destructor list
```
Z perspektywy kompilatora, aby wykonać te czynności przed i po wykonaniu funkcji `main`, można utworzyć funkcję `init` i funkcję `fini`, które będą odwoływane w sekcji dynamicznej jako **`INIT`** i **`FIN`** oraz umieszczone w sekcjach `init` i `fini` pliku ELF.
Inną opcją, jak wspomniano, jest odwołanie do list **`__CTOR_LIST__`** i **`__DTOR_LIST__** w wpisach **`INIT_ARRAY`** i **`FINI_ARRAY`** sekcji dynamicznej, a ich długość jest określana przez **`INIT_ARRAYSZ`** i **`FINI_ARRAYSZ`**. Każdy wpis to wskaźnik funkcji, który zostanie wywołany bez argumentów.
Ponadto możliwe jest posiadanie **`PREINIT_ARRAY`** z **wskaźnikami**, które zostaną wykonane **przed** wskaźnikami **`INIT_ARRAY`**.
1. Program jest wczytywany do pamięci, statyczne zmienne globalne są inicjowane w sekcji **`.data`**, a niezainicjowane są zerowane w sekcji **`.bss`**.
2. Wszystkie **zależności** programu lub bibliotek są **inicjowane**, a następnie wykonywane jest **dynamiczne łączenie**.
5. Jeśli istnieje wpis **`INIT`**, zostaje on wywołany.
6. Jeśli to biblioteka, dlopen kończy działanie tutaj, jeśli to program, nadszedł czas na wywołanie **prawdziwego punktu wejścia** (funkcji `main`).
## Pamięć lokalna wątku (TLS)
Są one definiowane za pomocą słowa kluczowego **`__thread_local`** w C++ lub rozszerzenia GNU **`__thread`**.
Każdy wątek będzie utrzymywał unikalne miejsce dla tej zmiennej, dzięki czemu tylko wątek może uzyskać dostęp do swojej zmiennej.
Gdy jest to używane, sekcje **`.tdata`** i **`.tbss`** są używane w pliku ELF. Są to odpowiedniki `.data` (zainicjowane) i `.bss` (niezainicjowane), ale dla TLS.
Każda zmienna ma wpis w nagłówku TLS określający rozmiar i przesunięcie TLS, czyli przesunięcie, które będzie używane w lokalnej przestrzeni danych wątku.
`__TLS_MODULE_BASE` to symbol używany do odwołania do bazowego adresu pamięci lokalnej wątku i wskazuje na obszar w pamięci zawierający wszystkie dane lokalne wątku modułu.