Boost interprocess message_queue and COM - winapi

I'm using boost::interprocess::message_queue for communication between processes. In one of them i use
::CoInitializeEx( 0, COINIT_MULTITHREADED );
to set up for COM calls. I cannot access any queues created after this call from the other process, or for that matter the same process but before the CoInit call.
I'm not terribly famililar with COM and their threading model, the CoInit call was added by a co-worker. What can I do to resolve this?
Here is a short snippet to illustrate:
boost::interprocess::message_queue m_queue1( boost::interprocess::open_or_create, "testqueue", 256, sizeof(int) );
::CoInitializeEx( 0, COINIT_MULTITHREADED );
boost::interprocess::message_queue m_queue2( boost::interprocess::open_only, "testqueue" );
In this example the second queue's constructor will throw an exception because it thinks the queue doesn't exist. If I remove the CoInit call it works fine.
EDIT:
Boost version is 1.46.1. The call to CoInit in the snippet above returns S_OK.

Related

Injecting a DLL from LoadImageNotifyRoutine, hangs on ZwMapViewOfSection

So I'm making a crackme and one of the parts is to hook a certain function and wait for a certain combination a params to happen, then the challenge is done.
For that, I'm creating a driver to inject a DLL into processes that have a specific DLL and hook a certain function.
I'm doing it by
Getting a handle for the DLL to inject
ZwCreateFile(
&DeviceExtension->HookDllHandle,
GENERIC_ALL,
&Attributes,
&StatusBlock,
NULL,
0,
0,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
)
Then, registering a LoadImageNotifyRoutine inside driver main
PsSetLoadImageNotifyRoutine(ImageCBK);
What's supposed to happen:
I check the if the needed DLL (that will export my function) is loaded.
By being inside the context of the process that invoked the callback, I create a section with ZwCreateSection, then map the dll into that section and call the DLL's entry point by creating a new thread.
After that, the hooking should be no problem.
Even though the IRQL for ZwCreateSection and ZwMapViewOfSection allows their use inside a notify routine, still ZwMapViewOfSection hangs every time I try to use it.
I've been using some code from Beholder
status = ObOpenObjectByPointer(PsGetCurrentProcess(), OBJ_KERNEL_HANDLE, NULL, STANDARD_RIGHTS_ALL, NULL, KernelMode, &ProcessHandle);
if (!NT_SUCCESS(status))
{
DbgPrint("Unable to get process handle\n");
return STATUS_SEVERITY_ERROR;
}
// Create a new section for DLL mapping
InitializeObjectAttributes(&Attributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
status = ZwCreateSection(&DllSectionHandle, SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_QUERY, &Attributes, NULL, PAGE_EXECUTE_READ, SEC_IMAGE, DeviceExtension->HookDllHandle);
if (!NT_SUCCESS(status))
{
ZwClose(ProcessHandle);
DbgPrint("Section creation failed %08X\n", status);
return status;
}
DbgPrint("Section created %08X\n", DllSectionHandle);
// Map DLL on the section
status = ZwMapViewOfSection(DllSectionHandle, ProcessHandle, &DllBaseAddress, 0, 0, NULL, &DllViewSize, ViewUnmap, 0, PAGE_EXECUTE_READ);
if (!NT_SUCCESS(status))
{
ZwClose(ProcessHandle);
ZwClose(DllSectionHandle);
DbgPrint("Unable to map section %08X\n", status);
return status;
}
DbgPrint("Mapped DLL: %08X\n", DllBaseAddress);
Sadly, it never shows the last DbgPrint with the DllBaseAddress
simply read documentation
The operating system calls the driver's load-image notify routine at
PASSIVE_LEVEL inside a critical region with normal kernel APCs always
disabled
and
To avoid deadlocks, load-image notify routines must not call system
routines that map, allocate, query, free, or perform other operations
on user-space virtual memory.
you ignore this and call routine ZwMapViewOfSection that map. and got deadlock
solution is simply and elegant - insert normal kernel mode APC to current thread inside ImageCBK. because this APC is disabled here - it executed already after you return from ImageCBK -just system exit from critical region and enable APC. at this point your apc KernelRoutine/NormalRoutine will be called. and exactly inside NormalRoutine you must map

Can't pass OVERLAPPED object to WSAGetOverlappedResult

I'm trying to develop req/res server by using overlapped io according to this example.
The problem is that in the same time there could be multiple sends to the same socket and I can't pass overlapped structure to the WSAGetOverlappedResult to manage send event properly. The main loop looks like:
while (TRUE) {
index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, TRUE);
if (index == WSA_WAIT_FAILED) {
printf("Wait failed w/err %d\n", WSAGetLastError());
continue;
}
index -= WSA_WAIT_EVENT_0;
if (!WSAEnumNetworkEvents(SocketArray[index]->Socket, EventArray[index], &NetworkEvents)) { // Multiple events max exist
if (NetworkEvents.lNetworkEvents & FD_ACCEPT)
ManageAccept(index, NetworkEvents);
if (NetworkEvents.lNetworkEvents & FD_READ)
ManageRead(index, NetworkEvents);
if (NetworkEvents.lNetworkEvents & FD_WRITE)
ManageWrite(index, NetworkEvents);
}
}
Then I send messages from method ManageRead to the client socket with
WSASend(SocketArray[index]->Socket, &(over->wsabuf), 1, &SendBytes, 0, over, NULL)
And when overlapped send completed I can't really realize in the method ManageSend which of the overlapped structures was actually sent with the call WSAGetOverlappedResult:
WSAGetOverlappedResult(SocketArray[index]->Socket, over, &SendBytes, FALSE, &flags)
I have to use WorkerRoutine temporary to gain control over sending but perhaps somebody knows how to address the issue. Or may there is some different method which returns the overlapped structure which was completed?

