首页 > 解决方案 > 在 Windows 中的 appcontainer 进程和正常进程之间是否有任何 ipc 方式?

问题描述

我正在尝试在 Windows 中的 appcontainer 进程和正常进程之间创建 ipc。

我在 Windows appcontainer 中做了一个进程,感谢这篇文章。但是,我不知道如何在 appcontainer 中的进程和正常进程之间进行通信。

我尝试使用命名管道进行通信,但在 appcontainer 进程“访问被拒绝”上出现错误。(GetLastError() 返回 5)。然后我尝试了一个套接字(localhost),但即使端口号相同,它们也没有连接。

我检查了很多文章来解决这个问题......但我确实失败了。这是我检查的文章。

我想知道有一种方法可以在普通进程和 Windows 应用程序容器中的进程之间进行 ipc。

我正在以下环境中工作。

这是我的代码。

#include <iostream>

#include <Windows.h>
#include <strsafe.h>
#include <Sddl.h>
#include <AccCtrl.h>
#include <AclAPI.h>
#include <UserEnv.h>

#pragma comment(lib, "Userenv.lib")

//List of allowed capabilities for the application
extern WELL_KNOWN_SID_TYPE app_capabilities[] =
{
    WinCapabilityInternetClientSid,
    //WinCapabilityPrivateNetworkClientServerSid,
};

WCHAR container_name[] = L"SandboxTest";
WCHAR container_desc[] = L"Sandbox Test";

BOOL IsInAppContainer();
BOOL SetSecurityCapabilities(PSID container_sid, SECURITY_CAPABILITIES* capabilities, PDWORD num_capabilities);
BOOL GrantNamedObjectAccess(PSID appcontainer_sid, HANDLE object_handle, SE_OBJECT_TYPE object_type, DWORD access_mask);
DWORD AddDACLToObject(PSID appcontainer_sid, HANDLE hObj, SE_OBJECT_TYPE seObjectType);
BOOL CreateObjectSecurityDescriptor(PSID pLogonSid, PSECURITY_DESCRIPTOR* ppSD);
BOOL GetLogonSid(HANDLE hToken, PSID* ppsid);
int ConnectClient(HANDLE hNamePipe);

BOOL IsInAppContainer()
{
    HANDLE process_token;
    BOOL is_container = 0;
    DWORD return_length;

    OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process_token);

    if (!GetTokenInformation(process_token, TokenIsAppContainer, &is_container, sizeof is_container, &return_length))
        return false;
    return is_container;
}

HANDLE hNamePipe;

