Copy link to clipboard
Copied
Hello i have an issue with creating COM objects in protected mode. As far as i know this type of action is forbiden in protected mode so i found this link. It says that I able to create named pipe if I specify something in NAMEDPIPES_ALLOW_ANY section. I tried with different naming and formats without result.
To be more clear i have a host application where named pipe created (C# application) and i want to connect to it from Adobe plug-in.
Also I looked at broker process but didn't found any information about possibility of creating COM objects if i implement custom broker.
So my question is: what name format should be at NAMEDPIPES_ALLOW_ANY to allow me create named pipe?
Copy link to clipboard
Copied
I’ve never worked with this but perhaps we can check your work. Please describe all the steps in detail that you have used to set the policy to enable named pipes.
Copy link to clipboard
Copied
Thx for your help.
1. I have host application where I created named pipe like this:
Task.Factory.StartNew(() =>
{
var server = new NamedPipeServerStream("foo");
server.WaitForConnection();
StreamWriter writer = new StreamWriter(server);
while (true)
{
writer.WriteLine("hello");
writer.Flush();
}
});
2. In Adobe plug-in (ACCB1 ASBool ACCB2 PluginInit(void) function) I tried to connect to it :
HANDLE hPipe;
hPipe = CreateFile(TEXT("\\\\.\\pipe\\foo"),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hPipe != INVALID_HANDLE_VALUE)
{
// do stuff
}
And I always get INVALID_HANDLE_VALUE result.
Add setting in reg. (HKLM_Software/Policies/Adobe/Acrobat Reader/DC/FeatureLockDown/bUseWhitelistConfigFile = 1)
In ProtectedModeWhitelistConfig.txt file which placed in C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader folder I added this lines :
FILES_ALLOW_ANY = pipe\*
NAMEDPIPES_ALLOW_ANY = \.\pipe\foo
I tried different string patterns in NAMEDPIPES_ALLOW_ANY section :
\\\\.\\pipe\\foo.*
\\\\.\\pipe\\foo
pipe\foo.*
pipe\foo
pipe\*
\\\\.\\pipe\\*
\.\pipe\*
Tried put only pipe name.
As well as at FILES_ALLOW_ANY section.
Also i enabled logs
Go to HKEY_CURRENT_USER\Software\Adobe\Acrobat Reader\(version)\Privileged.
Right click and choose New > REG_SZ Value.
Create tBrokerLogfilePath.
Right click on tBrokerLogfilePath and choose Modify.
Set the value. For example: C:\DOCUME~1\<username>\LOCALS~1\Temp\BrL4FBA.tmp.
Log :
[03:10/16:53:53] NtCreateFile: STATUS_ACCESS_DENIED
[03:10/16:53:53] real path: \??\pipe\foo
[03:10/16:53:53] Consider modifying policy using these policy rules: FILES_ALLOW_ANY or FILES_ALLOW_DIR_ANY
I got this message every time with different string pattern.
Copy link to clipboard
Copied
Thank you for the detail.
I would expect the pipe name to be either
\.\pipe\name or
\servername\pipe\name
However, I speculate we need to be led by the mesasge, which tells you to use FILES_ALLOW_ANY or FILES_ALLOW_DIR_ANY. I think this is because, as a client, you are using CreateFile. The sandbox does not need to know this is a named pipe. I look at the message. It mentions \??\pipe\foo. Is that ?? actually your redacted server name?
Whatever text is used, I would suggest using
FILES_ALLOW_ANY \??\pipe\foo
where ?? is as per the message.
The other thing would be to double check that the registry key HKLM/Software/Policies/Adobe/Acrobat Reader/DC/FeatureLockDown/bUseWhitelistConfigFile is a DWORD not a string, I have made this sort of mistake before.
Copy link to clipboard
Copied
bUseWhitelistConfigFile is DWORD value.
I thought that I made mistake at server path but I tested it on simple console application and it works fine. Host finds that someone connected to a pipe.
\??\pipe\foo - question mark placed by Adobe logger
var server = new NamedPipeServerStream("foo");
Creates pipe with default path \\\\.\\pipe\\pipeName
I tried :
FILES_ALLOW_ANY = \.\pipe\*
FILES_ALLOW_DIR_ANY = \.\pipe\*
NAMEDPIPES_ALLOW_ANY = \.\pipe\foo
FILES_ALLOW_ANY = .\pipe\*
FILES_ALLOW_DIR_ANY = .\pipe\*
NAMEDPIPES_ALLOW_ANY = .\pipe\foo
Result the same
Maybe I'm able somehow to make CoCreateInstance manage to work in protected mode?
Copy link to clipboard
Copied
I looked for info on \?? And find it has a specific meaning, see https://superuser.com/questions/1069055/what-is-the-function-of-question-marks-in-file-system-paths-... . I suggest you use the exact path shown in the message with the same number of \ and ?
You write it creates a path of the form starting\\.\\\\pipe but it does not. The \\ doubling is only part of C string constants and so the name is starting \.\pipe
Copy link to clipboard
Copied
Thx, i aware of C special symbols representation it was copy/paste.
Maybe there is a way to somehow allow to my plaug-in to create a COM objects by CoCreateInstance(...)?
For now in proteced mode it behaves like pipe creation.
Copy link to clipboard
Copied
Sorry I have no idea if you can make COM work. Did you try my last suggestion?
Copy link to clipboard
Copied
Yep, interesting that only with \??\ there no error in logs but creating a pipe fails.
[03:10/16:53:51] Adding custom policy: FILES_ALLOW_ANY = pipe\*
[03:10/16:53:51] Invalid path: pipe\*
[03:11/11:30:26] Adding custom policy: FILES_ALLOW_ANY = .\pipe\*
[03:11/11:30:26] Invalid path: .\pipe\*
[03:11/15:50:42] Adding custom policy: FILES_ALLOW_ANY = \.\pipe\*
[03:11/15:50:42] Invalid path: \.\pipe\*
[03:11/15:54:35] Adding custom policy: FILES_ALLOW_ANY = \??\pipe\*
Without error
[03:11/17:11:09] Adding custom policy: FILES_ALLOW_ANY = \pipe\*
[03:11/17:11:09] Invalid path: \pipe\*
Copy link to clipboard
Copied
Ok... that seems to have reached the limit of my knowledge. I someone else may visit the forum and have an idea.
Copy link to clipboard
Copied
Well, only one thought. I assume you have tested the client pipe creation in a standalone app (not the same app as the server end) and it works OK? A C app, I mean, using CreateFile. I have not seen anything about how to map pipe namespaces between .Net and C.
Copy link to clipboard
Copied
Yes, this is simple code:
// ConsoleApplication2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#define chrSize 16
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR chr[chrSize];
DWORD bytesRead;
HANDLE hPipe;
LPTSTR pipeName = TEXT("\\\\.\\pipe\\PipesOfPiece");
OVERLAPPED ovl;
HANDLE hEndRead;
hEndRead = CreateEvent(NULL, FALSE, FALSE, NULL);
ovl.Offset = 0;
ovl.OffsetHigh = 0;
ovl.hEvent = hEndRead;
hPipe = CreateFile(
pipeName, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file
if (hPipe != INVALID_HANDLE_VALUE)
{
//WriteFile(hPipe,
// "Hello Pipe\n",
// 12, // = length of string + terminating '\0' !!!
// &dwWritten,
// NULL);
for (;;)
{
DWORD dwBytesRead;
DWORD dwRet;
int n;
if (!ReadFile(
hPipe,
&n,
sizeof(n),
&dwBytesRead,
&ovl
))
{
switch (dwRet = GetLastError())
{
case ERROR_IO_PENDING:
//cout << "Read file pending." << endl;
break;
case ERROR_HANDLE_EOF:
//cout << endl << "End of the file." << endl;
//cout << "The file is read." << endl;
CloseHandle(hPipe);
CloseHandle(hEndRead);
return 1;
default:
/*cout << "Read file failed." << endl
<< "The last error code: " << dwRet << endl;*/
CloseHandle(hPipe);
CloseHandle(hEndRead);
return 0;
}
}
WaitForSingleObject(hEndRead, INFINITE);
//cout << n << ' ';
ovl.Offset += sizeof(n);
}
CloseHandle(hPipe);
}
return 0;
}
When CreateFile(...) process C# app react on that.
This line
server.WaitForConnection();
suspend thread on C# application and when C++ connect to a pipe by CreateFile() C# thread resumes and starts to write "hello"