2

I'm writing a small c# program, I don't want the final user to take screenshots while using my program, is it possible? Or even if he takes one, how can I know it?

Thanks in advance and sorry if this is a poor-content question due to my lack of experience in c# coding.

Praveen Prasad
  • 31,561
  • 18
  • 73
  • 106
Giorgio
  • 1,603
  • 5
  • 29
  • 52

3 Answers3

2

You can create a system-wide keyboard hook using the low-level keyboard filter and cancel any printscreen keyboard combination. But if someone has also installed a helper application (like Gadwin or something) it'll become a lot more difficult because you won't know beforehand what keyboard shortcut you should catch (most tools allow to specify your own hooks).

On a side note: it's generally not preferred to change the system behavior. Screenshots are system behavior and serve a distinguished purpose for trouble shooting. If you prevent this, users will not be able to show you a screenshot of something wrong. But if you must do it, you can do it.


EDIT: on a deeper level, you can install an API hook. All screenshot applications use API calls to get the content of a (part of) the screen. But API hooks are hard to get right. A more trivial way is probably by writing a user-level driver. While you can prevent all this, it is really worth all the trouble?

Abel
  • 56,041
  • 24
  • 146
  • 247
  • 1
    Doesn't work for virtual machines, physical cameras, and a host of other options. This is a waste of time. – Cody Gray - on strike Jan 14 '12 at 12:08
  • Thanks for your answer, I'll check out these options soon! If the user is taking a screenshoot from a Virtual Machine, will this method prevent him to take a SS? Or can I detect him? – Giorgio Jan 14 '12 at 12:09
  • Even usermode API hooks can be bypassed by simply calling into the kernel directly. – CodesInChaos Jan 14 '12 at 12:09
  • That's why I wrote "is it really worth all the trouble?". But I don't write the specs for the application. There are screens on the market that make it impossible to take pictures of. So I guess there's a market for this kind of stuff (but really, I don't know why). If all else fails, hackers will always find a way around it, like reading the memory of the graphical card. – Abel Jan 14 '12 at 12:10
  • If you control the system so much that you can prevent photos, you can easily prevent virtual machines and unauthorized programs too. – CodesInChaos Jan 14 '12 at 12:12
  • @CodeInChaos: agreed. Anything you prevent can be circumvented. My door has a lock, but you can still kick in the door. Does that mean I shouldn't use a lock? Generally, this kind of specs exist to make it hard for the _trivial_ user. – Abel Jan 14 '12 at 12:12
  • 3
    Applications that make things like this hard for the owner of a system are called malware. – CodesInChaos Jan 14 '12 at 12:13
  • @CodyGray: check here: http://stackoverflow.com/questions/3291167/how-to-make-screen-screenshot-with-win32-in-c. But it won't be enough to "just hook". It will require some work to find out what the API is called and used for. Like I said in my post: this is a hard task to get right. – Abel Jan 14 '12 at 12:14
  • @CodeInChaos: that's why I wrote _"it's generally not preferred to change the system behavior"_. But think of kiosk and security applications. There are always situations where this is not malware. – Abel Jan 14 '12 at 12:15
  • I'm quite aware of *how* to take a screenshot. `GetDC(NULL)` is an easier way than that post shows. The question was how in the world do you hook `GetDC` or `CreateDC` or whatever other function? Not to mention if they used Direct3D. Yes, it's hard to get right primarily because it's impossible. I think you're giving people false hope. – Cody Gray - on strike Jan 14 '12 at 12:16
  • @CodyGray hooking `GetDC` or whatever isn't hard. If you have admin privs you can inject a dll(preferably unmanaged) into every process and hook that function. I've done this with a single target process, but generalizing to every process isn't hard. The main issue is that you might cause strange side effects because you changed the behavior of an API a program might rely on, for different purposes. – CodesInChaos Jan 14 '12 at 12:18
  • I linked to an article on API hooking. There are plenty articles around on the web. It's been a few years that I ever needed it myself. You can check some API hook monitor applications, pretty interesting stuff! – Abel Jan 14 '12 at 12:19
  • @Code: Yes, that was sort of my point. How does an application draw to the screen if you've prevented it from calling `GetDC`? I suppose there are alternatives, but the code probably wasn't written with the need to use those alternatives in mind. This all just seems like a giant waste of energy. – Cody Gray - on strike Jan 14 '12 at 12:36
2

You might want a keyboard hook. But it'll tell you if the user pressed the "print screen" key, not if someone programmatically take a screenshot using some GDI function.

I doubt it's possible to prevent all the ways of taking a screenshot.

ken2k
  • 48,145
  • 10
  • 116
  • 176
  • 1
    Windows 7 Snipping Tool will be hard to avoid. – sshow Jan 14 '12 at 11:55
  • @sshow: not really. That's an executable and it's next to trivial to prevent an executable to run. Furthermore, if you want a kiosk-installation of Windows, Microsoft caters for this by preventing most system applications, including Snipping Tool, to run. – Abel Jan 14 '12 at 12:01
1

General answer: No. It's not possible to detect this - especially from C#. There are dozens of ways to take screenshot and even applications written in C++/WinAPI can only detect some of them, but not all.

Also consider - what if user is running your app in virtual machine? He'll be able to take screenshots at host machine and you can do absolutely nothing to detect (not even prevent) this.

Sergey Kudriavtsev
  • 10,328
  • 4
  • 43
  • 68
  • 1
    It's quite easy to detect the majority of cases. And anything you can write in C++ you can also write in C#, with the exception of unmanaged applications (like drivers). WinAPI can be used from C# with P/Invoke: http://pinvoke.net. +1 for the virtual machine ;) – Abel Jan 14 '12 at 12:05
  • P/Invoke is something I do try to avoid in my programs :) Anyway, how would you detect a simple GDI software doing `GetDC(0)` + image retrieving from that context? I could write one in 30 mins if I ever need something alike... – Sergey Kudriavtsev Jan 14 '12 at 12:15
  • Use an API Hook. Result is probably that your program crashes. I don't suggest writing such software, but the OP has probably asked this for a reason. – Abel Jan 14 '12 at 12:17