소개
개요 페이지에 설명된 대로 호스트 코드에서 샌드박스 라이브러리에 RPC 호출을 실행합니다. 샌드박싱으로 인해 프로세스 간에 메모리가 분리되므로 호스트 코드는 샌드박스 라이브러리의 메모리에 직접 액세스할 수 없습니다.
호스트 코드에서 원격 프로세스의 변수와 메모리 블록에 액세스할 수 있고 기본 로직 코드의 구현을 더 간단하게 할 수 있도록 SAPI는 포괄적인 C++ 클래스 집합을 제공합니다. 하지만 대부분의 경우 네이티브 C 유형도 사용할 수 있습니다.
특수 유형 (SAPI 유형)은 단순 유형과 메모리 블록 (구조체, 배열)에 포인터를 전달할 때 필요합니다.
예를 들어 포인터를 사용하는 함수를 호출할 때 포인터는 샌드박스 라이브러리의 메모리 내에서 해당 포인터로 변환되어야 합니다.
아래 코드 스니펫은 이 시나리오를 시각화합니다. 정수 3개로 된 배열 대신 샌드박스 라이브러리의 API 호출에 전달할 수 있는 ::sapi::v::Array<int>
객체가 생성됩니다.
int arr[3] = {1, 2, 3};
sapi::v::Array<int> sarr(arr, ABSL_ARRAYSIZE(arr));
사용 가능한 모든 SAPI 유형에 대한 포괄적인 개요는 SAPI 프로젝트 소스 코드의 var_*.h
헤더 파일을 검토하세요. 이러한 헤더 파일은 다음과 같은 다양한 유형의 데이터를 나타내는 클래스와 템플릿을 제공합니다.
::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 구조체는 샌드박스 라이브러리 호출에 사용할 수 있는 ::sapi::v::Ptr
객체를 가져오기 위해 SAPI 포인터에 설명된 모든 메서드를 제공합니다.
아래 코드 스니펫은 구조가 초기화된 후 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 데이터를 전송해야 합니다.
SAPI 배열
템플릿 ::sapi::v::Array
는 var_array.h에 문서화되어 있습니다. 이 템플릿은 기존 요소 배열을 래핑하는 데 사용할 수 있는 생성자와 배열을 동적으로 생성하는 생성자 두 개를 제공합니다.
이 코드 스니펫 (sum 예에서 가져옴)은 이 객체가 소유하지 않은 배열을 래핑하는 생성자의 사용을 보여줍니다.
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 배열은 샌드박스 라이브러리 호출에 사용할 수 있는 ::sapi::v::Ptr
객체를 가져오기 위해 SAPI 포인터에 설명된 모든 메서드를 제공합니다.