Windows crash in ChangeServiceConfig2

I'm having a problem with ChangeServiceConfig2(...SERVICE_CONFIG_TRIGGER_INFO...)
Relevant code:
WCHAR test[] = L"TEST12";
SERVICE_TRIGGER_SPECIFIC_DATA_ITEM stdata {
SERVICE_TRIGGER_DATA_TYPE_STRING,
wcslen(test)*sizeof(WCHAR),
reinterpret_cast<BYTE*>(test)
};
SERVICE_TRIGGER st {
SERVICE_TRIGGER_TYPE_NETWORK_ENDPOINT,
SERVICE_TRIGGER_ACTION_SERVICE_START,
const_cast<GUID*>(&NAMED_PIPE_EVENT_GUID),
1, &stdata
};
ChangeServiceConfig2(Service, SERVICE_CONFIG_TRIGGER_INFO, &st);
This causes an Access Violation on address 00000009, so clearly an unchecked null pointer. And it's not a null pointer in st or stdata. The address 00000009 does not depend on the length of test[].
Stack dump:
rpcrt4.dll!NdrpEmbeddedRepeatPointerBufferSize()
rpcrt4.dll!NdrConformantArrayBufferSize()
rpcrt4.dll!NdrSimpleStructBufferSize()
rpcrt4.dll!NdrpUnionBufferSize()
rpcrt4.dll!_NdrNonEncapsulatedUnionBufferSize#12()
rpcrt4.dll!NdrComplexStructBufferSize()
rpcrt4.dll!NdrClientCall2() rpcrt4.dll!_NdrClientCall4()
sechost.dll!ChangeServiceConfig2W()
The Service member is not the problem, or ChangeServiceConfig2 itself: I can set the service description via ChangeServiceConfig2(Service, SERVICE_CONFIG_DESCRIPTION, &desc);. The problem appears to be in the parsing of SERVICE_TRIGGER. Named Pipe service triggers apparently work for the Remote Registry service, so it's not fundamentally broken.
Q: which part of my SERVICE_TRIGGER is wrong?
Obviously there is at least one bug in Windows; at the very least it fails in parameter validation.
The SERVICE_TRIGGER object is correct, but ChangeServiceConfig2 wants a SERVICE_TRIGGER_INFO. Simple solution: wrap st using SERVICE_TRIGGER_INFO sti{ 1, &st, NULL };

how to pass a process thread handle to another process

I need to pass a thread handle for APC to another process in order to be able to call QueueUserAPC into the src thread :
HANDLE SMconsumerThread;
if (!DuplicateHandle(GetCurrentProcess(),// src server thread
GetCurrentThread(),
GetCurrentProcess(),// target is any client
(HANDLE*)&SMconsumerThread,
THREAD_SET_CONTEXT, // only permission required by QueueUserAPC
FALSE, // not inheritable
0)) // no options
{
printf("cannot server thread handle");
}
how is it done, because GetCurrentProcess/GetCurrentThread return the pseudo handle -1 within the caller process, I found this explanation for passing sockets among processes: http://tangentsoft.net/wskfaq/articles/passing-sockets.html
are there any examples or explanations how to duplicate a thread handle ?

