11. Windows Processes
Windows Processes
Что такое процесс Windows?
Процесс Windows - это программа или приложение, выполняющееся на машине Windows. Процесс может быть запущен как пользователем, так и самой системой. Для выполнения задачи процесс потребляет такие ресурсы, как память, дисковое пространство и процессорное время.
Process Threads(Процессорные Потоки)
Процессы Windows состоят из одного или нескольких потоков, которые выполняются одновременно. Поток - это набор инструкций, которые могут выполняться независимо друг от друга в рамках процесса. Потоки внутри процесса могут взаимодействовать и обмениваться данными. Потоки планируются к выполнению операционной системой и управляются в контексте процесса.
Process Memory(Память процессов)
Процессы Windows также используют память для хранения данных и инструкций. Память выделяется процессу при его создании, а объем выделяемой памяти может быть задан самим процессом. Операционная система управляет памятью, используя как виртуальную, так и физическую память. Виртуальная память позволяет операционной системе использовать больше памяти, чем физически доступно, путем создания виртуального адресного пространства, к которому могут обращаться приложения. Эти виртуальные адресные пространства делятся на "страницы", которые затем выделяются процессам.
Memory Types
Processes can have different types of memory:
- Private memory предназначена для одного процесса и не может быть использована другими процессами. Этот тип памяти используется для хранения данных, специфичных для данного процесса.
- Mapped memory(Маппированная память) может быть общей для двух или более процессов. Она используется для обмена данными между процессами, например, общими библиотеками, общими сегментами памяти и общими файлами. Картируемая память видна другим процессам, но защищена от модификации другими процессами.
- Image memory(Память образов) содержит код и данные исполняемого файла.Она используется для хранения кода и данных, используемых процессом, таких как код, данные и ресурсы программы.Память образов часто связана с DLL-файлами, загружаемыми в адресное пространство процесса.
Process Environment Block (PEB)
Process Environment Block (PEB) - это структура данных в Windows, содержащая, помимо прочего, информацию о процессе, такую как его параметры, информация о запуске, информация о выделенной куче и загруженных DLL. Он используется операционной системой для хранения информации о процессах во время их выполнения, а также используется загрузчиком Windows для запуска приложений. В нем также хранится информация о процессе, такая как идентификатор процесса (PID) и путь к исполняемому файлу.
Каждый созданный процесс имеет свою собственную структуру данных PEB, которая будет содержать свой набор информации о нем.
PEB Structure
Структура PEB на языке C показана ниже. Зарезервированные члены этой структуры можно игнорировать.
typedef struct _PEB {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID Reserved4[3];
PVOID AtlThunkSListPtr;
PVOID Reserved5;
ULONG Reserved6;
PVOID Reserved7;
ULONG Reserved8;
ULONG AtlThunkSListPtr32;
PVOID Reserved9[45];
BYTE Reserved10[96];
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
BYTE Reserved11[128];
PVOID Reserved12[1];
ULONG SessionId;
} PEB, *PPEB;
Ниже приводится описание нерезервированных участников.
BeingDebugged
BeingDebugged - это флаг в структуре PEB, который указывает, отлаживается процесс или нет. Он устанавливается в 1 (TRUE), если процесс отлаживается, и в 0 (FALSE), если не отлаживается. Он используется загрузчиком Windows для определения того, запускать ли приложение с подключенным отладчиком или нет.
Ldr
Ldr - это указатель на структуру PEB_LDR_DATA
в блоке Process Environment Block (PEB). Эта структура содержит информацию о загруженных модулях библиотеки динамических ссылок (DLL) процесса. Она включает в себя список DLL, загруженных в процесс, базовый адрес каждой DLL и размер каждого модуля. Он используется загрузчиком Windows для отслеживания загруженных в процесс DLL. Структура PEB_LDR_DATA
показана ниже.
typedef struct _PEB_LDR_DATA {
BYTE Reserved1[8];
PVOID Reserved2[3];
LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
Ldr
может быть использован для определения базового адреса конкретной DLL, а также того, какие функции находятся в ее пространстве памяти. Это будет использовано в будущих модулях для создания собственной версии GetModuleHandleA/W для обеспечения дополнительной скрытности.
ProcessParameters
ProcessParameters - это структура данных в PEB. Она содержит параметры командной строки, передаваемые процессу при его создании. Загрузчик Windows добавляет эти параметры в структуру PEB процесса. ProcessParameters - это указатель на структуру RTL_USER_PROCESS_PARAMETERS
которая показана ниже.
typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
ProcessParameters
будет использоваться в будущих модулях для выполнения таких действий, как подмена командной строки.
AtlThunkSListPtr & AtlThunkSListPtr32
AtlThunkSListPtr
и AtlThunkSListPtr32
используются модулем ATL (Active Template Library) для хранения указателя на связанный список Thunking-функций. Thunking-функции используются для вызова функций, реализованных в другом адресном пространстве, которые часто представляют собой функции, экспортируемые из DLL-файла (Dynamic Link Library). Связанный список проходных функций используется модулем ATL для управления процессом проходки.
PostProcessInitRoutine
Поле PostProcessInitRoutine
в структуре PEB используется для хранения указателя на функцию, которая вызывается операционной системой после завершения инициализации TLS (Thread Local Storage) для всех потоков процесса. Эта функция может быть использована для выполнения любых дополнительных задач инициализации, необходимых для данного процесса.
Более подробно TLS и обратные вызовы TLS будут рассмотрены позже, когда это потребуется.
SessionId
SessionID в PEB - это уникальный идентификатор, присваиваемый одной сессии. Он используется для отслеживания активности пользователя в течение сессии.
Thread Environment Block (TEB)
Thread Environment Block (TEB) - это структура данных в Windows, хранящая информацию о потоке. Он содержит окружение потока, контекст безопасности и другую связанную с ним информацию. Он хранится в стеке потока и используется ядром Windows для управления потоками.
TEB Structure
The TEB struct in C is shown below. The reserved members of this struct can be ignored.
typedef struct _TEB {
PVOID Reserved1[12];
PPEB ProcessEnvironmentBlock;
PVOID Reserved2[399];
BYTE Reserved3[1952];
PVOID TlsSlots[64];
BYTE Reserved4[8];
PVOID Reserved5[26];
PVOID ReservedForOle;
PVOID Reserved6[4];
PVOID TlsExpansionSlots;
} TEB, *PTEB;
ProcessEnvironmentBlock (PEB)
Является указателем на структуру PEB, о которой говорилось выше. PEB находится внутри блока Thread Environment Block (TEB) и используется для хранения информации о текущем запущенном процессе.
TlsSlots
Слоты TLS (Thread Local Storage) - это места в TEB, которые используются для хранения данных, специфичных для конкретного потока. Каждый поток в Windows имеет свой собственный TEB, и каждый TEB имеет набор слотов TLS. Приложения могут использовать эти слоты для хранения данных, специфичных для данного потока, таких как переменные, дескрипторы, состояния и т.д.
TlsExpansionSlots
Слоты расширения TLS в TEB представляют собой набор указателей, используемых для хранения данных локального хранилища потока. Слоты TLS Expansion Slots зарезервированы для использования системными DLL.
Process And Thread Handles
В операционной системе Windows каждый процесс имеет свой идентификатор процесса или PID (Process ID), который операционная система присваивает ему при создании. PID используется для отличия одного запущенного процесса от другого. Аналогичная концепция применима и к запущенному потоку: запущенный поток имеет уникальный идентификатор, который используется для отличия его от остальных существующих в системе потоков (в любом процессе).
Эти идентификаторы могут быть использованы для открытия дескриптора процесса или потока с помощью описанных ниже WinAPI.
- OpenProcess - Открывает хэндл существующего объекта процесса по его идентификатору.
- OpenThread - Открывает хэндл существующего объекта потока по его идентификатору.
Более подробно эти WinAPI будут рассмотрены позже, когда это потребуется. Пока же достаточно знать, что открытый хэндл может быть использован для выполнения дальнейших действий с родственным ему объектом Windows, например, для приостановки процесса или потока.
Ручки всегда должны быть закрыты, если их использование больше не требуется, чтобы избежать handle leaking. Это достигается с помощью CloseHandle WinAPI вызова.