- Статус
- Оффлайн
- Регистрация
- 13 Фев 2026
- Сообщения
- 445
- Реакции
- 10
Здарова, реверсеры. На днях ковырял методы проброса драйверов под EAC и наткнулся на интересное противоречие, которое немного пошатнуло мои убеждения о скрытности.
Сравнивал два конкретных подхода:
Самый сок в том, что второй метод, несмотря на присутствие в PsLoadedModuleList, живет под EAC гораздо бодрее. Казалось бы — драйвер светится в списке модулей, значит детект должен быть мгновенным. Но на практике kdmapper отлетает быстрее.
Основные проблемы Manual Mapping (векторы детекта):
Почему DSE Bypass + NtLoadDriver выглядит интереснее:
По факту, единственный реальный способ спалить такой драйвер — это сверка хешей модулей по вайтлисту или перехват через PsSetLoadImageNotifyRoutine в момент старта. После того как колбэк восстановлен, а драйвер загружен, система считает его своим.
Я сейчас плотно пересел на вариант с NtLoadDriver. Есть ощущение, что концепция "невидимости" через мануал маппинг сильно переоценена, когда речь заходит о серьезных античитах с мощным анализом памяти и стека.
Кто уже перекатился на подобные методы или допиливал свой маппер под нормальную работу со стеком?
Сравнивал два конкретных подхода:
- Классический Manual Mapping (kdmapper-style). Используем ExAllocatePool, раскидываем секции, резолвим импорты и вручную вызываем Entry Point. База, к которой все привыкли.
- Загрузка через DSE Bypass. Суть в патче CiValidateImageHeader в SeCiCallbacks, после чего вызывается NtLoadDriver, а оригинальный поинтер восстанавливается. Для R/W в ядре юзался gdrv.sys (Gigabyte).
Самый сок в том, что второй метод, несмотря на присутствие в PsLoadedModuleList, живет под EAC гораздо бодрее. Казалось бы — драйвер светится в списке модулей, значит детект должен быть мгновенным. Но на практике kdmapper отлетает быстрее.
Основные проблемы Manual Mapping (векторы детекта):
- Код живет в Pool Memory без привязки к конкретному модулю на диске.
- NMI Stackwalks легко вычисляют такой код, если прерывание срабатывает во время работы драйвера.
- Если мапнутый драйвер вызывает хукнутое API, адрес возврата не резолвится ни в один известный модуль.
- Палево через BigPoolTable.
Почему DSE Bypass + NtLoadDriver выглядит интереснее:
- Драйвер получает честную запись в PsLoadedModuleList и полноценный DRIVER_OBJECT.
- Стек выглядит чисто, так как код находится внутри легитимного (с точки зрения ОС) модуля.
- NMI Stackwalk не триггерится.
- Патч в SeCiCallbacks висит всего пару миллисекунд в момент загрузки.
По факту, единственный реальный способ спалить такой драйвер — это сверка хешей модулей по вайтлисту или перехват через PsSetLoadImageNotifyRoutine в момент старта. После того как колбэк восстановлен, а драйвер загружен, система считает его своим.
Код:
nt!SeCiCallbacks.CiValidateImageHeader = original_pointer;
Я сейчас плотно пересел на вариант с NtLoadDriver. Есть ощущение, что концепция "невидимости" через мануал маппинг сильно переоценена, когда речь заходит о серьезных античитах с мощным анализом памяти и стека.
Кто уже перекатился на подобные методы или допиливал свой маппер под нормальную работу со стеком?