Введение
Как поясняется на странице «Обзор» , код хоста выполняет вызовы RPC к изолированной библиотеке. Использование песочницы приводит к разделению памяти между процессами, и поэтому хост-код не может напрямую обращаться к памяти в изолированной библиотеке.
Чтобы гарантировать, что хост-код может получить доступ к переменным и блокам памяти в удаленном процессе, а также упростить реализацию основного логического кода, SAPI предоставляет полный набор классов C++. Однако во многих случаях вы также сможете использовать собственные C-типы.
Потребность в специальных типах (типах SAPI) возникает при передаче указателей на простые типы и блоки памяти (структуры, массивы).
Например, при вызове функции, принимающей указатель, указатель должен быть преобразован в соответствующий указатель внутри памяти изолированной библиотеки. Приведенный ниже фрагмент кода визуализирует этот сценарий. Вместо массива из трех целых чисел создается объект ::sapi::v::Array<int>
, который затем можно передать в вызове API изолированной библиотеки:
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. Это означает, что удаленная память указанной переменной будет передана в память процесса хост-кода после завершения вызова. |
::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
, который можно использовать для вызовов изолированной библиотеки.