BOOL RunExecutableInContainer(CHAR* executable_path)
{
    PSID sid = NULL;
    HRESULT result;

    SECURITY_CAPABILITIES SecurityCapabilities = { 0 };

    DWORD num_capabilities = 0;
    SIZE_T attribute_size = 0;

    STARTUPINFOEXA startup_info = { 0 };
    PROCESS_INFORMATION process_info = { 0 };

    CHAR* string_sid = NULL;
    BOOL success = FALSE;
    HANDLE hToken = NULL;
    HANDLE  hNewToken = NULL;
    PSID  pIntegritySid = NULL;

    TOKEN_MANDATORY_LABEL TIL = { 0 };
    CHAR wszIntegritySid[20] = "S-1-16-4096";
    //4096
    //8192

    // HANDLE hNamePipe;
    CHAR pipe_name[] = "\\\\.\\pipe\\LOCAL";

    do {
        result = CreateAppContainerProfile(container_name, container_name, container_desc, NULL, 0, &sid);
        if (!SUCCEEDED(result))
        {
            if (HRESULT_CODE(result) == ERROR_ALREADY_EXISTS)
            {
                result = DeriveAppContainerSidFromAppContainerName(container_name, &sid);
                if (!SUCCEEDED(result))
                {
                    printf("Failed to get existing AppContainer name, error code: %d", HRESULT_CODE(result));
                    break;
                }
            }
            else {
                printf("Failed to create AppContainer, last error: %d\n", HRESULT_CODE(result));
                break;
            }
        }

        printf("[Container Info]\nname: %ws\ndescription: %ws\n", container_name, container_desc);

        if (ConvertSidToStringSidA(sid, &string_sid))
            printf("Sid: %s\n\n", string_sid);

        if (!SetSecurityCapabilities(sid, &SecurityCapabilities, &num_capabilities))
        {
            printf("Failed to set security capabilities, last error: %d\n", GetLastError());
            break;
        }
        /*
        // pipe
        hNamePipe = CreateNamedPipe(
            pipe_name,
            PIPE_ACCESS_DUPLEX,
            PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
            PIPE_UNLIMITED_INSTANCES,
            0,
            0,
            20000,
            NULL);

        if (hNamePipe == INVALID_HANDLE_VALUE)
        {
            printf("CreateNamePipe error! \n");
            break;
        }

        if (!GrantNamedObjectAccess(sid, hNamePipe, SE_KERNEL_OBJECT, FILE_ALL_ACCESS))
        {
            printf("Failed to grant explicit access to %s\n", pipe_name);
            DisconnectNamedPipe(hNamePipe);
            CloseHandle(hNamePipe);
            break;
        }
        */

        /*
        hNamePipe = CreateNamedPipe(
            pipe_name,
            PIPE_ACCESS_DUPLEX,
            PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
            PIPE_UNLIMITED_INSTANCES,
            0,
            0,
            20000,
            NULL);

        if (AddDACLToObject(sid, hNamePipe, SE_KERNEL_OBJECT))
        {
            printf("Failed to grant explicit access to %s\n", pipe_name);
            break;
        }*/

        /*
        PSID pLogonSid = NULL;
        PSECURITY_DESCRIPTOR pSd = NULL;
        SECURITY_ATTRIBUTES  SecurityAttributes;
        HANDLE hToken = NULL;

        OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
        pLogonSid = (PSID)malloc(sizeof(PSID));

        //Allowing LogonSid and all appcontainers. 
        if (GetLogonSid(hToken, &pLogonSid) && CreateObjectSecurityDescriptor(pLogonSid, &pSd))
        {
            SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
            SecurityAttributes.bInheritHandle = TRUE;
            SecurityAttributes.lpSecurityDescriptor = pSd;

            hNamePipe = CreateNamedPipe(
                pipe_name,
                PIPE_ACCESS_DUPLEX,
                PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
                PIPE_UNLIMITED_INSTANCES,
                0,
                0,
                20000,
                &SecurityAttributes);
            printf("pipe created\n");
        }
        */

        InitializeProcThreadAttributeList(NULL, 1, NULL, &attribute_size);
        startup_info.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)malloc(attribute_size);

        if (!InitializeProcThreadAttributeList(startup_info.lpAttributeList, 1, NULL, &attribute_size))
        {
            printf("InitializeProcThreadAttributeList() failed, last error: %d", GetLastError());
            break;
        }

        if (!UpdateProcThreadAttribute(startup_info.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES,
            &SecurityCapabilities, sizeof(SecurityCapabilities), NULL, NULL))
        {
            printf("UpdateProcThreadAttribute() failed, last error: %d", GetLastError());
            break;
        }

        if (!OpenProcessToken(GetCurrentProcess(),
            TOKEN_DUPLICATE |
            TOKEN_ADJUST_DEFAULT |
            TOKEN_QUERY |
            TOKEN_ASSIGN_PRIMARY,
            &hToken))
        {
            break;
        }

        if (!DuplicateTokenEx(hToken,
            0,
            NULL,
            SecurityImpersonation,
            TokenPrimary,
            &hNewToken))
        {
            break;
        }

        if (!ConvertStringSidToSid(wszIntegritySid, &pIntegritySid))
        {
            break;
        }
        TIL.Label.Attributes = SE_GROUP_INTEGRITY;
        TIL.Label.Sid = pIntegritySid;

        if (!SetTokenInformation(hNewToken,
            TokenIntegrityLevel,
            &TIL,
            sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid)))
        {
            break;
        }

        if (!CreateProcessAsUser(hNewToken,
            executable_path,
            NULL,
            NULL,
            NULL,
            FALSE,
            EXTENDED_STARTUPINFO_PRESENT,
            NULL,
            NULL,
            (LPSTARTUPINFOA)& startup_info,
            &process_info))
        {
            printf("Failed to create process %s, last error: %d\n", executable_path, GetLastError());
            break;
        }

        printf("Successfully executed %s in AppContainer\n", executable_path);
        success = TRUE;

    } while (FALSE);

    if (startup_info.lpAttributeList)
        DeleteProcThreadAttributeList(startup_info.lpAttributeList);

    if (SecurityCapabilities.Capabilities)
        free(SecurityCapabilities.Capabilities);

    if (sid)
        FreeSid(sid);

    if (string_sid)
        LocalFree(string_sid);

    if (process_info.hProcess != NULL)
        CloseHandle(process_info.hProcess);

    if (process_info.hThread != NULL)
        CloseHandle(process_info.hThread);

    LocalFree(pIntegritySid);

    if (hNewToken != NULL)
        CloseHandle(hNewToken);

    if (hToken != NULL)
        CloseHandle(hToken);

    return success;
}

