API определен в заголовочном файле sysroot-*-kos/include/coresrv/task/task_api.h из состава KasperskyOS SDK.
Основные возможности API:
Сведения о функциях API приведены в таблице ниже.
Библиотека libkos также предоставляет высокоуровневый API для управления процессами. Рекомендуется использовать именно этот API. Низкоуровневый API следует использовать, если недостаточно возможностей высокоуровневого API.
Создание и запуск процесса
Для создания и запуска процесса требуются следующие функции API:
KnTaskCreate() или KnTaskCreateEx();KnTaskReseedAslr();KnTaskVmReserveForElf();KnTaskLoadSeg();KnTaskLoadElfSyms();KnTaskSetInitialState();KnTaskSetEnv();KnTaskResume().Эти функции предназначены для использования библиотекой libkos. Разработчику решения для создания и запуска процессов нужно использовать функции API task.h. При этом для многих функций API task_api.h, которые предназначены для применения разработчиком решения, входным параметром является дескриптор процесса. Чтобы получить дескриптор процесса, нужно вызвать функцию KosTaskGetHandle() из API task.h. Дескриптор процесса можно передать другому процессу через IPC.
Функция KnTaskVmReserveForElf() предназначена не только для использования библиотекой libkos, но и для применения разработчиком решения. Эта функция резервирует регион виртуальной памяти для загрузки ELF-образа. Через входные параметры task и elfDescr принимает дескриптор процесса и указатель на объект, описывающий ELF-образ, соответственно. (Объект, описывающий ELF-образ, создается функцией KnElfOpen() из API elf_api.h.) Через выходной параметр relocBase передает смещение загрузки ELF-образа. Если ELF-файл имеет тип DYN, передает случайное смещение, для ELF-файла другого типа передает нулевое смещение. Смещение загрузки ELF-образа является входным параметром функций KosTaskLoadSegments(), KosTaskInitFromSegEx() из API task.h, а также функции KnElfCreateVmSegEx() из API elf_api.h. Случайное смещение загрузки ELF-образа является элементом поддержки рандомизации размещения адресного пространства процесса. Рандомизация размещения адресного пространства (англ. Address Space Layout Randomization, ASLR) – это размещение структур данных (ELF-образа, динамических библиотек, стека и кучи) в памяти процесса по случайным адресам с целью усложнения эксплуатации уязвимостей, которые связаны с заранее известной злоумышленнику структурой адресного пространства процесса.
Перед запуском процесс получает данные от своего родительского процесса через страницу статических соединений. Страница статических соединений (англ. Static Connection Page, SCP) – набор структур, содержащих данные для статического создания IPC-каналов, параметры запуска и переменные окружения программы. Родительский процесс записывать данные в SCP дочернего процесса вызовом функции KnTaskSetEnv(). Дочерний процесс при запуске считывает данные из SCP вызовом функции KnTaskGetEnv(), а затем удаляет SCP вызовом функции KnTaskFreeEnv(). Функции KnTaskGetEnv() и KnTaskFreeEnv(), как и функция KnTaskSetEnv(), предназначены для использования библиотекой libkos.
По умолчанию начальный поток процесса является стандартным потоком исполнения. (О классах планирования потоков исполнения см. "Управление потоками исполнения (низкоуровневый API thread_api.h)".) Чтобы получить приоритет начального потока процесса, нужно вызвать функцию KnTaskGetInitialThreadPriority(). Чтобы изменить приоритет начального потока процесса, нужно вызвать функцию KnTaskSetInitialThreadPriority(). Чтобы изменить класс планирования и/или приоритет начального потока процесса, нужно вызвать функцию KnTaskSetInitialPolicy(). Все три функции можно использовать после установки точки входа в программу, а также после запуска процесса. Точку входа в программу устанавливают все функции создания процесса из API task.h, кроме KosTaskCreate(). Если процесс создан функцией KosTaskCreate(), точка входа будет установлена после вызова функции KosTaskLoadSegments().
Завершение процесса
Завершение процесса включает в себя:
При завершении процесса все дескрипторы, которыми он владеет, закрываются. Если закрытый дескриптор был единственным дескриптором ресурса, то этот ресурс освобождается.
Процесс завершается по следующим причинам:
Вызвана функция KnTaskExit(), или завершены все потоки процесса.
Вызвана функция KnTaskTerminate().
Вызовом функции KnTaskPanic() процесс может специально инициировать возникновение исключения, которое не может быть обработано и приводит к завершению этого процесса. Это требуется, чтобы процесс мог гарантированно завершить себя. (Например, если в процессе есть потоки исполнения, привязанные к прерываниям, то функция KnTaskExit() не может завершить этот процесс, а функция KnTaskPanic() позволяет сделать это.)
Коды завершения процессов определяются разработчиком решения. Эти коды нужно указывать в параметре status функции KnTaskExit(). Если процесс завершился в результате завершения всех его потоков, то кодом завершения этого процесса будет код завершения его начального потока. Чтобы получить код завершения процесса, который завершился по собственной инициативе, нужно вызвать функцию KnTaskGetExitCode().
Чтобы получить сведения о причине завершения процесса, нужно вызвать функцию KnTaskGetExitStatus(). Эта функция позволяет определить, был ли процесс завершен по собственной инициативе, по внешнему запросу или аварийно.
Чтобы получить сведения о необработанном исключении, которое привело к аварийному завершению процесса, нужно вызвать функцию KnTaskGetExceptionInfo(). Эти сведения включают код исключения и контекст потока исполнения, в котором это исключение возникло.
Если процесс создан одной из функций API task.h с указанием флага KOS_TASK_FLAG_DUMPABLE, то в результате необработанного исключения этот процесс не завершится, а перейдет в "замороженное" состояние. "Замороженное" состояние процесса – это такое состояние процесса, при котором исполнение его потоков завершилось в результате необработанного исключения, но ресурсы не освободились, чтобы можно было получить сведения об этом процессе. Чтобы получить контекст потока исполнения, входящего в процесс, который находится в "замороженном" состоянии, нужно вызвать функцию KnTaskGetThreadContext(). Чтобы получить сведения о регионе виртуальной памяти, принадлежащем процессу, который находится в "замороженном" состоянии, нужно вызвать функцию KnTaskGetNextVmRegion(). Эти сведения включают такую информацию, как базовый адрес и размер региона виртуальной памяти, права доступа к нему. Перед переходом процесса в "замороженное" состояние выполняется вывод данных обратной трассировки стека (сведений о стеке вызовов) для потока исполнения, в котором возникло необработанное исключение. Чтобы завершить процесс, который находится в "замороженном" состоянии, нужно вызвать функцию KnTaskTerminateAfterFreezing().
Чтобы объект ядра, который описывает процесс, был удален после завершения этого процесса, нужно до или после завершения этого процесса закрыть или отозвать каждый его дескриптор во всех процессах, которые владеют этими дескрипторами.
Обработка исключений
Чтобы зарегистрировать функцию обработки исключений для процесса, нужно вызвать из этого процесса функцию KnTaskSetExceptionHandler(). Эта функция дерегистрирует предыдущую функцию обработки исключений и возвращает ее идентификатор. Сохранив этот идентификатор, в дальнейшем можно снова зарегистрировать предыдущую функцию обработки исключений.
Функция обработки исключений вызывается при возникновении исключения в любом потоке процесса. В случае успешной обработки исключения эта функция возвращает значение, отличное от ноля, в противном случае она возвращает ноль. Входным параметром функции обработки исключений является структура, содержащая сведения об исключении. Тип этой структуры определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK.
Если функции обработки исключений, зарегистрированной на уровне процесса, не удалось успешно обработать исключение, будет вызвана функция обработки исключений, зарегистрированная на уровне потока исполнения, в котором возникло это исключение. (Об обработке исключений на уровне потоков исполнения см. "Управление потоками исполнения (низкоуровневый API thread_api.h)".)
Получение сведений о процессе
Чтобы получить идентификатор процесса (PID), нужно вызвать функцию KnTaskGetId() или KnTaskGetIdByHandle(). Функция KnTaskGetId() позволяет получить PID вызывающего процесса. Функция KnTaskGetIdByHandle() позволяет получить PID процесса по его дескриптору.
Чтобы получить имя процесса, нужно вызвать из этого процесса функцию KnTaskGetName().
Чтобы получить путь к исполняемому файлу, из которого создан процесс, нужно вызвать из этого процесса функцию KnTaskGetPath().
Передача дескрипторов дочернему процессу
Родительский процесс может передавать дескрипторы дочернему процессу, который еще не запущен. (Общие сведения о передаче дескрипторов приведены в разделе "Передача дескрипторов".) Передать дескриптор дочернему процессу позволяет функция KnTaskTransferResource(). Эта функция предназначена для использования библиотекой libkos. Разработчику решения нужно использовать функцию KosTaskTransferResource() из API task.h, которая не только передает дескриптор, но и копирует его в SCP дочернего процесса, чтобы дочерний процесс мог найти переданный дескриптор вызовом функции KosTaskLookupResource() из API task.h.
Резервирование памяти в дочернем процессе
API включает функции KnTaskVmReserve() и KnTaskVmFree(), которые позволяют соответственно резервировать и освобождать регионы виртуальной памяти в дочернем процессе, для которого еще не задана точка входа в программу. Эти функции предназначены для использования библиотекой libkos.
Получение адреса GSI
Общая системная информация (англ. Global System Information, GSI) – структура, содержащая системные сведения, такие как число отсчетов таймера с момента запуска ядра, число отсчетов таймера в секунду, число процессоров (вычислительных ядер) в активном состоянии, данные о процессорном кеше. Тип структуры определен в заголовочном файле sysroot-*-kos/include/task/pcbpage.h из состава KasperskyOS SDK. Получить адрес GSI позволяет функция KnTaskGetGsi(). Эта функция предназначена для использования библиотекой libc.
Получение адреса PCB
Блок управления процессом (англ. Process Control Block, PCB) – структура, содержащая сведения о процессе, которые используются ядром для управления этим процессом. Тип структуры определен в заголовочном файле sysroot-*-kos/include/task/pcbpage.h из состава KasperskyOS SDK. Получить адрес PCB позволяет функция KnTaskGetPcb(). Эта функция предназначена для использования библиотекой libc.
Получение адресов и размеров таблицы символов .symtab и таблицы строк .strtab
Получить адреса и размеры таблицы символов .symtab и таблицы строк .strtab, загруженных в память процесса, позволяет функция KnTaskGetElfSyms(). Эта функция предназначена для механизма, который выводит данные обратной трассировки стека, работая в пользовательском режиме (не в режиме ядра).
Сведения о функциях API
Функции task_api.h
Функция |
Сведения о функции |
|---|---|
|
Назначение Создает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Создает процесс. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения В параметре
|
|
Назначение Позволяет получить адрес GSI для вызывающего процесса. Параметры Нет. Возвращаемые значения Указатель на GSI. Тип данных для хранения GSI определен в заголовочном файле |
|
Назначение Позволяет получить адрес блока управления процессом (PCB) для вызывающего процесса. Параметры Нет. Возвращаемые значения Указатель на PCB. Тип данных для хранения PCB определен в заголовочном файле |
|
Назначение Позволяет получить адрес SCP вызывающего процесса. Параметры
Возвращаемые значения Указатель на SCP или |
|
Назначение Записывает данные в SCP процесса. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Удаляет SCP вызывающего процесса. Параметры Нет. Возвращаемые значения В случае успеха возвращает |
|
Назначение Запускает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Завершает вызывающий процесс. Параметры
Возвращаемые значения Код ошибки. Дополнительные сведения Не завершает процесс, если в нем есть потоки исполнения, привязанные к прерываниям. |
|
Назначение Завершает процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить сведения о причине завершения процесса. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения Через параметры
|
|
Назначение Позволяет получить сведения о необработанном исключении, которое привело к аварийному завершению процесса. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить контекст потока исполнения, входящего в процесс, который находится в "замороженном" состоянии. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить сведения о регионе виртуальной памяти, принадлежащем процессу, который находится в "замороженном" состоянии. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Завершает процесс, который находится в "замороженном" состоянии. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить код завершения процесса, который завершился по собственной инициативе. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить идентификатор процесса (PID) для вызывающего процесса. Параметры Нет. Возвращаемые значения Идентификатор процесса. Тип идентификатора определен в заголовочном файле |
|
Назначение Позволяет получить имя вызывающего процесса. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить путь к исполняемому файлу, из которого создан вызывающий процесс. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить приоритет начального потока процесса. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Задает приоритет начального потока процесса. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Регистрирует функцию обработки исключений для вызывающего процесса. Параметры
Возвращаемые значения Идентификатор предыдущей зарегистрированной функции обработки исключений или |
|
Назначение Загружает сегмент ELF-образа в память процесса. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Резервирует регион виртуальной памяти в процессе. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения В параметре
Допустимые комбинации флагов, задающих права доступа к региону виртуальной памяти:
|
|
Назначение Резервирует регион виртуальной памяти в процессе для загрузки ELF-образа. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Освобождает регион виртуальной памяти, зарезервированный вызовом функции Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Задает точку входа в программу и смещение загрузки ELF-образа. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Загружает таблицу символов Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Задает класс планирования и приоритет начального потока процесса. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения В параметре В параметре |
|
Назначение Задает начальное значение генератора случайных чисел для поддержки ASLR в заданном процессе. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить адреса и размеры таблицы символов Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения Если таблица символов |
|
Назначение Позволяет получить идентификатор процесса (PID). Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Инициирует возникновение исключения, которое не может быть обработано и приводит к завершению вызывающего процесса. Параметры Нет. Возвращаемые значения Нет. |
|
Назначение Передает дескриптор процессу, который еще не запущен. Параметры
Возвращаемые значения В случае успеха возвращает |