How do I automatically destroy child processes in Windows?

In C++ Windows app, I launch several long running child processes (currently I use CreateProcess(...) to do this.
I want the child processes to be automatically closed if my main processes crashes or is closed.
Because of the requirement that this needs to work for a crash of the "parent", I believe this would need to be done using some API/feature of the operating system. So that all the "child" processes are cleaned up.
How do I do this?
The Windows API supports objects called "Job Objects". The following code will create a "job" that is configured to shut down all processes when the main application ends (when its handles are cleaned up). This code should only be run once.:
HANDLE ghJob = CreateJobObject( NULL, NULL); // GLOBAL
if( ghJob == NULL)
{
::MessageBox( 0, "Could not create job object", "TEST", MB_OK);
}
else
{
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
// Configure all child processes associated with the job to terminate when the
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if( 0 == SetInformationJobObject( ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
{
::MessageBox( 0, "Could not SetInformationJobObject", "TEST", MB_OK);
}
}
Then when each child process is created, execute the following code to launch each child each process and add it to the job object:
STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;
// Launch child process - example is notepad.exe
if (::CreateProcess( NULL, "notepad.exe", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
::MessageBox( 0, "CreateProcess succeeded.", "TEST", MB_OK);
if(ghJob)
{
if(0 == AssignProcessToJobObject( ghJob, processInfo.hProcess))
{
::MessageBox( 0, "Could not AssignProcessToObject", "TEST", MB_OK);
}
}
// Can we free handles now? Not sure about this.
//CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
VISTA NOTE: See AssignProcessToJobObject always return "access denied" on Vista if you encounter access-denied issues with AssignProcessToObject() on vista.
One somewhat hackish solution would be for the parent process to attach to each child as a debugger (use DebugActiveProcess). When a debugger terminates all its debuggee processes are terminated as well.
A better solution (assuming you wrote the child processes as well) would be to have the child processes monitor the parent and exit if it goes away.
Windows Job Objects sounds like a good place to start. The name of the Job Object would have to be well-known, or passed to the children (or inherit the handle). The children would need to be notice when the parent dies, either through a failed IPC "heartbeat" or just WFMO/WFSO on the parent's process handle. At that point any child process could TermianteJobObject to bring down the whole group.
You can keep a separate watchdog process running. Its only task is watching the current process space to spot situations like you describe. It could even re-launch the original application after a crash or provide different options to the user, collect debug information, etc. Just try to keep it simple enough so that you don't need a second watchdog to watch the first one.
You can assign a job to the parent process before creating processes:
static HANDLE hjob_kill_on_job_close=INVALID_HANDLE_VALUE;
void init(){
hjob_kill_on_job_close = CreateJobObject(NULL, NULL);
if (hjob_kill_on_job_close){
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobli = { 0 };
jobli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
SetInformationJobObject(hjob_kill_on_job_close,
JobObjectExtendedLimitInformation,
&jobli, sizeof(jobli));
AssignProcessToJobObject(hjob_kill_on_job_close, GetCurrentProcess());
}
}
void deinit(){
if (hjob_kill_on_job_close) {
CloseHandle(hjob_kill_on_job_close);
}
}
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE causes all processes associated with the job to terminate when the last handle to the job is closed. By default, all child processes will be assigned to the job automatically, unless you passed CREATE_BREAKAWAY_FROM_JOB when calling CreateProcess. See https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags for more information about CREATE_BREAKAWAY_FROM_JOB.
You can use process explorer from Sysinternals to make sure all processes are assigned to the job. Just like this:
You'd probably have to keep a list of the processes you start, and kill them off one by one when you exit your program. I'm not sure of the specifics of doing this in C++ but it shouldn't be hard. The difficult part would probably be ensuring that child processes are shutdown in the case of an application crash. .Net has the ability to add a function that get's called when an unhandled exception occurs. I'm not sure if C++ offers the same capabilities.
You could encapsulate each process in a C++ object and keep a list of them in global scope. The destructors can shut down each process. That will work fine if the program exits normally but it it crashes, all bets are off.
Here is a rough example:
class myprocess
{
public:
myprocess(HANDLE hProcess)
: _hProcess(hProcess)
{ }
~myprocess()
{
TerminateProcess(_hProcess, 0);
}
private:
HANDLE _hProcess;
};
std::list<myprocess> allprocesses;
Then whenever you launch one, call allprocessess.push_back(hProcess);

Resources