Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
mora-hwbp — Движок перехвата в пользовательском режиме и инструментирования телеметрии на основе аппаратных точек останова (DR0-DR7) без модификации кода (AMSI, WLDP и ETW PoC). | Kitploit
Инструменты/GitHubGitHub/dovughs/mora-hwbp
Оборонительные ИнструментыОбход IDS/IPSОтладчикиОбучение и ОбразованиеRed TeamingСостязательная Атака
GitHubdovughs/mora-hwbp

mora-hwbp

Движок перехвата в пользовательском режиме и инструментирования телеметрии на основе аппаратных точек останова (DR0-DR7) без модификации кода (AMSI, WLDP и ETW PoC).

Репозиторий
101 день назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Mora-HWBP — Перехват телеметрии AMSI / WLDP / ETW через аппаратные точки останова

Концепт-доказательство (POC) для исследований в области безопасности, демонстрирующее перехват функций на основе аппаратных точек останова (регистров отладки CPU) как альтернативу традиционному пропатчиванию кода в памяти.

Цель и область применения

Данный репозиторий опубликован строго для оборонительных исследований в области безопасности, обучения red-team/purple-team, разработки механизмов обнаружения и академического изучения внутренностей Windows. Он демонстрирует как злоумышленник может злоупотребить регистрами отладки процессора, чтобы нейтрализовать пользовательскую телеметрию безопасности, — и, что не менее важно, что защитникам следует отслеживать для обнаружения таких техник. Автор не несёт ответственности за любое неправомерное использование этого кода. Использование данной техники против систем без явного разрешения незаконно и нарушает соответствующие законы о компьютерном мошенничестве и злоупотреблениях в большинстве юрисдикций. Не разворачивайте это в среде, которой вы не владеете или на тестирование которой у вас нет явного письменного разрешения.


Содержание

  1. Обзор
  2. Предыстория — Зачем аппаратные точки останова?
  3. Целевые компоненты безопасности
  4. Архитектура
  5. Техническое погружение
    • 5.1 Аппаратные точки останова на x64
    • 5.2 Раскладка регистров отладки (DR0–DR7)
    • 5.3 Векторный обработчик исключений (VEH)
    • 5.4 Логика перехвата для каждого компонента
    • 5.5 Управление потоками и устойчивость перехвата
  6. Экспортируемый API
  7. Инструкции по сборке
  8. Пример внедрения и использования
  9. Обнаружение и смягчение (Blue Team)
  10. Известные ограничения
  11. Ссылки

Обзор

mora_hwbp.c реализует DLL, которая после загрузки/внедрения в целевой процесс (например, хост PowerShell) перехватывает четыре пользовательские функции исключительно через аппаратные точки останова CPU, хранящиеся в архитектурных регистрах отладки (DR0–DR7) каждого потока процесса:

Векторный обработчик исключений (VEH) уровня процесса получает исключения EXCEPTION_SINGLE_STEP (0x80000004), вызванные регистрами отладки, имитирует успешный путь возврата исходной функции, переписывая контекст исключения, и возобновляет выполнение — всё без изменения ни одного байта исполняемой памяти.

Это делает технику особенно интересной как с точки зрения атаки, так и с точки зрения защиты:

  • С точки зрения атаки она обходит проверки целостности EDR/HIPS, которые ищут изменённые секции .text (классический inline-хукинг, патчинг EAT/IAT или стаббинг Etwp*).
  • С точки зрения защиты аппаратные точки останова оставляют высокохарактерные криминалистические артефакты (содержимое регистров отладки, плотность исключений одиночного шага, регистрацию VEH, паттерны системных вызовов GetThreadContext/SetThreadContext), которые можно использовать для обнаружения.

Предыстория — Зачем аппаратные точки останова?

Традиционные подходы к перехвату в пользовательском режиме — inline-детуры (перезапись 5–14 байт), перехват таблицы импорта (IAT) и перехват таблицы экспорта (EAT) — имеют общую слабость: они модифицируют память, которую могут наблюдать сканеры целостности и ETW.

