11. Windows Processes

Windows Processes

Что такое процесс Windows?

Процесс Windows - это программа или приложение, выполняющееся на машине Windows. Процесс может быть запущен как пользователем, так и самой системой. Для выполнения задачи процесс потребляет такие ресурсы, как память, дисковое пространство и процессорное время.

Process Threads(Процессорные Потоки)

Процессы Windows состоят из одного или нескольких потоков, которые выполняются одновременно. Поток - это набор инструкций, которые могут выполняться независимо друг от друга в рамках процесса. Потоки внутри процесса могут взаимодействовать и обмениваться данными. Потоки планируются к выполнению операционной системой и управляются в контексте процесса.

Process Memory(Память процессов)

Процессы Windows также используют память для хранения данных и инструкций. Память выделяется процессу при его создании, а объем выделяемой памяти может быть задан самим процессом. Операционная система управляет памятью, используя как виртуальную, так и физическую память. Виртуальная память позволяет операционной системе использовать больше памяти, чем физически доступно, путем создания виртуального адресного пространства, к которому могут обращаться приложения. Эти виртуальные адресные пространства делятся на "страницы", которые затем выделяются процессам.

Memory Types

Processes can have different types of memory:

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.

Более подробно эти WinAPI будут рассмотрены позже, когда это потребуется. Пока же достаточно знать, что открытый хэндл может быть использован для выполнения дальнейших действий с родственным ему объектом Windows, например, для приостановки процесса или потока.

Ручки всегда должны быть закрыты, если их использование больше не требуется, чтобы избежать handle leaking. Это достигается с помощью CloseHandle WinAPI вызова.