A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about user-mode development.
 #20261  by Vrtule
 Mon Jul 29, 2013 5:06 pm
Hello,

my service runs under the SYSTEM account. From time to time, I would like the service to display some GUI to the user. I thought that probably the best solution for me would be that the service creates a new process that would display the GUI, and communicate with the service.

The problem is, how to decet which desktop is currently displayed to the user (I do not expect users connected remotely in this scenario). I hoped that OpenInputDesktop function would provide me with necessary infomration, howerver, the function seems to work different than I expected.

Is there a way how to create a new process the GUI of which will be displayed on a desktop currently visible to the user?
 #20270  by xp5evr
 Mon Jul 29, 2013 9:03 pm
ZeuS does something similar. Although what it seems to do is try to start a program in RDP session as user it also uses WTSQueryUserToken and CreateProcessAsUser mentioned in the article you linked, it also uses GetTokenInformation to get user token.

Not exactly the same as you are looking but if you are interested look at ZeuS source client\coreinstall.cpp, common\winsecurity.cpp and common\process.cpp.
 #20283  by TETYYSs
 Tue Jul 30, 2013 12:41 pm
You can just restart your process with Session 1 at your programs very start.
Take a look at Process hacker's "Run as..." function. It's open source.
 #20290  by xqrzd
 Tue Jul 30, 2013 7:24 pm
Here is my implementation of the article you attached. It works fine for me.
Code: Select all
DWORD currentSessionId = WTSGetActiveConsoleSessionId();
if (currentSessionId != 0xFFFFFFFF) //also check for 0
{
	HANDLE userToken;

	//printf("Session: %d", currentSessionId);
	if (WTSQueryUserToken(currentSessionId, &userToken))
	{
		STARTUPINFOW startupInfo;
		PROCESS_INFORMATION processInfo;

		RtlZeroMemory(&startupInfo, sizeof(startupInfo));
		RtlZeroMemory(&processInfo, sizeof(processInfo));
		startupInfo.cb = sizeof(startupInfo);

		if (CreateProcessAsUserW(userToken, L"cmd.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo))
		{
			CloseHandle(processInfo.hThread);
			CloseHandle(processInfo.hProcess);
		}
		else
			printf("CreateProcessAsUserW failed %d", GetLastError());

		CloseHandle(userToken);
	}
	else
		printf("WTSQueryUserToken failed %d", GetLastError());
}
else
	printf("WTSGetActiveConsoleSessionId failed");
edit: nevermind, didn't see you already had it working
 #20313  by Vrtule
 Wed Jul 31, 2013 2:45 pm
TETYYSs: my goal was to create process in current interactive session which, AFAIK, might not be the session 1. For example, when Fast User Switching is enabled, there might be quite a lot of interractive sessions, one of them will be the current one.

xqrzd: yes, my code is very similar to yours.