/*
    Set the security capabilities of the container to those listed in app_capabilities
*/
BOOL SetSecurityCapabilities(PSID container_sid, SECURITY_CAPABILITIES* capabilities, PDWORD num_capabilities)
{
    DWORD sid_size = SECURITY_MAX_SID_SIZE;
    DWORD num_capabilities_ = sizeof(app_capabilities) / sizeof(DWORD);
    SID_AND_ATTRIBUTES* attributes;
    BOOL success = TRUE;

    attributes = (SID_AND_ATTRIBUTES*)malloc(sizeof(SID_AND_ATTRIBUTES) * num_capabilities_);

    ZeroMemory(capabilities, sizeof(SECURITY_CAPABILITIES));
    ZeroMemory(attributes, sizeof(SID_AND_ATTRIBUTES) * num_capabilities_);

    for (unsigned int i = 0; i < num_capabilities_; i++)
    {
        attributes[i].Sid = malloc(SECURITY_MAX_SID_SIZE);
        if (!CreateWellKnownSid(app_capabilities[i], NULL, attributes[i].Sid, &sid_size))
        {
            success = FALSE;
            break;
        }
        attributes[i].Attributes = SE_GROUP_ENABLED;
    }

    if (success == FALSE)
    {
        for (unsigned int i = 0; i < num_capabilities_; i++)
        {
            if (attributes[i].Sid)
                LocalFree(attributes[i].Sid);
        }

        free(attributes);
        attributes = NULL;
        num_capabilities_ = 0;
    }

    capabilities->Capabilities = attributes;
    capabilities->CapabilityCount = num_capabilities_;
    capabilities->AppContainerSid = container_sid;
    *num_capabilities = num_capabilities_;

    return success;
}

/*
    Explicitly grants the container access to a named object (file, section, etc)
*/
BOOL GrantNamedObjectAccess(PSID appcontainer_sid, HANDLE object_handle, SE_OBJECT_TYPE object_type, DWORD access_mask)
{
    EXPLICIT_ACCESS_A explicit_access;
    PACL original_acl = NULL, new_acl = NULL;
    DWORD status;
    BOOL success = FALSE;

    do
    {
        explicit_access.grfAccessMode = GRANT_ACCESS;
        explicit_access.grfAccessPermissions = access_mask;
        explicit_access.grfInheritance = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;

        explicit_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
        explicit_access.Trustee.pMultipleTrustee = NULL;
        explicit_access.Trustee.ptstrName = (CHAR*)appcontainer_sid;
        explicit_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
        explicit_access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;

        status = GetSecurityInfo(object_handle, object_type, DACL_SECURITY_INFORMATION, NULL, NULL, &original_acl,
            NULL, NULL);
        if (status != ERROR_SUCCESS)
        {
            printf("GetSecurityInfo() failed, error: %d\n", status);
            break;
        }

        status = SetEntriesInAclA(1, &explicit_access, original_acl, &new_acl);
        if (status != ERROR_SUCCESS)
        {
            printf("SetEntriesInAclA() failed, error: %d\n", status);
            break;
        }

        status = SetSecurityInfo(object_handle, object_type, DACL_SECURITY_INFORMATION, NULL, NULL, new_acl, NULL);
        if (status != ERROR_SUCCESS)
        {
            printf("SetSecurityInfo() failed, error: %d\n", status);
            break;
        }

        success = TRUE;

    } while (FALSE);

    if (original_acl)
        LocalFree(original_acl);

    if (new_acl)
        LocalFree(new_acl);

    return success;
}

