It seems that starting with Windows Vista, processes with a lower integrity level (IL) cannot send messages to processes with higher integrity levels. This makes sense from a security standpoint, but it breaks some of our interprocess communication.
We have a legacy application (Process A) that unfortunately has to run with elevated "admin" privileges (accomplished by setting its shortcut to always run as administrator). At times it needs to instantiate a separate application (Process B). As a result, Process B inherits the same elevated privileges (and IL) as Process A. Therein lies the problem. There might be other independent instances of Process B that do not have elevated privileges, and all of these Process B instances need to be able to send messages to each other. This obviously fails if one instance of Process B is elevated and another is not.
I know we can open holes in the UIPI message filter using the ChangeWindowMessageFilter
API method, but this doesn't seem like the ideal solution. Instead, I would much rather have Process A spawn Process B with reduced privileges, specifically so that it can communicate with the other Process B instances. I think by default the other Process B instances run at the "Medium" IL, so therefore I'd like Process A to spawn Process B instances with this same IL.
My searches have led me to the CreateProcessAsUser
and CreateRestrictedToken
API methods, but despite this documentation, all of the various facets of tokens and security descriptors and such is still very confusing to me.
I've also come across some threads here (Running a process with lowest possible privileges in winapi and Dropping privileges in C++ on Windows), but I can't find any good examples with code.
Can anyone provide me with some simple yet "correct" code that will help me spawn child processes using the appropriate Windows IL? Specifically, I'd like an example of how to take the existing Process A token and convert it so it has the reduced privileges (I'm pretty sure I can figure out the rest). I'm really unclear about whether I need to duplicate the process' token before modifying it as well.