Guía de variables

Introducción

Como se explica en la página Descripción general, el código de host realiza llamadas RPC a la biblioteca de zona de pruebas. La zona de pruebas genera una separación de memoria entre los procesos y, por lo tanto, el código de host no puede acceder directamente a la memoria de la biblioteca de la zona de pruebas.

Para asegurarse de que el código de host pueda acceder a las variables y los bloques de memoria en un proceso remoto y para facilitar la implementación del código lógico principal, SAPI proporciona un conjunto completo de clases C++. Sin embargo, en muchos casos, también podrás usar tipos C nativos.

La necesidad de los tipos especiales (tipos de SIP) surge cuando se pasan punteros a tipos simples y bloques de memoria (estructuras, arrays).

Por ejemplo, cuando se llama a una función que toma un puntero, este debe convertirse en un puntero correspondiente dentro de la memoria de la biblioteca de la zona de pruebas. En el siguiente fragmento de código, se visualiza esta situación. En lugar de un array de tres números enteros, se crea un objeto ::sapi::v::Array<int> que, luego, se puede pasar en la llamada a la API de la biblioteca de la zona de pruebas:

int arr[3] = {1, 2, 3};
sapi::v::Array<int> sarr(arr, ABSL_ARRAYSIZE(arr));

Para obtener una descripción general completa de todos los tipos de SAPI disponibles, revisa los archivos de encabezado var_*.h en el código fuente del proyecto de SAP. Estos archivos de encabezado proporcionan clases y plantillas que representan varios tipos de datos, p.ej.:

  • ::sapi::v::UChar representa caracteres sin firma conocidos.
  • ::sapi::v::Array<int> representa un array de números enteros.

Tipos de SAPI

En esta sección, se presentan tres tipos de SAPI que se suelen ver en el código de host.

Punteros SAPI

Si una función que se someterá a la zona de pruebas requiere pasar un puntero, este se debe obtener de uno de los métodos PtrXXX() que se indican a continuación. Las clases de variables de SAPI implementan estos métodos.

Tipos de puntero
::PtrNone() No sincroniza la memoria subyacente entre el proceso del código de host y el proceso de la biblioteca de la zona de pruebas cuando se pasa a una función de la API de zona de pruebas.
::PtrBefore() Sincroniza la memoria del objeto al que apunta antes de que se realice la llamada a la función a la API de la zona de pruebas. Esto significa que la memoria local de la variable puntiaguda se transferirá al proceso de la biblioteca de la zona de pruebas antes de que se inicie la llamada.
::PtrAfter() Sincroniza la memoria del objeto al que apunta después de que se realiza la llamada a la función a la API de la zona de pruebas. Esto significa que la memoria remota de la variable apuntada se transferirá a la memoria de proceso del código de host después de que se complete la llamada.
::PtrBoth() Combina la funcionalidad de ::PtrBefore() y ::PtrAfter().

La documentación sobre los punteros de SAPI se puede encontrar aquí.

Estructura SAPI

La plantilla ::sapi::v::Struct está documentada en var_struct.h. Proporciona un constructor que se puede usar para unir estructuras existentes. SAPI Struct proporciona todos los métodos descritos en Punteros SAPI a fin de obtener un objeto ::sapi::v::Ptr que se puede usar para llamadas a bibliotecas de zona de pruebas.

En el siguiente fragmento de código, se muestra una estructura que se inicia y luego se pasa a una llamada a función de zona de pruebas en el ejemplo de 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));
…

Si tu struct existente contiene punteros, estos apuntarán a direcciones en Sandboxee. En consecuencia, deberás transferir los datos de Sandboxee antes de que estén disponibles para el código de host.

Arrays SAPI

La plantilla ::sapi::v::Array se documenta en var_array.h. Proporciona dos constructores, uno que se puede usar para unir arrays de elementos existentes y otro para crear un array de forma dinámica.

Este fragmento de código (tomado del ejemplo de suma) muestra el uso del constructor que une un array que no es propiedad de este objeto:

int arr[10];
sapi::v::Array<int> iarr(arr, ABSL_ARRAYSIZE(arr));

En este fragmento de código, se muestra un ejemplo del constructor que se usa para crear un array de forma dinámica:

sapi::v::Array<uint8_t> buffer(PNG_IMAGE_SIZE(*image.mutable_data()));

El array SAPI proporciona todos los métodos descritos en Punteros SAP para obtener un objeto ::sapi::v::Ptr que se puede usar para llamadas a bibliotecas de zona de pruebas.