DWORD AddDACLToObject(PSID appcontainer_sid, HANDLE hObj, SE_OBJECT_TYPE seObjectType)
{
    LPSTR szAddSid = (LPSTR)"S-1-15-2-1";
    // LPWSTR szAddSid = L"S-1-15-2-1";//SID_ALL_APP_PACKAGES;

    PACL pACL = NULL;
    DWORD dwRes;
    PSID pSIDAllAppPackage = NULL;

    PSECURITY_DESCRIPTOR pSDOld = NULL;
    PACL pOldDACL = NULL;
    dwRes = GetSecurityInfo(hObj, seObjectType,
        DACL_SECURITY_INFORMATION,
        NULL, NULL, &pOldDACL, NULL, &pSDOld);
    if (ERROR_SUCCESS != dwRes)
    {
        return dwRes;
    }

    if (ConvertStringSidToSid(szAddSid, &pSIDAllAppPackage) == FALSE)
    {
        dwRes = GetLastError();
        return dwRes;
    }

    const int NUM_ACES = 1;
    EXPLICIT_ACCESS ea[NUM_ACES];
    ZeroMemory(&ea, NUM_ACES * sizeof(EXPLICIT_ACCESS));

    ea[0].grfAccessPermissions = GENERIC_ALL;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance = NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[0].Trustee.ptstrName = (LPTSTR)appcontainer_sid;

    dwRes = SetEntriesInAcl(NUM_ACES, ea, pOldDACL, &pACL);
    if (ERROR_SUCCESS != dwRes)
    {
        return dwRes;
    }

    dwRes = SetSecurityInfo(
        hObj,                      // name of the object
        seObjectType,              // type of object
        DACL_SECURITY_INFORMATION, // change only the object's DACL
        NULL, NULL,                // do not change owner or group
        pACL,                      // DACL specified
        NULL);                     // do not change SACL
    return dwRes;
}

BOOL GetLogonSid(HANDLE hToken, PSID* ppsid)
{
    BOOL bSuccess = FALSE;
    DWORD dwLength = 0;
    PTOKEN_GROUPS ptg = NULL;

    // Verify the parameter passed in is not NULL.
    if (NULL == ppsid)
        goto Cleanup;

    // Get required buffer size and allocate the TOKEN_GROUPS buffer.

    if (!GetTokenInformation(
        hToken,         // handle to the access token
        TokenLogonSid,    // get information about the token's groups 
        (LPVOID)ptg,   // pointer to TOKEN_GROUPS buffer
        0,              // size of buffer
        &dwLength       // receives required buffer size
    ))
    {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            goto Cleanup;

        ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
            HEAP_ZERO_MEMORY, dwLength);

        if (ptg == NULL)
            goto Cleanup;
    }

    // Get the token group information from the access token.

    if (!GetTokenInformation(
        hToken,         // handle to the access token
        TokenLogonSid,    // get information about the token's groups 
        (LPVOID)ptg,   // pointer to TOKEN_GROUPS buffer
        dwLength,       // size of buffer
        &dwLength       // receives required buffer size
    ) || ptg->GroupCount != 1)
    {
        goto Cleanup;
    }

    // Found the logon SID; make a copy of it.

    dwLength = GetLengthSid(ptg->Groups[0].Sid);
    *ppsid = (PSID)HeapAlloc(GetProcessHeap(),
        HEAP_ZERO_MEMORY, dwLength);
    if (*ppsid == NULL)
        goto Cleanup;
    if (!CopySid(dwLength, *ppsid, ptg->Groups[0].Sid))
    {
        HeapFree(GetProcessHeap(), 0, (LPVOID)* ppsid);
        goto Cleanup;
    }

    bSuccess = TRUE;

Cleanup:

    // Free the buffer for the token groups.

    if (ptg != NULL)
        HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);

    return bSuccess;
}

