Does Process have a GUI?

@Johnny

With EnumThreadWindows I tried impersonating the process before passing the
threads to EnumThreadWindows. here is the impersonation code below:

// First open the process handle with query info rights. It is needed
to open a token.
HANDLE oProcHandle;
oProcHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
dwProcessID);
if (oProcHandle == NULL)
{
DoTraceError(“OpenProcess failed. Last Error = %!WINERROR!”,
GetLastError());
return HRESULT_FROM_WIN32(GetLastError());
}

// Open the process token with query and duplicate rights. They are
needed for impersonation.
HANDLE oTokenHandle;
if (FALSE == OpenProcessToken(oProcHandle, TOKEN_QUERY |
TOKEN_DUPLICATE, &oTokenHandle))
{
DoTraceError(“OpenProcessToken failed. Last Error = %!WINERROR!”,
GetLastError());
return HRESULT_FROM_WIN32(GetLastError());
}

// Impersonate the process token
if (FALSE == ImpersonateLoggedOnUser(oTokenHandle))
{
DoTraceError(“ImpersonateLoggedOnUser failed. Last Error =
%!WINERROR!”, GetLastError());
return HRESULT_FROM_WIN32(GetLastError());
}

I do not impersonate each thread (is that needed?)

After this code executes I call EnumWindows with the actual thread of this
process, assuming that my calling thread now has the same privilege as that
of the process being queried.

For EnumWindows and GetWindowThreadProcessId, the enumeration only returns
processes in the same session (session 0) I dont see any calls to the
EnumProc fucntion for any other process.

On Wed, Apr 19, 2017 at 11:05 PM, wrote:

> I’m kind of perplexed why EnumThreadWindows isn’t working for you. Maybe
> the token needs modified? Though usually Microsoft is good about
> documenting that. Maybe try EnumWindows and GetWindowThreadProcessId. Then
> EnumChildWindows and walk the chain from there. Not the most direct method
> but worth a shot maybe.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

Why don’t you launch a process in the user session (with the registry) and then setup an IPC channel between the two sessions ?

oh yeah, that is a solution we have, I was merely answering @Johnny’s
question to see if we did something specifically wrong.

For the sake of a future reader searching for a similar issue, this blog
post migth be very helpful:
https://brianbondy.com/blog/100/understanding-windows-at-a-deeper-level-sessions-window-stations-and-desktops

On Thu, Apr 20, 2017 at 1:38 PM, wrote:

> Why don’t you launch a process in the user session (with the registry) and
> then setup an IPC channel between the two sessions ?
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

On Thu, Apr 20, 2017 at 1:56 PM, A P wrote:
> @Johnny
>
> With EnumThreadWindows I tried impersonating the process before passing the
> threads to EnumThreadWindows. here is the impersonation code below:
>
> // First open the process handle with query info rights. It is needed
> to open a token.
> HANDLE oProcHandle;
> oProcHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
> dwProcessID);
> if (oProcHandle == NULL)
> {
> DoTraceError(“OpenProcess failed. Last Error = %!WINERROR!”,
> GetLastError());
> return HRESULT_FROM_WIN32(GetLastError());
> }
>
> // Open the process token with query and duplicate rights. They are
> needed for impersonation.
> HANDLE oTokenHandle;
> if (FALSE == OpenProcessToken(oProcHandle, TOKEN_QUERY |
> TOKEN_DUPLICATE, &oTokenHandle))
> {
> DoTraceError(“OpenProcessToken failed. Last Error = %!WINERROR!”,
> GetLastError());
> return HRESULT_FROM_WIN32(GetLastError());
> }
>
> // Impersonate the process token
> if (FALSE == ImpersonateLoggedOnUser(oTokenHandle))
> {
> DoTraceError(“ImpersonateLoggedOnUser failed. Last Error =
> %!WINERROR!”, GetLastError());
> return HRESULT_FROM_WIN32(GetLastError());
> }
>
> I do not impersonate each thread (is that needed?)
>
> After this code executes I call EnumWindows with the actual thread of this
> process, assuming that my calling thread now has the same privilege as that
> of the process being queried.
>
> For EnumWindows and GetWindowThreadProcessId, the enumeration only returns
> processes in the same session (session 0) I dont see any calls to the
> EnumProc fucntion for any other process.
>
>
> On Wed, Apr 19, 2017 at 11:05 PM, wrote:
>>
>> I’m kind of perplexed why EnumThreadWindows isn’t working for you. Maybe
>> the token needs modified? Though usually Microsoft is good about documenting
>> that. Maybe try EnumWindows and GetWindowThreadProcessId. Then
>> EnumChildWindows and walk the chain from there. Not the most direct method
>> but worth a shot maybe.
>>
>>

