共用方式為


繼承應用程式的 AppContainer

AppContainer 環境是限制性的進程執行環境,可用於繼承應用程式以提供資源安全性。 AppContainer 應用程式的進程及其子進程會在輕量型應用程式容器內執行,其只能存取特別授與他們的資源。 它們會使用檔案系統和登錄虛擬化來隔離。 因此,在 AppContainer 中實作的應用程式無法遭到駭客攻擊,以允許有限指派資源以外的惡意動作。

針對已封裝和未封裝的應用程式,AppContainer 代表良好的安全工程實務。

提示

AppContainer 最初命名為 LowBox (在 Windows 8 版本之前)。 您可以在 API 名稱中看到該舊版名稱,例如 NtCreateLowBoxToken

已封裝的應用程式

您可以採用使用 MSIX 封裝的應用程式,並輕鬆地將其設定為在 AppContainer 環境中執行。 通用 Windows 平臺 (UWP) 應用程式會自動是 AppContainer 應用程式。 但您也可以將搭配 MSIX 封裝的桌面應用程式設定為 AppContainer 應用程式。 如果您使用 MSIX 封裝,則特別容易使用 AppContainer。 如需詳細資訊、案例和組態範例,請參閱 MSIX AppContainer 應用程式

解壓縮的應用程式

未封裝的應用程式也可以在應用程式容器中執行。 若要在應用程式容器中建立進程,您需要 AppContainer 定義(或設定檔)。 這就是為什麼使用 AppContainer 搭配已封裝的應用程式會比較容易。 當您為使用者註冊套件時,部署堆疊會為您呼叫特定的 WIN32 API,以建立必要的 AppContainer 設定檔(例如 CreateAppContainerProfile )。 當您取消註冊使用者的套件時,部署堆疊會執行移除 AppContainer 設定檔 ( DeleteAppContainerProfile ) 的工作。 如果您未封裝應用程式,則必須自行呼叫這些 WIN32 API 來執行相同的動作:但可能很複雜。

大部分使用低效能層級的未封裝應用程式現在都會使用 AppContainer 作為提供受限執行環境的更好方式。

當在應用程式容器中執行的未封裝進程呼叫 CreateProcess 時,子進程通常會繼承父系的權杖。 該權杖包含完整性層級 (IL) 和應用程式容器資訊。 最好不要考慮單一軸,其值已提高/中/低/appContainer。 相反地,不在應用程式容器中是第二個和正交屬性。 也就是說,如果您 位於 應用程式容器中,則完整性層級 (IL) 一律 很低

使用 AppContainer 環境的優點

AppContainer 環境的主要目標是盡可能將應用程式狀態與系統狀態分開,同時維持與其他應用程式的相容性。 Windows 可藉由偵測並重新導向它在執行時間對檔案系統和登錄所做的特定變更來達成此目的(稱為 虛擬化 )。 AppContainer 應用程式會寫入自己的虛擬登錄和應用程式資料檔案夾,並在卸載或重設應用程式時刪除該資料。 其他應用程式無法存取 AppContainer 應用程式的虛擬登錄或虛擬檔案系統。

因此,AppContainer 環境提供安全的應用程式沙箱化。 隔離應用程式,使其無法存取硬體、檔案、登錄、其他應用程式、網路連線能力,以及沒有特定許可權的網路資源。 個別資源可以設為目標,而不公開其他資源。 此外,使用者身分識別會使用唯一身分識別來保護,這是使用者和應用程式的串連;和 資源會使用最低許可權模型來授與。 這可進一步防止模擬使用者以存取其他資源的應用程式。

測試在應用程式容器中執行的範例程式碼

在 C# 或 C++ 專案中,您可以使用下列其中一個程式碼範例來判斷進程是否在應用程式容器內執行。 針對每個範例,在程式碼執行之後,如果 isAppContainer 的值 不是零 (或 true ),則進程會在應用程式容器內執行。

C# (P/Invoke)

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetCurrentProcess();

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool OpenProcessToken(
    IntPtr ProcessHandle,
    UInt32 DesiredAccess,
    out IntPtr TokenHandle);

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetTokenInformation(
    IntPtr TokenHandle,
    uint TokenInformationClass,
    out uint TokenInformation,
    uint TokenInformationLength,
    out uint ReturnLength);

UInt32 TOKEN_QUERY = 0x0008;
IntPtr tokenHandle;

if (!OpenProcessToken(
    GetCurrentProcess(),
    TOKEN_QUERY,
    out tokenHandle))
{
    // Handle the error.
}

uint isAppContainer;
uint TokenIsAppContainer = 29;
uint tokenInformationLength = sizeof(uint);

if (!GetTokenInformation(
    tokenHandle,
    TokenIsAppContainer,
    out isAppContainer,
    tokenInformationLength,
    out tokenInformationLength))
{
    // Handle the error.
}

C++ (WIL)

此範例使用 Windows 實作連結 庫 (WIL) )。 安裝 WIL 的便利方式是移至 Visual Studio,按一下 [ 專案 > 管理 NuGet 套件...] > 在搜尋方塊中流覽 、輸入或貼上 Microsoft.Windows.ImplementationLibrary ,選取搜尋結果中的專案,然後按一下 [安裝 ] 以安裝該專案的套件。

#include <wil\token_helpers.h>
...
bool isAppContainer = wil::get_token_is_app_container();

式 wil::get_token_is_app_container_nothrow wil::get_token_is_app_container_failfast 提供替代的錯誤處理策略。 如需詳細資訊,請參閱 wil\token_helpers.h

C++ (標準)

#include <windows.h>
...
HANDLE tokenHandle{};
DWORD isAppContainer{};
DWORD tokenInformationLength{ sizeof(DWORD) };

if (!::OpenProcessToken(
    GetCurrentProcess(),
    TOKEN_QUERY,
    &tokenHandle))
{
    // Handle the error.
}

if (!::GetTokenInformation(
    tokenHandle,
    TOKEN_INFORMATION_CLASS::TokenIsAppContainer,
    &isAppContainer,
    tokenInformationLength,
    &tokenInformationLength
))
{
    // Handle the error.
}

本節內容

如需針對繼承應用程式使用 AppContainer 的詳細資訊,請參閱下列主題。

主題 說明
AppContainer 隔離 隔離是 AppContainer 執行環境的主要目標。 藉由將應用程式與不需要的資源和其他應用程式隔離,惡意操作的機會就會最小化。 根據最低許可權授與存取權可防止應用程式和使用者存取超出其許可權的資源。 控制資源的存取權可保護進程、裝置和網路。
實作 AppContainer AppContainer 是藉由將新資訊新增至進程權杖、變更 SeAccessCheck() 來實作,讓所有舊版、未修改 的存取控制清單 (ACL) 物件預設會封鎖來自 AppContainer 進程的存取要求,以及應該可供 AppContainers 使用的重新 ACL 物件。