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

佐手、 提交于 2019-11-29 07:21:09

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);
        }

}

you can add the ALL_APPLICATION_PACKAGE permission to the handle, but it's a backdoor solution,the broker solution is long term.

DWORD WindowsSecurity::AddDACLToObject(HANDLE hObj,SE_OBJECT_TYPE seObjectType) {
LPWSTR szAddSid = 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)pSIDAllAppPackage;

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;

}

Vivek

I found this question very useful and wanted to add in my 2 cents based on my recent experience with retrofitting an EPM-compatible BHO in a complex product. Dropping some info here that will hopefully help the community. My original question was posted here, so some of it is a repeat of my comments there - Accessing named pipe servers from within IE EPM BHO

I needed some way to achieve 2-way communication -

  1. From BHO to a Windows Service that held some relevant data : The security descriptor above will not work because cross-session IPC doesn't seem to work. I tried setting the named pipes to allow EVERYONE too.

    • Solved it by adding a broker to relay the communication.
  2. From external to BHO : This was to provide the BHO some data to perform actions - DOM manipulation etc. Standard IPC options - named pipes, Windows RPC etc. won't work because the BHO cannot host the named pipe servers for external access, looks like.

    • Solved it by creating a HWND_MESSAGE window in the SetSite function and calling to it from the Broker process using SendMessage. Message type used needs to be WM_COPYDATA since this is cross-process.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!