Следуйте инструкциям в видео ниже, чтобы узнать, как установить наш сайт как веб-приложение на главный экран вашего устройства.
Примечание: Эта функция может быть недоступна в некоторых браузерах.

✉️ Email: [email protected]
📲 Telegram канал: https://t.me/zer0kernelorg
💰 Donate (BTC): bc1qwvrgka76eeley8feqdxjxk2866sv0tnweylxjc
LoadLibrary и без создания записи в списке загруженных модулей. Библиотека существует в памяти как набор страниц, выделенных через VirtualAlloc, но не видна стандартным средствам перечисления. Это делает её привлекательной для обхода детектов, основанных на мониторинге загрузки модулей.LoadLibrary или LoadLibraryEx загрузчик Windows выполняет последовательность действий:NtMapViewOfSection — создаёт секцию, привязанную к файлу, и проецирует её в адресное пространство процесса.DllMain с причиной DLL_PROCESS_ATTACH.InLoadOrderModuleList структуры PEB_LDR_DATA.NtQueryVirtualMemory с классом MemoryMappedFilenameInformation) система вернёт путь к файлу, а EnumProcessModules увидит модуль в списке.IMAGE_DOS_HEADER, IMAGE_NT_HEADERS, таблица секций, директории импортов и релокаций.VirtualAlloc с флагом MEM_RESERVE | MEM_COMMIT и защитой PAGE_EXECUTE_READWRITE (или поэтапно с изменением прав). Размер — SizeOfImage из optional header.ntdll.dll и выполняет инструкцию syscall без обращения к API-функциям. Это позволяет обойти userland-хуки, которые EDR-продукты устанавливают на экспортируемые функции ntdll.dll для перехвата и инспекции вызовов.ntdll.dll — например, NtAllocateVirtualMemory, NtWriteVirtualMemory, NtCreateThreadEx. Хук заменяет первые байты функции на безусловный переход (jmp) к коду агента, который логирует параметры вызова, проверяет их на подозрительность и при необходимости блокирует операцию.; Оригинальный пролог NtAllocateVirtualMemory:
4C 8B D1 mov r10, rcx
B8 XX XX 00 00 mov eax, <SSN>
0F 05 syscall
C3 ret
; После хука EDR:
E9 XX XX XX XX jmp <hook_handler>
...
NtAllocateVirtualMemory через стандартный механизм импорта, управление сначала попадает в хук EDR. Hell's Gate решает эту проблему: вместо вызова функции из ntdll.dll код самостоятельно находит SSN и выполняет syscall напрямую, минуя хук.ntdll.dll. Базовый адрес модуля получается через PEB (Process Environment Block):PPEB pPeb = (PPEB)__readgsqword(0x60);
PLDR_DATA_TABLE_ENTRY pLdr = (PLDR_DATA_TABLE_ENTRY)
((PBYTE)pPeb->LoaderData->InMemoryOrderModuleList.Flink->Flink - 0x10);
ULONG_PTR uModule = (ULONG_PTR)(pLdr->DllBase);
IMAGE_EXPORT_DIRECTORY, которая содержит три массива:| Поле | Назначение |
|---|---|
AddressOfNames | RVA массива имён экспортируемых функций |
| ... |
IMAGE_DIRECTORY_ENTRY_IMPORT указывает на массив структур IMAGE_IMPORT_DESCRIPTOR, каждая из которых описывает одну импортируемую DLL.typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics;
DWORD OriginalFirstThunk; // RVA к INT (Import Name Table)
};
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name; // RVA к имени DLL (ASCII)
DWORD FirstThunk; // RVA к IAT (Import Address Table)
} IMAGE_IMPORT_DESCRIPTOR;
IMAGE_IMPORT_BY_NAME с именами функций. Используется загрузчиком для разрешения импортов..ko), который загружается в адресное пространство ядра во время работы системы без перезагрузки. Модули позволяют добавлять драйверы, файловые системы, сетевые протоколы и отладочные механизмы «на лету», не пересобирая ядро целиком..ko — это обычный ELF-объект с дополнительными секциями, специфичными для ядра:| Секция | Назначение |
|---|---|
.modinfo | Метаданные модуля: автор, описание, зависимости, параметры, лицензия |
__ksymtab | Таблица экспортируемых символов |
__kcrctab | CRC-значения экспортируемых символов (при включённом CONFIG_MODVERSIONS) |
__versions | Имена и CRC импортируемых символов (при CONFIG_BASIC_MODVERSIONS) |
.init.text | Код, выполняемый только при инициализации модуля |
.exit.text | Код, выполняемый только при выгрузке модуля |
.gnu.linkonce.this_module | Структура struct module, через которую ядро управляет модулем |
.init.text освобождаются, что экономит память. Секция .exit.text остаётся в памяти, если модуль не поддерживает выгрузку (например, встроенный драйвер критичной подсистемы).insmod module.ko или modprobe module, происходит следующая последовательность:CONFIG_MODVERSIONS, CRC каждого импортируемого символа сравнивается с CRC, записанным в __versions модуля. Несоответствие — отказ в загрузке.VirtualAllocEx, WriteProcessMemory и CreateRemoteThread, EDR-агент, перехватывающий userland-функции в ntdll.dll или kernel32.dll, видит каждый шаг. Техника direct syscalls обходит этот слой: вместо вызова экспортируемой функции из ntdll.dll код напрямую выполняет инструкцию syscall, подставляя номер системного вызова в регистр eax/rax и передавая аргументы через стек или регистры по конвенции x64.NtAllocateVirtualMemory, NtWriteVirtualMemory, NtProtectVirtualMemory и NtCreateThreadEx, не срабатывают, потому что исполнение не проходит через тело функции в ntdll.dll. Для защитника это означает потерю одного из самых удобных слоёв телеметрии — но не всех.| Шаг | Системный вызов | Назначение |
|---|---|---|
| 1 | NtAllocateVirtualMemory | Выделение региона памяти в целевом процессе с правами PAGE_READWRITE |
| 2 | NtWriteVirtualMemory | Запись полезной нагрузки в выделенный регион |
| 3 | NtProtectVirtualMemory | Смена защиты региона на PAGE_EXECUTE_READWRITE |
| 4 | NtCreateThreadEx | Создание потока с точкой входа в записанный код |
ProcessHandle — дескриптор целевого процесса. Если дескриптор не является псевдодескриптором текущего процесса ((HANDLE)-1), значит операция направлена на чужой процесс. Это ключевой артефакт, который сохраняется вне зависимости от способа вызова.VirtualAllocEx + WriteProcessMemory + CreateRemoteThread — оставляют характерный артефакт: регион памяти с правами PAGE_EXECUTE_READWRITE, не привязанный ни к какому модулю. Многие EDR и memory scanners ищут именно такие регионы.PAGE_EXECUTE_READ после записи, а сам регион числится как часть валидного модуля. Это снижает вероятность детекта по памяти, но не устраняет артефакты полностью.setupapi.dll, version.dll, dbghelp.dll и другие модули, которые редко вызываются напрямую.LoadLibraryA или LoadLibraryExA в целевом процессе (напрямую или через CreateRemoteThread). Если модуль уже загружен — используется его текущий базовый адрес.GetProcAddress находится адрес...VirtualAllocEx + WriteProcessMemory при инъекции кода.VirtualAllocEx и WriteProcessMemory — две функции, на которые настроено большинство правил детектирования. Вместо них используется цепочка CreateFileMapping → MapViewOfFile → MapViewOfFile2, которая выглядит менее подозрительно для статических сигнатур.| Тип | Привязка к диску | Время жизни | Типичное применение |
|---|---|---|---|
| Персистентный | Да, связан с файлом на диске | Данные сохраняются после закрытия последнего дескриптора | Работа с большими файлами |
| Неперсистентный (анонимный) | Нет | Данные теряются при закрытии последнего дескриптора | IPC, инъекции |
CreateFileMapping вызывается с INVALID_HANDLE_VALUE вместо дескриптора реального файла. Раздел существует только в памяти и не оставляет артефактов на диске.CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, payloadSize, NULL) — создаёт анонимный раздел с правами на исполнение.MapViewOfFile(hFile, FILE_MAP_WRITE | FILE_MAP_EXECUTE, 0, 0, payloadSize) — проецирует раздел в текущий процесс.memcpy копирует шеллкод в полученный адрес.#include <windows.h>
#include <stdio.h>
BOOL LocalMapInject(IN PBYTE pPayload, IN SIZE_T sPayloadSize, OUT...
write():syscall на x86-64).sysret на x86-64).errno и возвращает −1.syscall.errno и возвращает −1 вызывающему коду.| Метод | Уровень | Область действия | Сложность обнаружения |
|---|---|---|---|
| Inline hooking (трамплин) | Машинный код функции | Конкретная функция в процессе | Средняя |
| IAT hooking | Таблица импорта | Все вызовы через IAT модуля | Низкая |
| SetWindowsHookEx | Механизм сообщений Windows | Глобально или по потоку | Низкая |
| SSDT hooking | Таблица системных сервисов ядра | Все процессы | Высокая (требует Ring 0) |
mov r10, <адрес_перехватчика> ; 10 байт: 49 BA + 8 байт адреса
jmp r10 ; 3 байта: 41 FF E2
TRAMPOLINE_SIZE для x64).mov eax, <адрес_перехватчика> ; 5 байт: B8 + 4 байта адреса
jmp eax ; 2 байта: FF...
CreateRemoteThread здесь не срабатывает.QueueUserAPC:DWORD QueueUserAPC(
PAPCFUNC pfnAPC, // указатель на функцию для выполнения
HANDLE hThread, // дескриптор целевого потока
ULONG_PTR dwData // параметр, передаваемый в функцию
);
| Функция | Alertable | Условие |
|---|---|---|
SleepEx | Да | bAlertable = TRUE |
WaitForSingleObjectEx | Да | bAlertable = TRUE |
WaitForMultipleObjectsEx | Да | bAlertable = TRUE |
| ... |