As best I know the window enumeration isn’t working because sessions
and stations are isolated in the kernel. They are incapable of
communicating without kernel involvement, and memory is in different
segments.

I strongly suggest following some of the links from this landing:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms687096(v=vs.85).aspx.

>The interactive window station is the only window station that can display a user >interface or receive user input. It is assigned to the logon session of the >interactive user, and contains the keyboard, mouse, and display device. It is >always named “WinSta0”. All other window stations are noninteractive, which >means they cannot display a user interface or receive user input.

Notably it is not explained why this is the case, nor is any mechanism
provided to subvert it. It is likely impossible to share GUI state
between sessions precisely because the kernel doesn’t want you to -
even if you used some form of IPC to pass handles between stations,
those handles are likely invalid on any other station.

If you have code running in the kernel that spans multiple stations
then you are doing something very odd and are completely on your own.
Some of the primitives you may need to access might not be accessible
and there may be no way to examine events that you might need to.

On Thu, Apr 20, 2017 at 3:53 PM, A P wrote:
> oh yeah, that is a solution we have, I was merely answering @Johnny’s
> question to see if we did something specifically wrong.
>
> For the sake of a future reader searching for a similar issue, this blog
> post migth be very helpful:
> https://brianbondy.com/blog/100/understanding-windows-at-a-deeper-level-sessions-window-stations-and-desktops
>

The heading “How to circumvent all security in Windows” is dubious,
but as mentioned, this won’t help you in the case of session and
station isolation.

> On Thu, Apr 20, 2017 at 1:38 PM, wrote:
>>
>> Why don’t you launch a process in the user session (with the registry) and
>> then setup an IPC channel between the two sessions ?
>>

I would strongly recommend
https://msdn.microsoft.com/en-us/library/windows/hardware/dn653293(v=vs.85).aspx.
The above, which has been mentioned many times, is the only supported
way to do what the original question wants.

Impersonating the user from the execution context of the process will have no effect here. The security boundary is not based on the security principal, but rather the process context from a GDI point of view. Look at the windows station APIs in MSDN. Here is a good place to start

https://msdn.microsoft.com/en-us/library/windows/desktop/ms687096(v=vs.85).aspx

and then you will want to go here

https://msdn.microsoft.com/en-us/library/windows/desktop/ms686232(v=vs.85).aspx

Sent from Mailhttps: for Windows 10

From: A Pmailto:xxxxx
Sent: April 20, 2017 2:56 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: Re: [ntdev] Does Process have a GUI?

@Johnny

With EnumThreadWindows I tried impersonating the process before passing the threads to EnumThreadWindows. here is the impersonation code below:
// First open the process handle with query info rights. It is needed to open a token.
HANDLE oProcHandle;
oProcHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessID);
if (oProcHandle == NULL)
{
DoTraceError(“OpenProcess failed. Last Error = %!WINERROR!”, GetLastError());
return HRESULT_FROM_WIN32(GetLastError());
}

// Open the process token with query and duplicate rights. They are needed for impersonation.
HANDLE oTokenHandle;
if (FALSE == OpenProcessToken(oProcHandle, TOKEN_QUERY | TOKEN_DUPLICATE, &oTokenHandle))
{
DoTraceError(“OpenProcessToken failed. Last Error = %!WINERROR!”, GetLastError());
return HRESULT_FROM_WIN32(GetLastError());
}