Современные AV/EDR реализуют:

  • Сканирование памяти / AMSI-сканирование буферов PowerShell и .NET CLR;
  • Телеметрию на основе ETW (Microsoft-Windows-PowerShell, .NET ETW, поставщики threat intelligence);
  • Ядерные колбэки и проверки целостности в пользовательском режиме, которые обнаруживают трюки с pageguard/guard-page, переходы VirtualProtect к PAGE_EXECUTE_READWRITE и несовпадения хэшей секций.

Аппаратные точки останова обходят всё это:

  1. Они — регистры CPU, а не память — в .text нечего сканировать.
  2. Они устанавливаются для каждого потока через Windows API SetThreadContext, что не вызывает классические сигналы "память изменена", используемые сканерами целостности.
  3. Точка перехвата полностью обрабатывается диспетчеризацией исключений процессора, которая проходит через цепочку VEH процесса до выполнения любой целевой функции в пользовательском режиме.

Этот POC исследует эффективность и обнаруживаемость данной техники против AMSI (Antimalware Scan Interface), WLDP (Windows Lockdown Policy) и ETW (Event Tracing for Windows) — трёх наиболее широко используемых примитивов безопасности в пользовательском режиме в современном стеке безопасности Windows.


Целевые компоненты безопасности

AMSI — интерфейс сканирования вредоносных программ

AMSI — это точка интеграции платформы Windows, которая позволяет приложениям (PowerShell, Office, VBScript, .NET-хостам и т.д.) запрашивать сканирование содержимого у зарегистрированных антивирусных провайдеров. Представляют основной интерес две точки входа:

  • AmsiScanBuffer(HANDLE hamsiContext, PVOID buffer, ULONG length, LPCWSTR contentName, HANDLE hamsiSession, AMSI_RESULT *pResult)
  • AmsiScanString(HANDLE hamsiContext, LPCWSTR string, LPCWSTR contentName, HANDLE hamsiSession, AMSI_RESULT *pResult)

Принудительно устанавливая возвращаемое значение AMSI_RESULT в AMSI_RESULT_CLEAN (0), механизм сценариев считает, что содержимое было проверено и признано безвредным, поэтому выполнение продолжается без перерыва.

WLDP — политика ограничений Windows

WLDP реализует оценку политик для Windows Defender Application Control (WDAC / Device Guard). WldpIsClassInApprovedList отвечает на вопрос, разрешён ли данный COM-класс (идентифицируемый GUID) в рамках текущей политики. AMSI внутренне обращается к WLDP, чтобы решить, считаются ли определённые классы сценариев/содержимого "доверенными" (находящимися в списке одобренных). Если функция сообщает, что класс одобрен, AMSI может пропустить дополнительную проверку для этого типа содержимого.

DLL устанавливает выходной параметр isApproved (RDX) в TRUE и возвращает S_OK, делая проверяемый класс "доверенным".

ETW — трассировка событий Windows

Функция EtwEventWrite в ntdll.dll — это основной приёмник пользовательского режима практически для всей эмиссии событий ETW в системе. Её подавление имеет широкие побочные эффекты, важные для мониторинга безопасности:

  • события журналирования конвейера PowerShell и блоков сценариев
  • события загрузки сборок .NET (Microsoft-Windows-DotNETRuntime)
  • телеметрия результатов AMSI-сканирования
  • события поставщиков Threat Intelligence, потребляемые EDR-агентами

DLL просто возвращает ERROR_SUCCESS (0), не выполняя реальную функцию.


