Руководство по переменным

Введение

Как поясняется на странице «Обзор» , код хоста выполняет вызовы 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 , который можно использовать для вызовов изолированной библиотеки.