The API is defined in the header file sysroot-*-kos/include/coresrv/task/task_api.h from the KasperskyOS SDK.
Main capabilities of the API:
Information about API functions is provided in the table below.
The libkos library also provides a high-level API for process management. It is recommended to use this specific API. The low-level API should be used only if the high-level API does not have sufficient capabilities.
Creating and starting a process
The following API functions are required for creating and running a process:
KnTaskCreate() or KnTaskCreateEx();KnTaskReseedAslr();KnTaskVmReserveForElf();KnTaskLoadSeg();KnTaskLoadElfSyms();KnTaskSetInitialState();KnTaskSetEnv();KnTaskResume().These functions are intended for use by the libkos library. The solution developer must use the task.h API functions to create and run processes. For many functions of the task_api.h API that are intended for use by the solution developer, the input parameter is the process handle. To get the handle of a process, call the KosTaskGetHandle() function from the task.h API. The handle of a process can be transferred to another process via IPC.
The KnTaskVmReserveForElf() function is intended for use both by the libkos library and by the solution developer. This function reserves a region of virtual memory for loading the ELF image. The task and elfDescr input parameters are used to accept the process handle and the pointer to the object describing the ELF image, respectively. (The object describing the ELF image is created by the KnElfOpen() function from the elf_api.h API.) The relocBase output parameter is used to pass the ELF image load offset. If the ELF file has the DYN type, it passes a random offset. It passes a zero offset for an ELF file of a different type. The ELF image load offset is an input parameter of the KosTaskLoadSegments() and KosTaskInitFromSegEx() functions from the task.h API and of the KnElfCreateVmSegEx() function from the elf_api.h API. A random ELF image load offset is part of the address space layout randomization (ASLR) support. Address Space Layout Randomization (ASLR) is the use of random addresses for the location of data structures (ELF image, dynamic libraries, stack and heap) in process memory to make it harder to exploit vulnerabilities associated with a conventional process address space structure that is known by a hacker in advance.
Before a process is started, it receives data from its parent process via a static connection page. A static connection page (SCP) is a set of structures containing data for statically creating IPC channels, startup parameters, and environment variables of a program. A parent process writes data to the SCP of a child process by calling the KnTaskSetEnv() function. When a child process is started, it reads data from the SCP by calling the KnTaskGetEnv() function, then it deletes the SCP by calling the KnTaskFreeEnv() function. Like the KnTaskSetEnv() function, the KnTaskGetEnv() and KnTaskFreeEnv() functions are intended for use by the libkos library.
By default, the initial thread of a process is a standard thread. (For details about thread scheduler classes, see Managing threads (low-level API thread_api.h) To get the priority of the initial thread of a process, call the KnTaskGetInitialThreadPriority() function. To change the priority of the initial thread of a process, call the KnTaskSetInitialThreadPriority() function. To change the scheduler class and/or priority of the initial thread of a process, call the KnTaskSetInitialPolicy() function. All three functions can be used after setting the program entry point and after starting the process. The program entry point is set by all the process creation functions from the task.h API, except for KosTaskCreate(). If the process is created by the KosTaskCreate() function, the entry point will be set after calling the KosTaskLoadSegments() function.
Terminating a process
Process termination includes the following:
When a process is terminated, all the handles that it owns are closed. If a closed handle was the only handle of a resource, this resource is freed.
A process can be terminated for the following reasons:
The KnTaskExit() function is called, or all threads of the process are terminated.
The KnTaskTerminate() function is called.
By calling the KnTaskPanic() function, a process can purposefully initiate an exception that cannot be handled and leads to the process terminating. This assures that the process can terminate itself. (For example, if the process contains threads attached to interrupts, the KnTaskExit() function cannot terminate this process but the KnTaskPanic() function can.)
Process exit codes are defined by the solution developer. These codes must be specified in the status parameter of the KnTaskExit() function. If a process was terminated due to the termination of all its threads, the exit code of this process will be the exit code of its initial thread. To get the exit code of a process that was terminated on its own initiative, call the KnTaskGetExitCode() function.
To get information regarding the reason for process termination, call the KnTaskGetExitStatus() function. This function determines whether a process was terminated on its own initiative, by external request, or unexpectedly.
To get information about an unhandled exception that led to an unexpected termination of a process, call the KnTaskGetExceptionInfo() function. This information includes the exception code and the context of the thread in which this exception occurred.
If the process was created by one of the functions of the task.h API with the specified KOS_TASK_FLAG_DUMPABLE flag, an unhandled exception will cause this process to go into a "frozen" state and the process will not terminate. When a process is switched to a "frozen" state, its threads are terminated as a result of the unhandled exception but its resources are not freed, which means that you can get information about this process. To get the context of a thread that is part of a frozen process, call the KnTaskGetThreadContext() function. To get information about the virtual memory region that belongs to a frozen process, call the KnTaskGetNextVmRegion() function. This information includes the base address and size of the virtual memory region, and the access rights to this virtual memory region. Before a process switches to the frozen state, stack backtrace data (call stack information) is printed for the thread in which the unhandled exception occurred. To terminate a frozen process, call the KnTaskTerminateAfterFreezing() function.
To ensure that the kernel object describing a process is deleted after this process is terminated, each of its handles must be closed or revoked in all processes that own these handles before or after this process is terminated.
Handling exceptions
To register an exception handling function for a process, call the KnTaskSetExceptionHandler() function from this process. This function deregisters the previous exception handling function and returns its ID. By saving this ID, you can subsequently register the previous exception handling function again.
An exception handling function is called when an exception occurs in any process thread. If the exception is successfully handled, this function returns a value other than zero. Otherwise it returns zero. The input parameter of the exception handling function is a structure containing information about the exception. The type of this structure is defined in the header file sysroot-*-kos/include/thread/tcbpage.h from the KasperskyOS SDK.
If an exception handling function registered at the process level failed to successfully handle an exception, the exception handling function registered at the level of the thread in which the exception occurred will be called. (For details about handling exceptions at the thread level, see Managing threads (low-level API thread_api.h)).
Receiving information about a process
To get the process ID (PID), call the KnTaskGetId() or KnTaskGetIdByHandle() function. The KnTaskGetId() function lets you get the PID of the calling process. The KnTaskGetIdByHandle() function lets you get the PID of a process based on its handle.
To get the name of a process, call the KnTaskGetName() function from this process.
To get the path to the executable file from which the process was created, call the KnTaskGetPath() function from this process.
Transferring handles to a child process
A parent process can transfer handles to a child process that is not yet running. (General information about transferring handles is provided in the Transferring handles section.) The KnTaskTransferResource() function lets you transfer a handle to a child process. This function is intended for use by the libkos library. The solution developer needs to use the KosTaskTransferResource() function from the task.h API, which not only transfers the handle, but also copies it to the SCP of the child process so that the child process can find the transferred handle by calling the KosTaskLookupResource() function from the task.h API.
Reserving memory in a child process
The API includes the KnTaskVmReserve() and KnTaskVmFree() functions, which reserve and free virtual memory regions, respectively, in a child process that does not yet have a defined program entry point. These functions are intended for use by the libkos library.
Getting the GSI address
Global system information (GSI) is a structure containing system information, such as the timer count since the kernel started, the timer counts per second, the number of processors (processor cores) in active state, and processor cache data. The type of structure is defined in the header file sysroot-*-kos/include/task/pcbpage.h from the KasperskyOS SDK. The KnTaskGetGsi() function gets the GSI address. This function is intended for use by the libc library.
Getting the PCB address
A process control block (PCB) is a structure containing process information that is used by the kernel to manage this process. The type of structure is defined in the header file sysroot-*-kos/include/task/pcbpage.h from the KasperskyOS SDK. The KnTaskGetPcb() function gets the PCB address. This function is intended for use by the libc library.
Getting the addresses and sizes of the symbol table.symtab and the string table .strtab
The KnTaskGetElfSyms() function lets you get the addresses and sizes of the symbol table .symtab and the string table .strtab loaded into the process memory. This function is intended for a mechanism that prints stack backtrace data when operating in user mode (not in kernel mode).
Information about API functions
task_api.h functions
Function |
Information about the function |
|---|---|
|
Purpose Creates a process. Parameters
Returned values If successful, the function returns |
|
Purpose Creates a process. Parameters
Returned values If successful, the function returns Additional information In the
|
|
Purpose Gets the GSI address for the calling process. Parameters N/A Returned values Pointer to the GSI. The data type for GSI storage is defined in the header file |
|
Purpose Gets the address of the process control block (PCB) for the calling process. Parameters N/A Returned values Pointer to the PCB. The data type for PCB storage is defined in the header file |
|
Purpose Gets the SCP address of the calling process. Parameters
Returned values Pointer to the SCP, or |
|
Purpose Writes data to the SCP of a process. Parameters
Returned values If successful, the function returns |
|
Purpose Deletes the SCP of the calling process. Parameters N/A Returned values If successful, the function returns |
|
Purpose Resumes a process. Parameters
Returned values If successful, the function returns |
|
Purpose Terminates the calling process. Parameters
Returned values Error code. Additional information Does not terminate the process as long as it contains threads attached to interrupts. |
|
Purpose Terminates a process. Parameters
Returned values If successful, the function returns |
|
Purpose Gets information about the reason for process termination. Parameters
Returned values If successful, the function returns Additional information You can use the
|
|
Purpose Gets information about an unhandled exception that led to an unexpected termination of a process. Parameters
Returned values If successful, the function returns |
|
Purpose Gets the context of a thread that is part of a frozen process. Parameters
Returned values If successful, the function returns |
|
Purpose Gets information about the virtual memory region that belongs to a frozen process. Parameters
Returned values If successful, the function returns |
|
Purpose Terminates a frozen process. Parameters
Returned values If successful, the function returns |
|
Purpose Gets the exit code of a process that terminated on its own initiative. Parameters
Returned values If successful, the function returns |
|
Purpose Gets the process ID (PID) for the calling process. Parameters N/A Returned values Process ID. The ID type is defined in the header file |
|
Purpose Gets the name of a calling process. Parameters
Returned values If successful, the function returns |
|
Purpose Gets the path to the executable file from which the calling process was created. Parameters
Returned values If successful, the function returns |
|
Purpose Gets the priority of the initial thread of a process. Parameters
Returned values If successful, the function returns |
|
Purpose Sets the priority of the initial thread of a process. Parameters
Returned values If successful, the function returns |
|
Purpose Registers the exception handling function for the calling process. Parameters
Returned values ID of the previously registered exception handling function if one exists, otherwise |
|
Purpose Loads an ELF image segment into process memory. Parameters
Returned values If successful, the function returns |
|
Purpose Reserves a virtual memory region in a process. Parameters
Returned values If successful, the function returns Additional information In the
Permissible combinations of flags defining the access rights to the virtual memory region:
|
|
Purpose Reserves a virtual memory region in a process for loading the ELF image. Parameters
Returned values If successful, the function returns |
|
Purpose Frees the virtual memory region that was reserved by calling the Parameters
Returned values If successful, the function returns |
|
Purpose Defines the program entry point and the ELF image load offset. Parameters
Returned values If successful, the function returns |
|
Purpose Loads the symbol table Parameters
Returned values If successful, the function returns |
|
Purpose Defines the scheduler class and priority of the initial thread of a process. Parameters
Returned values If successful, the function returns Additional information In the In the |
|
Purpose Defines the seed value for ASLR support in the defined process. Parameters
Returned values If successful, the function returns |
|
Purpose Gets the addresses and sizes of the symbol table Parameters
Returned values If successful, the function returns Additional information If the symbol table |
|
Purpose Gets the process ID (PID). Parameters
Returned values If successful, the function returns |
|
Purpose Initiates an exception that cannot be handled and leads to the process terminating. Parameters N/A Returned values N/A |
|
Purpose Transfers a handle to a process that is not yet running. Parameters
Returned values If successful, the function returns |