• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 677
  • Last Modified:

capturing a screen from a non-interactive service

hello all.

I'm trying to write an exe that will capture a screen on windows and save it into a bitmap file.
I'm using GDI, and I've managed to do it now using the GetDC function. in a nutshell, it is something like that:
HDC desktopDC   = GetDC(NULL);
HDC memDC       = CreateCompatibleDC (desktopDC);
HBITMAP ScreenBitmap = CreateCompatibleBitmap(desktopDC,DesktopWidth,DesktopHeight);

of course, this kind of code is good only if I run my program in interactive mode, and it capture the desktop that I can see. however, I need to run this program as a service, which means it will be in the context of the LOCAL SYSTEM user, and won't have a desktop. what I want it to do, is to find the desktop of a specified user session (which I know that it is connected), and capture it.

is that possible? (programmtically, not from the security point of view)
does anyone know how it can be done? how can I get a DC of a different session that myself?

  • 2
  • 2
1 Solution
Cyber-EEAuthor Commented:
thanks for the answer, ChristianWimmer.

are you sure this approach will also fail in case the other session is connected using RDP?
I read a bit about using WTSRegisterSessionNotification & WTSGetActiveConsoleSessionId and such. If the user is connected to the terminal service, isn't it somehow possible to get its session from a service, and then use things like SetProcessWindowStation & SetThreadDesktop in order to get the desktop of the interactive user?

I didn't understand these function pefectly yet, but does the security problems you mentioned in your answer still problematic with this approach?
There is no difference with RDP. You can't get a handle with OpenDesktop for a desktop in another session because there is an if case for this situation (If (Process.Session != Desktop.Session) return 5)
The only way is a second process that is spawned into the target session.

You can run a new system process in any session you like. However you should not use this system process to show any windows to the user. A shatter attack could use your GUI to infiltrate the system.
These steps are necessary to create a system process in any session
* OpenProcessToken in a service
* DuplicateToken
* SetTokenInformation with TokenSessionId to set the target session ID for the new process. Needs TCB privilege!
* CreateProcessAsUser with the duplicated token. Set also parameter bInheritHandles to FALSE !
Cyber-EEAuthor Commented:
Thanks for the help
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now