Архитектура```

┌──────────────────────────────────────────────────────────────────────────┐ │ Target Process (e.g. powershell.exe) │ │ │ │ ┌──────────────────────────┐ ┌──────────────────────────────────┐│ │ │ mora_hwbp.dll │ │ CPU / Windows ││ │ │ │ │ ││ │ │ DllMain / InstallHook │ │ Thread A Thread B ││ │ │ │ │ │ ┌────────┐ ┌────────┐ ││ │ │ ▼ │ │ │ DR0..3 │ │ DR0..3 │ ││ │ │ Resolve exports │ │ └────────┘ └────────┘ ││ │ │ (amsi/wldp/ntdll) │ │ ││ │ │ │ │ │ #DB (single-step) ││ │ │ ▼ │ │ exception ──► Windows Dispatch ││ │ │ AddVectoredException │ │ │ ││ │ │ Handler(VEH) │ │ ▼ ││ │ │ │ │ │ ┌─────────────────────────────┐ ││ │ │ ▼ │ │ │ VectoredHandler (ours) │ ││ │ │ SetHwbpOnThread(ALL) │ │ │ • match #DB address │ ││ │ │ │ │ │ │ • rewrite context (RIP/RSP)│ ││ │ │ ▼ │ │ │ • spoof return value (RAX) │ ││ │ │ MonitorThread ◄──┐ │ │ │ • continue execution │ ││ │ │ (re-hook every │ │ │ └─────────────────────────────┘ ││ │ │ 500ms) └──────┘ │ ││ │ └──────────────────────────┘ └──────────────────────────────────┘│ └──────────────────────────────────────────────────────────────────────────┘

root@kitploit:~
**Общий порядок работы:**

1. DLL загружается в целевой процесс (любым методом инъекции — см. [Использование](#injection--usage-example)).
2. При `DLL_PROCESS_ATTACH` (или через экспортируемую функцию `InstallHook`) целевые экспортируемые функции разрешаются с помощью `GetProcAddress` (при необходимости принудительно загружая модули через `LoadLibraryW`).
3. **Векторный обработчик исключений** регистрируется как **первый** обработчик в процессе (`AddVectoredExceptionHandler(1, ...)`).
4. **Текущий поток** перехватывается немедленно, затем **все существующие потоки** в процессе перечисляются через `CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0)` и перехватываются.
5. **Поток-монитор** просыпается каждые 500 мс и повторно применяет точки останова ко всем потокам — включая **новые созданные потоки** — гарантируя сохранение перехвата, даже если поток появился после установки хуков или если точки останова были сброшены извне.
6. Когда любая перехваченная функция вызывается в любом потоке, CPU генерирует исключение одиночного шага `#DB`; Windows передаёт его в VEH, который имитирует безвредный возврат и продолжает выполнение.

### Пример диагностического вывода