// Impersonate the process token
if (FALSE == ImpersonateLoggedOnUser(oTokenHandle))
{
DoTraceError(“ImpersonateLoggedOnUser failed. Last Error = %!WINERROR!”, GetLastError());
return HRESULT_FROM_WIN32(GetLastError());
}

I do not impersonate each thread (is that needed?)

After this code executes I call EnumWindows with the actual thread of this process, assuming that my calling thread now has the same privilege as that of the process being queried.

For EnumWindows and GetWindowThreadProcessId, the enumeration only returns processes in the same session (session 0) I dont see any calls to the EnumProc fucntion for any other process.

On Wed, Apr 19, 2017 at 11:05 PM, > wrote:
I’m kind of perplexed why EnumThreadWindows isn’t working for you. Maybe the token needs modified? Though usually Microsoft is good about documenting that. Maybe try EnumWindows and GetWindowThreadProcessId. Then EnumChildWindows and walk the chain from there. Not the most direct method but worth a shot maybe.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:

— NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers! Details at To unsubscribe, visit the List Server section of OSR Online at</http:></http:></http:></mailto:xxxxx></mailto:xxxxx></https:>

This statement

The interactive window station is the only window station that can display a user >interface or receive user input. It is assigned to the logon session of the >interactive user, and contains the keyboard, mouse, and display device. It is >always named “WinSta0”. All other window stations are noninteractive, which >means they cannot display a user interface or receive user input.

Is false. It dates from Windows 2000 and should be updated. Remote desktop and fast user switching rely on multiple interactive desktops and windows stations

Sent from Mailhttps: for Windows 10

From: R0b0t1mailto:xxxxx
Sent: April 20, 2017 5:35 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: Re: [ntdev] Does Process have a GUI?

On Thu, Apr 20, 2017 at 1:56 PM, A P wrote:
> @Johnny
>
> With EnumThreadWindows I tried impersonating the process before passing the
> threads to EnumThreadWindows. here is the impersonation code below:
>
> // First open the process handle with query info rights. It is needed
> to open a token.
> HANDLE oProcHandle;
> oProcHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
> dwProcessID);
> if (oProcHandle == NULL)
> {
> DoTraceError(“OpenProcess failed. Last Error = %!WINERROR!”,
> GetLastError());
> return HRESULT_FROM_WIN32(GetLastError());
> }
>
> // Open the process token with query and duplicate rights. They are
> needed for impersonation.
> HANDLE oTokenHandle;
> if (FALSE == OpenProcessToken(oProcHandle, TOKEN_QUERY |
> TOKEN_DUPLICATE, &oTokenHandle))
> {
> DoTraceError(“OpenProcessToken failed. Last Error = %!WINERROR!”,
> GetLastError());
> return HRESULT_FROM_WIN32(GetLastError());
> }
>
> // Impersonate the process token
> if (FALSE == ImpersonateLoggedOnUser(oTokenHandle))
> {
> DoTraceError(“ImpersonateLoggedOnUser failed. Last Error =
> %!WINERROR!”, GetLastError());
> return HRESULT_FROM_WIN32(GetLastError());
> }
>
> I do not impersonate each thread (is that needed?)
>
> After this code executes I call EnumWindows with the actual thread of this
> process, assuming that my calling thread now has the same privilege as that
> of the process being queried.
>
> For EnumWindows and GetWindowThreadProcessId, the enumeration only returns
> processes in the same session (session 0) I dont see any calls to the
> EnumProc fucntion for any other process.
>
>
> On Wed, Apr 19, 2017 at 11:05 PM, wrote:
>>
>> I’m kind of perplexed why EnumThreadWindows isn’t working for you. Maybe
>> the token needs modified? Though usually Microsoft is good about documenting
>> that. Maybe try EnumWindows and GetWindowThreadProcessId. Then
>> EnumChildWindows and walk the chain from there. Not the most direct method
>> but worth a shot maybe.
>>
>>

