internet-explorerinternet-explorer-11bhoappcontainer

Is there a way to create a named pipe from an AppContainer BHO on IE11?


I'm trying to write a BHO for Internet Explorer 11 (Windows 8.1). My BHO implements the AppContainer sandbox, but I can't seem to create a Named Pipe, CreateNamedPipe fails with that message: Access is denied.

Here's the code I'm using to create the named pipe (which I found on a russian website, last comment:

        LPCWSTR LOW_INTEGRITY_SDDL_SACL_W = L"S:(ML;;NW;;;LW)D:(A;;0x120083;;;WD)(A;;0x120083;;;AC)";

        PSECURITY_DESCRIPTOR pSD = NULL;
        ConvertStringSecurityDescriptorToSecurityDescriptorW (
            LOW_INTEGRITY_SDDL_SACL_W,
            SDDL_REVISION_1,
            &pSD,
            NULL );

        if ( pSD != NULL)
        {
            SECURITY_ATTRIBUTES  SecurityAttributes;

            SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
            SecurityAttributes.bInheritHandle = TRUE;
            SecurityAttributes.lpSecurityDescriptor = pSD;

            HANDLE hPipe = CreateNamedPipe(
                L"\\\\.\\pipe\\testpipe",
                PIPE_ACCESS_DUPLEX,                     
                PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
                1,                                  
                4096,                   
                4096,                               
                1000,
                &SecurityAttributes);           

        }

Unfortunately, it doesn't work. GetLastError() returns this Access is denied as usual.


Solution

  • You cannot create Named Pipe in BHO. But you can create it in your broker process and connect to the pipe from BHO. I'm author of the pointed comment and I tested the code in the broker part of my IE addon.

    The code snippets. Pipe creating in auto-started exe (Delphi)

    function CreateAppContainerSecurityDescriptor(var SD: PSECURITY_DESCRIPTOR): boolean;
    const
      SDDL_REVISION_1 = 1;
    var
      pSD: PSECURITY_DESCRIPTOR;
      ConvertStringSecurityDescriptorToSecurityDescriptor: TConvertStringSecurityDescriptorToSecurityDescriptorW;
    begin
      @ConvertStringSecurityDescriptorToSecurityDescriptor := GetProcAddress(AdvapiDll(),
        'ConvertStringSecurityDescriptorToSecurityDescriptorW');
      result := false;
      if ConvertStringSecurityDescriptorToSecurityDescriptor('S:(ML;;NW;;;LW)D:(A;;0x120083;;;WD)(A;;0x120083;;;AC)',
        SDDL_REVISION_1, pSD, nil) then begin
        SD := pSD;
        result := true;
      end;
    end;
    
    function TPipeServer.Start: boolean;
    var
      SD: PSECURITY_DESCRIPTOR;
      SecurityAttributes: SECURITY_ATTRIBUTES;
    begin
      result := false;
      if Win32MajorVersion >= 6 then begin
        if CreateAppContainerSecurityDescriptor(SD) then begin
          SecurityAttributes.nLength := sizeof(SECURITY_ATTRIBUTES);
          SecurityAttributes.bInheritHandle := true;
          SecurityAttributes.lpSecurityDescriptor := SD;
    
          PipeHandle := CreateNamedPipe('\\.\pipe\MyPipe', PIPE_ACCESS_DUPLEX,
            PIPE_TYPE_BYTE or PIPE_READMODE_BYTE, 1, 0, 0, 1000, @SecurityAttributes);
          result := PipeHandle <> INVALID_HANDLE_VALUE;
        end;
      end;
    end;
    
    procedure TPipeServer.Execute;
    begin
      if Start() then begin
        while true do begin
          if ConnectNamedPipe(PipeHandle, nil) then begin
            ...
          end;
        end;
      end;
    end;
    

    Connecting to pipe in IE toolbar (C++)

    #define PIPE_NAME "\\\\.\\pipe\\MYPipe"
    
    LRESULT CMFToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
    ...
        HANDLE PipeHandle;
        if (WaitNamedPipe(PIPE_NAME, NMPWAIT_WAIT_FOREVER) != 0) {
            PipeHandle = CreateFile(PIPE_NAME, FILE_READ_DATA | FILE_WRITE_DATA,
                0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
            if (PipeHandle != INVALID_HANDLE_VALUE) {
                WriteFile(PipeHandle, ...
                CloseHandle(PipeHandle);
            }
    
    }