![Диагностика статуса перехвата HWBP Engine, полученная в Sysinternals DebugView](https://assets.kitploit.com/production/public/readmes/50594/5cf99fadc07272ff598cbb9486ff7803a3234eb6aeaa8202684c27e97bd7e161.png)

*Рисунок 1 — Пример диагностического вывода, полученного с помощью Sysinternals DebugView. Каждая строка сообщает разрешённый адрес целевой функции и текущий счётчик срабатываний для соответствующего регистра отладки.*

---

## Технические подробности

### 5.1 Аппаратные точки останова на x64

В x86/x64 каждый процессор предоставляет **четыре аппаратных регистра адресов точек останова** (`DR0`–`DR3`) и управляющий регистр (`DR7`). Любой поток, выполняющийся с ненулевой точкой останова в `DR0`–`DR3`, вызовет исключение, когда счётчик команд достигнет этого адреса (или когда доступ к данным соответствует заданным условиям). Регистр состояния `DR6` фиксирует, какая точка останова сработала.

Аппаратные точки останова **зависят от контекста**: они хранятся в структуре `CONTEXT` потока и действуют только для того потока, на котором установлены. Именно поэтому надёжная реализация должна устанавливать точки останова на **каждом потоке** процесса (и постоянно повторно применять их для новых потоков).

### 5.2 Распределение регистров отладки (DR0–DR7)

`DR7` представляет собой битовое поле, управляющее включением и поведением точек останова:

| Биты   | Поле  | Назначение                                           |
|--------|--------|------------------------------------------------------|
| `0`    | `L0`   | Локальное включение для точки останова 0 (DR0)       |
| `2`    | `L1`   | Локальное включение для точки останова 1 (DR1)       |
| `4`    | `L2`   | Локальное включение для точки останова 2 (DR2)       |
| `6`    | `L3`   | Локальное включение для точки останова 3 (DR3)       |
| `8`    | `LE`   | Устаревшее локальное включение (сохранено для совместимости) |
| `9`    | `GE`   | Устаревшее глобальное включение (сохранено для совместимости) |
| `16–17`| `R/W0` | Тип доступа для BP0 (`00` = выполнение инструкции)   |
| `18–19`| `Len0` | Длина для BP0 (`00` = 1 байт)                        |
| `20–21`| `R/W1` | Тип доступа для BP1 (`00` = выполнение инструкции)   |
| `22–23`| `Len1` | Длина для BP1 (`00` = 1 байт)                        |
| `24–25`| `R/W2` | Тип доступа для BP2 (`00` = выполнение инструкции)   |
| `26–27`| `Len2` | Длина для BP2 (`00` = 1 байт)                        |
| `28–29`| `R/W3` | Тип доступа для BP3 (`00` = выполнение инструкции)   |
| `30–31`| `Len3` | Длина для BP3 (`00` = 1 байт)                        |

Все четыре точки останова настроены на **выполнение (выборку инструкции) одного байта**, что является подходящим условием для хуков на входе в функцию.

### 5.3 Векторный обработчик исключений (VEH)

Когда срабатывает точка останова, процессор вызывает исключение `#DB`. В x64 Windows процедура диспетчеризации в `ntdll` направляет его через общепроцессную **цепочку VEH** перед цепочкой структурированных обработчиков исключений (SEH) потока. Обработчик в этом проекте:

1. **Фильтрует** — обрабатывает только `EXCEPTION_SINGLE_STEP` (`0x80000004`); всё остальное передаётся дальше через `EXCEPTION_CONTINUE_SEARCH`.
2. **Сопоставляет** — сравнивает `ExceptionAddress` с четырьмя известными адресами функций.
3. **Переписывает контекст**:
   - `RIP = *(RSP)` → «возврат» к исходному вызывающему коду путём извлечения обратного адреса из стека.
   - `RSP += 8` → имитация `ret` (одноинструкционная размотка стека в x64).
   - `RAX = 0` → подмена `S_OK` / `ERROR_SUCCESS` (код успешного возврата).
   - `DR6 &= ~0xF` → сброс битов состояния точки останова, чтобы инструкцию можно было повторно выполнить позже без ложного состояния.
4. **Изменяет выходные параметры** (см. [5.4](#54-per-component-interception-logic)).
5. **Возвращает `EXCEPTION_CONTINUE_EXECUTION`**, что указывает Windows перезапустить поток с изменённым контекстом — то есть выполнение возобновляется с *вызывающего кода*, а реальная целевая функция **никогда не выполняется**.

Каждая точка перехвата дополнительно обёрнута в защиту SEH `__try/__except`, чтобы некорректное или неожиданное расположение стека не могло привести к краху процесса — это соображение надёжности для враждебных/усиленно защищённых целей.

### 5.4 Логика перехвата по компонентам

**DR0 — `AmsiScanBuffer`** (x64, первые 6 аргументов в `RCX, RDX, R8, R9, [RSP+0x28], [RSP+0x30]`):```
HRESULT AmsiScanBuffer(HANDLE, PVOID, ULONG, LPCWSTR, HANDLE, AMSI_RESULT* pResult);
                                                        [RSP+0x28]  [RSP+0x30]
  • Записывает AMSI_RESULT_CLEAN (0) в 6-й параметр (pResult, по адресу [RSP+0x30]).
  • Возвращает S_OK (0) в RAX.

DR1 — AmsiScanString (x64, первые 5 аргументов в RCX, RDX, R8, R9, [RSP+0x28]):``` HRESULT AmsiScanString(HANDLE, LPCWSTR, LPCWSTR, HANDLE, AMSI_RESULT* pResult); [RSP+0x28]

root@kitploit:~
- Записывает `AMSI_RESULT_CLEAN (0)` в 5-й параметр (`pResult`, по адресу `[RSP+0x28]`).
- Возвращает `S_OK (0)` в `RAX`.

**DR2 — `WldpIsClassInApprovedList`** (первые 3 аргумента в `RCX, RDX, R8`):```
HRESULT WldpIsClassInApprovedList(const GUID* classId, PBOOL isApproved, DWORD evalCriteria);
                                         RCX             RDX             R8
  • Записывает TRUE в *isApproved (через RDX).
  • Возвращает S_OK (0) в RAX.
  • Следствие: оцениваемый класс содержимого считается «одобренным» политикой lockdown, и AMSI доверяет этому решению для данного класса.

DR3 — EtwEventWrite (первые 4 аргумента в RCX, RDX, R8, R9):``` ULONG EtwEventWrite(HANDLE RegHandle, PCEVENT_DESCRIPTOR EventDescriptor, ULONG UserDataCount, PEVENT_DATA_DESCRIPTOR UserData);

root@kitploit:~
- Возвращает `ERROR_SUCCESS (0)` в `RAX`, не затрагивая ни один выходной параметр.
- Следствие: поставщики ETW **не** получают **никаких** событий от перехваченного процесса, что подавляет журналирование выполнения скриптов, загрузки модулей, создания процессов и телеметрии AMSI.

### 5.5 Управление потоками и постоянство хуков

Поскольку аппаратные регистры отладки являются пер-потоковыми, движок должен непрерывно поддерживать хуки:

1. **Немедленный перехват** — `DllMain` (или `InstallHook`) перехватывает вызывающий поток с помощью `SetHwbpOnThread(GetCurrentThread())`.
2. **Обход всех потоков** — `HookAllThreads()` перечисляет каждый поток в процессе через снимок `TH32CS_SNAPTHREAD`, приостанавливает каждый посторонний поток (`SuspendThread`), применяет точки останова (`SetHwbpOnThread`), возобновляет его и закрывает дескриптор. Приостановка предотвращает гонку, при которой поток вызывает сбой в середине переключения контекста между `GetThreadContext` и `SetThreadContext`.
3. **Монитор постоянства** — `MonitorThreadProc` зацикливается с `Sleep(500)` и вызывает `HookAllThreads()` каждые 500 мс. Это **повторно устанавливает любые снятые точки останова** (например, внешним вызовом `SetThreadContext`, отладочным инструментом или при завершении/создании потока) и **покрывает потоки, созданные после первоначального перехвата**.
4. **Синхронизация** — `HookAllThreads` выполняется под `CRITICAL_SECTION` (`g_HookLock`), поэтому поток монитора и первоначальная процедура перехвата никогда не перемежают переключения контекста.
5. **Чистое завершение** — `UninstallHook` останавливает монитор, очищает `DR0–DR7` в каждом потоке и удаляет VEH.

> **Ответ на вопрос о «постоянстве хуков» явно:** да — если точки останова сняты с любого потока (другим агентом, отладчиком или EDR), поток монитора **повторно применяет их в течение 500 мс**. Кроме того, любой поток, созданный после загрузки DLL, перехватывается в течение одного цикла монитора. Единственный надёжный способ победить именно этот движок — завершить поток монитора *и* очистить VEH *и* снять регистры в одном и том же окне — или использовать анти-отладку, которая с самого начала запрещает `SetThreadContext`.

---

## Экспортируемый API

| Экспорт          | Сигнатура                         | Поведение                                                              |
|------------------|-----------------------------------|-----------------------------------------------------------------------|
| `InstallHook`    | `BOOL WINAPI InstallHook(void)`   | Разрешает цели, регистрирует VEH, перехватывает все потоки, запускает монитор. |
| `UninstallHook`  | `BOOL WINAPI UninstallHook(void)` | Останавливает монитор, очищает точки останова во всех потоках, удаляет VEH.   |
| `GetStats`       | `void WINAPI GetStats(void)`      | Выводит текущий статус хуков (через `OutputDebugStringA`) — адрес, счётчики попаданий. |

Счётчики попаданий (`g_HaveAmsiBuf`, `g_HaveAmsiStr`, `g_HaveWldp`, `g_HaveEtw`) поддерживаются с помощью `InterlockedIncrement` и выводятся в отладочный вывод, что полезно для проверки того, что перехват действительно происходит в лабораторной среде.

Обратите внимание, что `DllMain` сам выполняет полную последовательность перехвата при `DLL_PROCESS_ATTACH`, поэтому экспортируемые функции являются необязательными удобствами для сценариев (вы)грузки во время выполнения.

---

## Инструкции по сборке

**Требования:** Windows 10/11 x64, Visual Studio Build Tools (`icx.exe`), SDK.

Скомпилируйте DLL (x64):```bat
icx.exe /nologo /O3 /MT /EHsc "mora_hwbp.c" /link /DLL /out:"mora_hwbp.dll" /LIBPATH:"C:\Program Files (x86)\Intel\oneAPI\compiler\latest\lib"

Пояснение флагов:

FlagPurpose

Результатом является mora_hwbp.dll, который может быть загружен в целевой процесс.


Пример инъекции и использования

DLL должен быть загружен в процесс, использующий AMSI/WLDP/ETW — хост PowerShell является каноническим испытательным стендом. Загрузка может быть выполнена с помощью любого стандартного метода инъекции DLL. Минимальная автономная демонстрация с использованием Reflective/LoadLibrary-инъекции может быть выполнена с помощью небольшого загрузчика на C:```bat rem Run from an x64 developer prompt (example with a generic loader) loader.exe mora_hwbp.dll powershell.exe

root@kitploit:~
Или, для ручной проверки в лабораторных условиях, внедрите с помощью предпочитаемого вами инструмента, а затем проверьте из PowerShell:```powershell
# 1. Inject mora_hwbp.dll into the PowerShell process (via external tool).
# 2. Verify that classic AMSI test vectors now return clean.
"AmsiTestSample:7e72c3ce-861b-4339-8740-0ac1484c1386"

Только лабораторная проверка. Убедитесь с помощью отладчика или GetStats/OutputDebugString, что все четыре точки останова сообщают о срабатывании по мере выполнения содержимого скрипта.


Обнаружение и смягчение последствий (Blue Team)

Этот POC имеет двойное назначение: те же характеристики, которые делают его эффективным в атаке, являются именно тем, что защитникам следует искать.

Индикаторы компрометации (IOCs)

Рекомендуемые меры смягчения

  1. Сторожевые агенты/агенты самоконтроля — опрашивайте GetThreadContext(CONTEXT_DEBUG_REGISTERS) в критически важных процессах и проверяйте любой поток с ненулевыми DR0–DR3 вне утверждённых профилей отладчика.
  2. Аудит ETW ядра — включите трассировку Microsoft-Windows-Kernel-Process + Thread и оповещайте о NtGetContextThread/NtSetThreadContext, направленных на процессы, значимые для безопасности.
  3. Целостность пользовательских хуков EDR — поскольку аппаратные хуки обходят проверки памяти, полагайтесь на поведенческое обнаружение (хуки потребителей ETW ниже EtwEventWrite, ETW ядра, повторную проверку потребителем AMSI), а не только на целостность .text.
  4. Защитите монитор — в по-настоящему враждебных средах рассматривайте SetThreadContext для других процессов как явный сигнал высокой степени серьёзности.
  5. Усиление конечных точек — включите WDAC (который этот POC явно обходит для одобрения класса — не рассматривайте WDAC как самостоятельную защиту от внутрипроцессных инструментов), Credential Guard и защиту LSASS там, где это применимо.

Известные ограничения

  • Только x64 — перезапись смещений стека предполагает соглашение о вызовах x64 (аргументы RCX/RDX/R8/R9, затем [RSP+0x20…]). Вариант для x86 потребовал бы реконструкции параметров в стиле [EBP+…].
  • Только четыре слота — архитектура x64 предоставляет ровно четыре регистра точек останова; одним этим методом вы не можете перехватить более четырёх функций на поток.
  • Окно гонки монитора — существует (намеренно небольшое) окно между итерациями Sleep(500); чрезвычайно быстрое создание потоков в сочетании с агрессивной зачисткой теоретически может уйти вперёд монитора на несколько сотен миллисекунд.
  • Помехи со стороны анти-отладки — любой компонент, который активно отслеживает или очищает регистры отладки (настоящий отладчик, некоторые песочницы, отдельные EDR), будет мешать применению техники.
  • Статус на основе OutputDebugStringA — диагностика полагается на канал вывода отладки; в полностью урезанной/безголовой среде следует подключить отладчик или перенаправить вывод для лабораторного наблюдения.
  • Не является примитивом персистентности в памяти — это исключительно runtime-техника внутри процесса. Она не обеспечивает сохранности на диске/в реестре, не повышает привилегии и сама по себе не даёт горизонтального перемещения между процессами. Вся её цель — контролируемое изучение одного примитива перехвата.

Ссылки

  • Microsoft Learn — Интерфейс сканирования вредоносных программ (AMSI)
  • Microsoft Learn — Политика ограничения Windows (WLDP)
  • Microsoft Learn — Трассировка событий Windows (ETW)
  • Microsoft Learn — Структура CONTEXT и регистры отладки
  • Руководство разработчика по архитектурам Intel® 64 и IA-32, Том 3B — Регистры отладки (Dr0–Dr7, исключение #DB)

Лицензия и ответственное раскрытие информации

Этот проект распространяется под лицензией MIT — подробности см. в файле LICENSE.

Этот проект выпущен только для образовательных и оборонительных исследовательских целей. Если вы поставщик решений безопасности, участник blue team или инженер по обнаружению, мы призываем вас использовать содержимое этого репозитория для улучшения охвата обнаружения обхода на основе аппаратных точек останова. Если вы обнаружили, что эта техника используется во вредоносных целях, сообщите об этом через процесс ответственного раскрытия вашей организации и соответствующие каналы вендора/органов власти.

Используйте на свой страх и риск. Несанкционированное использование этой техники может нарушать действующее законодательство.

Скачать инструмент
РегистрПерехватываемая функцияМодульНазначение
DR0AmsiScanBufferamsi.dllНейтрализация сканирования содержимого AMSI
DR1AmsiScanStringamsi.dllНейтрализация сканирования строк AMSI
DR2WldpIsClassInApprovedListwldp.dllПринудительное одобрение класса WLDP (Device Guard / WDAC)
DR3EtwEventWritentdll.dllПодавление трассировки событий ETW
/O3Максимальная оптимизация (код функции, необязательно)
/MTСтатическая компоновка CRT (без зависимости от DLL времени выполнения)
/EHscОбработка исключений C++/SEH (необходимо для __try)
/DLLСоздание DLL с таблицей экспорта
АртефактНаблюдаемый признак
вызовы GetThreadContext / SetThreadContextВысокочастотные переключения контекста отладочных регистров в других процессах/потоках (ETW ядра: Microsoft-Windows-Kernel-Process/Thread APIs).
Ненулевые DR0–DR3Любой поток, чьи CONTEXT_DEBUG_REGISTERS содержат адрес пользовательского режима вне известных сценариев работы отладчика.
Биты локального разрешения DR7 (L0–L3) при R/W = 00Точки останова только на исполнение в потоках, не управляемых отладчиком, — явная аномалия.
Объём EXCEPTION_SINGLE_STEPВысокая частота исключений #DB (0x80000004), исходящих от VEH процесса.
Регистрация VEH первого шансаНедавно добавленный VEH (AddVectoredExceptionHandler) незадолго до шторма #DB.
TH32CS_SNAPTHREAD + SuspendThread/ResumeThreadПовторяющиеся паттерны перечисления потоков и приостановки (используются монитором с интервалом 500 мс).
Загрузка wldp.dll/amsi.dll через LoadLibraryW, если ранее не загруженыАномальные загрузки модулей в целевом процессе.
EtwEventWrite никогда не вызываетсяОтсутствие ожидаемых событий ETW (операционные журналы PowerShell молчат, пока выполняются скрипты).