As best I know the window enumeration isn’t working because sessions
and stations are isolated in the kernel. They are incapable of
communicating without kernel involvement, and memory is in different
segments.

I strongly suggest following some of the links from this landing:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms687096(v=vs.85).aspx.

>The interactive window station is the only window station that can display a user >interface or receive user input. It is assigned to the logon session of the >interactive user, and contains the keyboard, mouse, and display device. It is >always named “WinSta0”. All other window stations are noninteractive, which >means they cannot display a user interface or receive user input.

Notably it is not explained why this is the case, nor is any mechanism
provided to subvert it. It is likely impossible to share GUI state
between sessions precisely because the kernel doesn’t want you to -
even if you used some form of IPC to pass handles between stations,
those handles are likely invalid on any other station.

If you have code running in the kernel that spans multiple stations
then you are doing something very odd and are completely on your own.
Some of the primitives you may need to access might not be accessible
and there may be no way to examine events that you might need to.

On Thu, Apr 20, 2017 at 3:53 PM, A P wrote:
> oh yeah, that is a solution we have, I was merely answering @Johnny’s
> question to see if we did something specifically wrong.
>
> For the sake of a future reader searching for a similar issue, this blog
> post migth be very helpful:
> https://brianbondy.com/blog/100/understanding-windows-at-a-deeper-level-sessions-window-stations-and-desktops
>

The heading “How to circumvent all security in Windows” is dubious,
but as mentioned, this won’t help you in the case of session and
station isolation.

> On Thu, Apr 20, 2017 at 1:38 PM, wrote:
>>
>> Why don’t you launch a process in the user session (with the registry) and
>> then setup an IPC channel between the two sessions ?
>>

I would strongly recommend
https://msdn.microsoft.com/en-us/library/windows/hardware/dn653293(v=vs.85).aspx.
The above, which has been mentioned many times, is the only supported
way to do what the original question wants.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx></mailto:xxxxx></https:>

On Sun, Apr 23, 2017 at 4:12 PM, Marion Bond wrote:
> This statement
>
>
>
>>The interactive window station is the only window station that can display
>> a user >interface or receive user input. It is assigned to the logon session
>> of the >interactive user, and contains the keyboard, mouse, and display
>> device. It is >always named “WinSta0”. All other window stations are
>> noninteractive, which >means they cannot display a user interface or receive
>> user input.
>
>
> Is false. It dates from Windows 2000 and should be updated. Remote desktop
> and fast user switching rely on multiple interactive desktops and windows
> stations
>
>
>
> Sent from Mail for Windows 10
>
>

Multiple interactive desktops are possible due to the creation of
multiple sessions. Each session has a sole interactive window station.

There are privileges granted to sessions that are not granted to
anything else, and there is no way to create a session besides logging
in - and if your computer is not licensed as a terminal server you can
only log in one user at a time. This implies it is impossible to
implement fast user switching or remote desktop (i.e. terminal
services) without low-level OS involvement, which is the case.

