Skip to content

Instantly share code, notes, and snippets.

@notmike101
Created June 28, 2014 01:26
Show Gist options
  • Save notmike101/b35eed7e1f221d5abdc7 to your computer and use it in GitHub Desktop.
Save notmike101/b35eed7e1f221d5abdc7 to your computer and use it in GitHub Desktop.
#include <Windows.h>
bool runInSafeScreen(const char *, const char *);
BOOL IsUserAdmin(VOID);
int main() {
// We need to check if the user has administrator privileges.
if (!IsUserAdmin()) {
// If they don't, tell them they need administrator privileges.
printf("Please run this program as an administrator\n");
} else {
// Otherwise, lets run notepad in a secure desktop with the default name.
runInSafeScreen("C:\\Windows\\notepad.exe");
}
// BAD DON'T DO THIS. ONLY DOING THIS CAUSE I AM TOO LAZY TO
// INCLUDE IOSTREAM! ALSO DON'T WANT TO INCLUDE A WHOLE LIBRARY
// FOR ONE FUNCTION!
system("PAUSE");
// And exit without any errors
return 0;
}
/*
IsUserAdmin returns true if the user running the program has admin
privileges and false if they do not.
Source: http://msdn.microsoft.com/en-us/library/windows/desktop/aa376389%28v=vs.85%29.aspx
*/
BOOL IsUserAdmin(VOID) {
BOOL b;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
b = AllocateAndInitializeSid(
&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&AdministratorsGroup);
if (b)
{
if (!CheckTokenMembership(NULL, AdministratorsGroup, &b))
{
b = FALSE;
}
FreeSid(AdministratorsGroup);
}
return(b);
}
/*
runInSafeScreen returns true if the program was successfully ran,
and false if it was not. It takes in two parameters, the path to the
file that it needs to run, and a name for the new desktop environment.
The name for the new desktop environemtn is optional, and if it is not
passed in, it will be given the name "hiddenDesktop".
*/
bool runInSafeScreen(const char* szAppPath, const char *szDesktop = "hiddenDesktop") {
// Initialize a boolean value for later use.
bool ret = true;
// Create null pointers for later use.
HDESK hRealDesktop = NULL, hNewDesktop = NULL;
HWINSTA hRealWinsta = NULL, hNewWinsta = NULL;
// Set the hRealDesktop pointter to the current desktop thread.
// This is done so we can later switch back to the main desktop environemnt.
// For more info on window desktops: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682573%28v=vs.85%29.aspx
hRealDesktop = GetThreadDesktop(GetCurrentThreadId());
// Set the hRealWinsta pointter to the current Windows Station thread.
// This is done so we can later switch back to the main desktop environemnt.
// For more info on window stations: http://msdn.microsoft.com/en-us/library/windows/desktop/ms687096%28v=vs.85%29.aspx
hRealWinsta = GetProcessWindowStation();
// Create a new windows station and set it to the hNewWinsta pointer.
if (hNewWinsta = CreateWindowStation(
"hiddenWinSta", // Give it the name "hiddenWinSta".
0, // Additional creation flags. We don't need any.
WINSTA_CREATEDESKTOP, // This allows us to create new desktop environments.
NULL // Additional security flags. We don't need any.
)) {
// Switch to the window station we just created.
SetProcessWindowStation(OpenWindowStation("hiddenWinSta", TRUE, 0));
// Create a new windows desktop and set it to the hNewDesktop pointer.
if (hNewDesktop = CreateDesktop(
szDesktop, // Give it the name that we passed into the function. By default, this will be "hiddenDesktop"
NULL, // Must be NULL.
NULL, // Must be NULL.
0, // Additional creation flags. We don't need any.
DESKTOP_CREATEWINDOW | DESKTOP_SWITCHDESKTOP, // Additional access flags. We need to create windows in this desktop and be able to switch out of it.
NULL // Additional security flags. We don't need any.
)) {
// Switch to the new desktop we just created
SetThreadDesktop(hNewDesktop);
SwitchDesktop(hNewDesktop);
// This next part is what we will use to create our process...
// In other words, we start our program.
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo;
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo;
// This is needed to tell the program what desktop to run on.
// We are telling it to run on this new desktop we created.
char tmp[1024];
strcpy(tmp, szDesktop);
StartupInfo.lpDesktop = tmp;
// Attempt to start the program.
if (!CreateProcess(szAppPath, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo)) {
// If it can't start, just set the return value to "false" and move on.
ret = false;
} else {
// Otherwise, wait for the program to close...
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
// Then be 100% sure the program is closed.
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
}
// Wait 300 miliseconds...
// This isn't required, but it's always good to be sure.
Sleep(300);
// Then switch back to the "real" desktop environment.
SwitchDesktop(hRealDesktop);
SetThreadDesktop(hRealDesktop);
// And get rid of the one we created earlier. We don't need it anymore.
CloseDesktop(hNewDesktop);
} else {
// Looking back to an earlier part of the code, if we were not able to create
// the new desktop environment, we will just set the return value to false
// and move on.
ret = false;
}
// Switch back to the "real" desktop environment.
SetProcessWindowStation(hRealWinsta);
// And get rid of the one we created earlier. We don't need it anymore.
CloseWindowStation(hNewWinsta);
} else {
// Looking back to an earlier part of the code, if we were not able to create
// the new window environment, we will just set the return value to false
// and move on.
ret = false;
}
// And finally, return whatever the return value is. This will let us know the
// final state of what we just did.
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment