Reputation: 11
I'm working on an application that runs with SYSTEM level privileges and is created by the SYSTEM user. I need to track foreground activities for the currently logged-in user. I'm using SetWinEventHook for the same. It works fine when I run the application from my current user. But if I started the application with the SYSTEM user, it was unable to receive events. Is there any workaround to trigger this with user context?
Edit: g_hook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, NULL, focusChangeCallbackHandle, 0, 0, WINEVENT_OUTOFCONTEXT); focusChangeCallbackHandle is a in same namespace as the caller function
Edit 2:
Adding my boilerplate code here: I'm using pstools to run the binary with the SYSTEM user. Also not sure why but after running any of the getter/setters of ThreadDesktop and WindowStation my application stop printing on the console.
void ForegroundCheck() {
printf("In thread \n");
HWINSTA orgWS = GetProcessWindowStation();
printf("Done GetProcessWindowStation \n");
if (orgWS) {
printf("In GetProcessWindowStation \n");
HWINSTA itrWS = OpenWindowStation(TEXT("WinSta0"), true, GENERIC_ALL);
if (itrWS) {
printf("In OpenWindowStation \n");
if (SetProcessWindowStation(itrWS)) {
printf("In SetProcessWindowStation \n");
HDESK iD = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, true, GENERIC_ALL);
if (iD) {
if (!SetThreadDesktop(iD)) {
printf("SetThreadDesktop failed: %lu \n", GetLastError());
} else {
printf("setting hoook");
// SetWinEventHook sets the hook for the mentioned event.
// In current case EVENT_SYSTEM_FOREGROUND. When ever EVENT_SYSTEM_FOREGROUND is triggerd HandleWinEvent will be called
g_hook = SetWinEventHook(
EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, // Range of events (4 to 5).
NULL, // Handle to DLL.
HandleWinEvent, // The callback.
0, 0, // Process and thread IDs of interest (0 = all)
WINEVENT_OUTOFCONTEXT);
MSG msg;
//GetMessage(&msg, NULL, 0, 0);
while (WaitMessage() && set) {
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
}
}
} else {
printf("OpenInputDesktop failed: %lu \n", GetLastError());
}
SetProcessWindowStation(orgWS);
} else {
printf("SetProcessWindowStation failed: %lu \n", GetLastError());
}
CloseWindowStation(itrWS);
} else {
printf("OpenWindowStation failed: %lu \n", GetLastError());
}
} else {
printf("GetProcessWindowStation failed: %lu \n", GetLastError());
}
}
int main() {
bool retVal = false;
printf("In Main \n");
CoInitialize(NULL);
std::thread t(ForegroundCheck);
printf("In thread started \n");
std::cin.get();
// Deinit
UnhookWinEvent(g_hook);
set = false;
t.join();
CoUninitialize();
return 0;
}
Thanks
Upvotes: 1
Views: 183
Reputation: 319
Each logged on user has separate desktop. So if you want to track foreground activities, your process need to run as Users group. You can create another process as user with CreateProcessAsUser
.
Upvotes: 0