>
> From: R0b0t1
> Sent: April 20, 2017 5:35 PM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] Does Process have a GUI?
>
>
>
> On Thu, Apr 20, 2017 at 1:56 PM, A P wrote:
>
>
>> @Johnny
>>
>> With EnumThreadWindows I tried impersonating the process before passing
>> the
>> threads to EnumThreadWindows. here is the impersonation code below:
>>
>> // First open the process handle with query info rights. It is needed
>> to open a token.
>> HANDLE oProcHandle;
>> oProcHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
>> dwProcessID);
>> if (oProcHandle == NULL)
>> {
>> DoTraceError(“OpenProcess failed. Last Error = %!WINERROR!”,
>> GetLastError());
>> return HRESULT_FROM_WIN32(GetLastError());
>> }
>>
>> // Open the process token with query and duplicate rights. They are
>> needed for impersonation.
>> HANDLE oTokenHandle;
>> if (FALSE == OpenProcessToken(oProcHandle, TOKEN_QUERY |
>> TOKEN_DUPLICATE, &oTokenHandle))
>> {
>> DoTraceError(“OpenProcessToken failed. Last Error = %!WINERROR!”,
>> GetLastError());
>> return HRESULT_FROM_WIN32(GetLastError());
>> }
>>
>> // Impersonate the process token
>> if (FALSE == ImpersonateLoggedOnUser(oTokenHandle))
>> {
>> DoTraceError(“ImpersonateLoggedOnUser failed. Last Error =
>> %!WINERROR!”, GetLastError());
>> return HRESULT_FROM_WIN32(GetLastError());
>> }
>>
>> I do not impersonate each thread (is that needed?)
>>
>> After this code executes I call EnumWindows with the actual thread of this
>> process, assuming that my calling thread now has the same privilege as
>> that
>> of the process being queried.
>>
>> For EnumWindows and GetWindowThreadProcessId, the enumeration only returns
>> processes in the same session (session 0) I dont see any calls to the
>> EnumProc fucntion for any other process.
>>
>>
>> On Wed, Apr 19, 2017 at 11:05 PM, wrote:
>>>
>>> I’m kind of perplexed why EnumThreadWindows isn’t working for you. Maybe
>>> the token needs modified? Though usually Microsoft is good about
>>> documenting
>>> that. Maybe try EnumWindows and GetWindowThreadProcessId. Then
>>> EnumChildWindows and walk the chain from there. Not the most direct
>>> method
>>> but worth a shot maybe.
>>>
>>>
>
> As best I know the window enumeration isn’t working because sessions
> and stations are isolated in the kernel. They are incapable of
> communicating without kernel involvement, and memory is in different
> segments.
>
> I strongly suggest following some of the links from this landing:
> https://msdn.microsoft.com/en-us/library/windows/desktop/ms687096(v=vs.85).aspx.
>
>>The interactive window station is the only window station that can display
>> a user >interface or receive user input. It is assigned to the logon session
>> of the >interactive user, and contains the keyboard, mouse, and display
>> device. It is >always named “WinSta0”. All other window stations are
>> noninteractive, which >means they cannot display a user interface or receive
>> user input.
>
> Notably it is not explained why this is the case, nor is any mechanism
> provided to subvert it. It is likely impossible to share GUI state
> between sessions precisely because the kernel doesn’t want you to -
> even if you used some form of IPC to pass handles between stations,
> those handles are likely invalid on any other station.
>
> If you have code running in the kernel that spans multiple stations
> then you are doing something very odd and are completely on your own.
> Some of the primitives you may need to access might not be accessible
> and there may be no way to examine events that you might need to.
>
> On Thu, Apr 20, 2017 at 3:53 PM, A P wrote:
>> oh yeah, that is a solution we have, I was merely answering @Johnny’s
>> question to see if we did something specifically wrong.
>>
>> For the sake of a future reader searching for a similar issue, this blog
>> post migth be very helpful:
>>
>> https://brianbondy.com/blog/100/understanding-windows-at-a-deeper-level-sessions-window-stations-and-desktops
>>
>
> The heading “How to circumvent all security in Windows” is dubious,
> but as mentioned, this won’t help you in the case of session and
> station isolation.
>
>> On Thu, Apr 20, 2017 at 1:38 PM, wrote:
>>>
>>> Why don’t you launch a process in the user session (with the registry)
>>> and
>>> then setup an IPC channel between the two sessions ?
>>>
>
> I would strongly recommend
> https://msdn.microsoft.com/en-us/library/windows/hardware/dn653293(v=vs.85).aspx.
> The above, which has been mentioned many times, is the only supported
> way to do what the original question wants.
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at:
> http:
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
>
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at:
> http:
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:</http:></http:></http:></http:></http:></http:>