Wprowadzenie
Zgodnie z informacjami na stronie Przegląd kod hosta wykonuje wywołania RPC do biblioteki w piaskownicy. Piaskownica powoduje rozdzielenie pamięci między procesami, więc kod hosta nie może bezpośrednio uzyskiwać dostępu do pamięci w bibliotece w piaskownicy.
Aby mieć pewność, że kod hosta może uzyskiwać dostęp do zmiennych i bloków pamięci w procesie zdalnym, a także aby uprościć implementację głównego kodu logiki, SAPI udostępnia kompleksowy zestaw klas C++. W wielu przypadkach możesz jednak używać też natywnych typów C.
Potrzeba użycia typów specjalnych (typów SAPI) pojawia się podczas przekazywania wskaźników do typów prostych i bloków pamięci (struktur, tablic).
Na przykład podczas wywoływania funkcji przyjmującej wskaźnik musi on zostać przekonwertowany na odpowiedni wskaźnik w pamięci biblioteki w piaskownicy.
Poniższy fragment kodu ilustruje ten scenariusz. Zamiast tablicy 3 liczb całkowitych tworzony jest ::sapi::v::Array<int>
obiekt, który można następnie przekazać w wywołaniu interfejsu API biblioteki w piaskownicy:
int arr[3] = {1, 2, 3};
sapi::v::Array<int> sarr(arr, ABSL_ARRAYSIZE(arr));
Szczegółowe informacje o wszystkich dostępnych typach interfejsu SAPI znajdziesz w var_*.h
plikach nagłówkowych w kodzie źródłowym projektu SAPI. Te pliki nagłówkowe zawierają klasy i szablony reprezentujące różne typy danych, np.:
::sapi::v::UChar
reprezentuje znane znaki bez znaku::sapi::v::Array<int>
reprezentuje tablicę liczb całkowitych.
Typy SAPI
W tej sekcji przedstawiamy 3 typy interfejsu SAPI, które często występują w kodzie hosta.
Wskaźniki SAPI
Jeśli funkcja, która ma być uruchomiona w piaskownicy, wymaga przekazania wskaźnika, należy go uzyskać za pomocą jednej z PtrXXX()
metod poniżej. Te metody są implementowane przez klasy zmiennych SAPI.
Typy wskaźników | |
---|---|
::PtrNone() |
Nie synchronizuje pamięci bazowej między procesem kodu hosta a procesem biblioteki w piaskownicy, gdy jest przekazywana do funkcji interfejsu API w piaskownicy. |
::PtrBefore() |
Synchronizuje pamięć obiektu, na który wskazuje, przed wywołaniem funkcji interfejsu API w piaskownicy. Oznacza to, że przed zainicjowaniem wywołania lokalna pamięć wskazywanej zmiennej zostanie przeniesiona do procesu biblioteki w piaskownicy. |
::PtrAfter() |
Synchronizuje pamięć obiektu, na który wskazuje, po wywołaniu funkcji interfejsu API w piaskownicy. Oznacza to, że pamięć zdalna wskazywanej zmiennej zostanie przeniesiona do pamięci procesu kodu hosta po zakończeniu wywołania. |
::PtrBoth() |
Łączy funkcje ::PtrBefore() i ::PtrAfter() . |
Dokumentację wskaźników SAPI znajdziesz tutaj.
SAPI Struct
Szablon ::sapi::v::Struct
jest opisany w pliku var_struct.h. Zawiera konstruktor, którego można użyć do opakowania istniejących struktur. SAPI
Struct udostępnia wszystkie metody opisane w sekcji Wskaźniki SAPI, aby uzyskać obiekt ::sapi::v::Ptr
, którego można używać do wywołań biblioteki w piaskownicy.
Poniższy fragment kodu pokazuje strukturę, która jest inicjowana, a następnie przekazywana do wywołania funkcji w piaskownicy w przykładzie 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));
…
Jeśli istniejąca struktura zawiera wskaźniki, będą one wskazywać adresy w Sandboxee. W konsekwencji przed uzyskaniem dostępu do danych Sandboxee przez kod hosta konieczne będzie ich przeniesienie.
Tablice SAPI
Szablon ::sapi::v::Array
jest opisany w pliku var_array.h. Zawiera 2 konstruktory: jeden służy do opakowywania istniejących tablic elementów, a drugi do dynamicznego tworzenia tablicy.
Ten fragment kodu (pochodzący z przykładu sum) pokazuje użycie konstruktora, który otacza tablicę niebędącą własnością tego obiektu:
int arr[10];
sapi::v::Array<int> iarr(arr, ABSL_ARRAYSIZE(arr));
Ten fragment kodu pokazuje przykład konstruktora używanego do dynamicznego tworzenia tablicy:
sapi::v::Array<uint8_t> buffer(PNG_IMAGE_SIZE(*image.mutable_data()));
SAPI Array udostępnia wszystkie metody opisane w sekcji Wskaźniki SAPI, aby uzyskać obiekt ::sapi::v::Ptr
, który można wykorzystać do wywołań biblioteki w piaskownicy.