2

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

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

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

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

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

我正在以下环境中工作。

  • 视窗 10
  • 视觉工作室 2019

这是我的代码。

#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();
}
4

0 回答 0