⚙️ Процессы и Потоки
Создание процесса начинается с вызова
Kernel32!CreateProcess(), который через цепочку Ntdll → ядро попадает в Nt/ZwCreateFile(). Здесь создается основная структура процесса _EPROCESS, включающая ядро планировщика _KPROCESS. Каждый поток получает свою структуру _ETHREAD, связанную с _EPROCESS. Процессы идентифицируются по PID, а потоки по TID, что помогает ОС отслеживать и управлять их состоянием.⚙️ Object, Handle и Identifier
В глазах ядра всё является *объектом* — от файлов до процессов. Каждый объект имеет дескриптор (handle), который предоставляет к нему доступ. Когда, например, открывается файл через
CreateFile(), ядро создает объект и возвращает handle, по которому процесс может обращаться к объекту. Управление и подсчет ссылок на объекты происходит через два счетчика: Handle и Pointer, которые отслеживаются диспетчером объектов.⚙️ Исследование объектов
На физическом уровне объект — это структура данных с заголовком
OBJECT_HEADER. У него есть поле SecurityDescriptor, хранящее доступ к объекту (DACL/ACE). Обычно драйверы и API возвращают только тело объекта (смещение 30h), скрывая доступ к заголовку. Но, имея адрес объекта, можно получить и доступ к заголовку, что важно при анализе системной безопасности.⚙️ Таблица Дескрипторов Процесса
Каждому процессу выделяется своя таблица дескрипторов
HANDLE_TABLE. Это ускоряет доступ к дескрипторам и управляется системой автоматически, выделяя виртуальные страницы памяти. Размер одной записи — 16 байт, из которых первые 8 — это указатель на OBJECT_HEADER, а вторые — маска доступа GrantedAccess. ✏️ Продолжение следует: в следующей части обсудим больше интересных деталей системы, так что следите за обновлениями!
➡️ Читать подробнее
