When a process launches a child process, it becomes the parent of the child process. That is the default behaviour. In Vista however, a process can launch a process as a child of yet another process. This facility is used by User Account Control (UAC) when elevated processes are launched by AppInfo service to look like being launched from non-elevated process that would have been the parent, had there been no elevation.

The win32 call CreateProcess launches processes, and in Vista onwards one can pass a new flag in dwCreationFlags parameter called EXTENDED_STARTUPINFO_PRESENT that enables the caller to pass a STARTUPINFOEX structure pointer (instead of STARTUPINFO structure) in the lpStartupInfo parameter.1

The STARTUPINFOEX structure is declared in winbase.h like thus

STARTUPINFOEX declarations in winbase.h

Note the new member lpAttributeList, a pointer to _PROC_THREAD_ATTRIBUTE_LIST structure. That structure is where the parent process handle gets passed to CreateProcess.2

First lpAttributeList must point to an allocation of sufficient size so we can store some attributes in there. We are interested in setting just one attribute which is the parent process attribute

InitializeProcThreadAttributeList initializes lpAttributeList and is the first call that needs to be made on the _PROC_THREAD_ATTRIBUTE_LIST structure. InitializeProcThreadAttributeList also indicates space needed for the attributes that need to go in there. Here is how the initialization code may look like

Now that lpAttributeList is allocated and initialized for one attribute, UpdateProcThreadAttribute can be called to put in the PROC_THREAD_ATTRIBUTE_PARENT_PROCESS attribute, with the attribute value set to a handle to the parent process. The code would look something like this –


The launched process will appear to be child of the process passed rather than the process from which it was launched.

I am not sure how this can be put to good use in software3 but I hope next time you look at parent child relationships in Process Explorer (or call PsGetProcessInheritedFromUniqueProcessId to get the parent process id in a driver) you do not believe everything you see.





1To keep the compiler happy STARTUPINFOEX pointer would need to be type cast to LPSTARTUPINFO

2What is tricky is that the STARTUPINFOEX.StartupInfo.cb must be set to sizeof(STARTUPINFOEX) not sizeof(STARTUPINFO) even though StartupInfo is of type STARTUPINFO. It is as if StartupInfo member was an unnamed member of STARTUPINFOEX.

3The only one thing I can think of is a malware writer trying to cover tracks to make things difficult for threat analyst to figure out the anatomy of a threat.

Tagged with →  
Share →

2 Responses to Launching a non-child process

  1. Bovine says:

    Maybe this was intended to be used internally by user-mode Windows APIs such as CreateProcessWithLoginW(), which resulted in a parent identity of one of the service host processes instead of the originally launching process.

  2. Satya Das says:

    Yes, this could also be used with CreateProcessWithLogonW but will depend on whoever is calling CreateProcessWithLogonW. If you do runas, you will see that secondary logon service still ends up being the parent on Vista.

Leave a Reply

Your email address will not be published. Required fields are marked *


Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop us a note so we can take care of it!

Visit our friends!

A few highly recommended friends...

Set your Twitter account name in your settings to use the TwitterBar Section.