BOOL
CreateObjectSecurityDescriptor(PSID pLogonSid, PSECURITY_DESCRIPTOR* ppSD)
{
    BOOL bSuccess = FALSE;
    DWORD dwRes;
    PSID pAllAppsSID = NULL;
    PACL pACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea[2];
    SID_IDENTIFIER_AUTHORITY ApplicationAuthority = SECURITY_APP_PACKAGE_AUTHORITY;

    // Create a well-known SID for the all appcontainers group.
    if (!AllocateAndInitializeSid(&ApplicationAuthority,
        SECURITY_BUILTIN_APP_PACKAGE_RID_COUNT,
        SECURITY_APP_PACKAGE_BASE_RID,
        SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE,
        0, 0, 0, 0, 0, 0,
        &pAllAppsSID))
    {
        wprintf(L"AllocateAndInitializeSid Error %u\n", GetLastError());
        goto Cleanup;
    }

    // Initialize an EXPLICIT_ACCESS structure for an ACE.
    // The ACE will allow LogonSid generic all access
    ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
    ea[0].grfAccessPermissions = STANDARD_RIGHTS_ALL | MUTEX_ALL_ACCESS;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance = NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
    ea[0].Trustee.ptstrName = (LPTSTR)pLogonSid;

    // Initialize an EXPLICIT_ACCESS structure for an ACE.
    // The ACE will allow the all appcontainers execute permission
    ea[1].grfAccessPermissions = STANDARD_RIGHTS_READ | STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTEX_MODIFY_STATE;
    ea[1].grfAccessMode = SET_ACCESS;
    ea[1].grfInheritance = NO_INHERITANCE;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[1].Trustee.ptstrName = (LPTSTR)pAllAppsSID;

    // Create a new ACL that contains the new ACEs.
    dwRes = SetEntriesInAcl(2, ea, NULL, &pACL);
    if (ERROR_SUCCESS != dwRes)
    {
        wprintf(L"SetEntriesInAcl Error %u\n", GetLastError());
        goto Cleanup;
    }

    // Initialize a security descriptor.  
    pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR,
        SECURITY_DESCRIPTOR_MIN_LENGTH);
    if (NULL == pSD)
    {
        wprintf(L"LocalAlloc Error %u\n", GetLastError());
        goto Cleanup;
    }

    if (!InitializeSecurityDescriptor(pSD,
        SECURITY_DESCRIPTOR_REVISION))
    {
        wprintf(L"InitializeSecurityDescriptor Error %u\n",
            GetLastError());
        goto Cleanup;
    }

    // Add the ACL to the security descriptor. 
    if (!SetSecurityDescriptorDacl(pSD,
        TRUE,     // bDaclPresent flag   
        pACL,
        FALSE))   // not a default DACL 
    {
        wprintf(L"SetSecurityDescriptorDacl Error %u\n",
            GetLastError());
        goto Cleanup;
    }

    *ppSD = pSD;
    pSD = NULL;
    bSuccess = TRUE;
Cleanup:

    if (pAllAppsSID)
        FreeSid(pAllAppsSID);
    if (pACL)
        LocalFree(pACL);
    if (pSD)
        LocalFree(pSD);

    return bSuccess;
}

int ConnectClient(HANDLE hNamePipe)
{
    TCHAR recvMessage[100];
    TCHAR sendMessage[100];
    DWORD recvSize;
    DWORD sendSize;

    while (1)
    {
        printf("Input Send Message : ");
        scanf("%s", sendMessage);

        if (!(WriteFile(
            hNamePipe,
            sendMessage,
            (strlen(sendMessage) + 1) * sizeof(TCHAR),
            &sendSize,
            NULL)))
        {
            printf("WriteFile error! \n");
            return -1;
        }
        FlushFileBuffers(hNamePipe);

        if (!(ReadFile(
            hNamePipe,
            recvMessage,
            sizeof(recvMessage) - sizeof(TCHAR) * 1,
            &recvSize,
            NULL)))
        {
            printf("ReadFile error! \n");
            return -1;
        }

        recvMessage[recvSize / sizeof(TCHAR) - 1] = '\x00';
        printf("Recv Message : %s \n", recvMessage);
    }
    return 1;
}

int main()
{
    CHAR path[] = "D:\\Projects\\Visual Studio Project\\SandboxTest\\socket.exe";
    std::cout << IsInAppContainer();
    RunExecutableInContainer(path);

    getchar();
}

标签: c++windowsipcappcontainer

解决方案


推荐阅读