Введение
Как поясняется на странице «Обзор» , хост-код выполняет RPC-вызовы к изолированной библиотеке. Использование изолированной библиотеки приводит к разделению памяти между процессами, и, следовательно, хост-код не может напрямую обращаться к памяти изолированной библиотеки.
Чтобы обеспечить доступ хост-кода к переменным и блокам памяти в удалённом процессе и упростить реализацию основного логического кода, SAPI предоставляет полный набор классов C++. Однако во многих случаях вы также сможете использовать нативные типы C.
Необходимость в специальных типах (типах SAPI) возникает при передаче указателей на простые типы и блоки памяти (структуры, массивы).
Например, при вызове функции, принимающей указатель, этот указатель должен быть преобразован в соответствующий указатель в памяти библиотеки Sandboxed. Приведённый ниже фрагмент кода наглядно иллюстрирует этот сценарий. Вместо массива из трёх целых чисел создаётся объект ::sapi::v::Array<int>
, который затем можно передать в вызов API библиотеки Sandboxed:
int arr[3] = {1, 2, 3};
sapi::v::Array<int> sarr(arr, ABSL_ARRAYSIZE(arr));
Для полного обзора всех доступных типов SAPI ознакомьтесь с заголовочными файлами var_*.h
в исходном коде проекта SAPI . Эти заголовочные файлы содержат классы и шаблоны, представляющие различные типы данных, например:
-
::sapi::v::UChar
представляет известные беззнаковые символы -
::sapi::v::Array<int>
представляет массив целых чисел
Типы SAPI
В этом разделе описываются три типа SAPI, которые обычно встречаются в коде хоста.
Указатели SAPI
Если функция, которую необходимо изолировать, требует передачи указателя, этот указатель следует получить с помощью одного из методов PtrXXX()
перечисленных ниже. Эти методы реализованы в классах переменных SAPI.
Типы указателей | |
---|---|
::PtrNone() | Не синхронизирует базовую память между процессом кода хоста и процессом изолированной библиотеки при передаче в изолированную функцию API. |
::PtrBefore() | Синхронизирует память объекта, на который указывает, до вызова функции API в изолированной среде. Это означает, что локальная память указанной переменной будет передана процессу библиотеки в изолированной среде до инициации вызова. |
::PtrAfter() | Синхронизирует память объекта, на который он указывает, после вызова изолированной API-функции. Это означает, что удалённая память указанной переменной будет перенесена в память процесса Host Code после завершения вызова. |
::PtrBoth() | Объединяет функциональность ::PtrBefore() и ::PtrAfter() . |
Документацию по указателям SAPI можно найти здесь .
Структура SAPI
Шаблон ::sapi::v::Struct
документирован в var_struct.h . Он предоставляет конструктор, который можно использовать для обёртки существующих структур. SAPI Struct предоставляет все методы, описанные в разделе «Указатели SAPI», для получения объекта ::sapi::v::Ptr
, который можно использовать для вызовов изолированных библиотек.
В приведенном ниже фрагменте кода показана инициализация структуры, которая затем передается в вызов изолированной функции в примере zlib :
sapi::v::Struct<sapi::zlib::z_stream> strm;
…
if (ret = api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION,
version.PtrBefore(), sizeof(sapi::zlib::z_stream));
…
Если ваша существующая структура содержит указатели, то эти указатели будут указывать на адреса в Sandboxee. Следовательно, вам придётся перенести данные Sandboxee, прежде чем они станут доступны коду хоста.
SAPI-массивы
Шаблон ::sapi::v::Array
документирован в файле var_array.h . Он предоставляет два конструктора: один для обёртки существующих массивов элементов, а другой — для динамического создания массива.
В этом фрагменте кода (взятом из примера суммы ) показано использование конструктора, который оборачивает массив, не принадлежащий данному объекту:
int arr[10];
sapi::v::Array<int> iarr(arr, ABSL_ARRAYSIZE(arr));
В этом фрагменте кода показан пример конструктора, используемого для динамического создания массива:
sapi::v::Array<uint8_t> buffer(PNG_IMAGE_SIZE(*image.mutable_data()));
SAPI Array предоставляет все методы, описанные в разделе «Указатели SAPI», для получения объекта ::sapi::v::Ptr
, который можно использовать для вызовов изолированной библиотеки.