views:

1143

answers:

11

I'm writing a Windows application. How can I tell when a screenshot is being taken of it? I read about how to detect the hotkey being pressed, but I'm more worried about the case where every 100 ms or so another program is taking screenshots of it. Namely, I'm trying to notice when someone creates another program (say a python one using ImageGrab, as mentioned in another post) which constantly takes screenshots of my app and uses them to read info off of it.

I don't care much about preventing the screenshots from being taken - I can just ban the user once this behavior is noticed.

Is this possible? Is there a windows message sent when any app takes a screenshot, like with WM_HOTKEY? Or does windows just use the latest info from the latest paint events, and return that to the other program directly, without my app being able to notice at all?

+7  A: 

What if I use a video camera? What if I capture the video coming between the computer and the monitor?

I'll be surprised to learn there's any practical way to do this.

John Saunders
still working on that bionic arm prototype which will disguise itself as a licence dongle! It'll just strangle the user if they attempt to use video cam corder or camera.
dr. evil
+1 for Dr. Evil for really making me laugh
Tokk
+1  A: 

The way I usually take screenshots (from C#) is by calling BitBlt, which is the basis of a lot of screen painting. Not sure how you'd intercept calls to it in any meaningful way, since probably every program on the system uses it at a low level.

Chris Doggett
I've seen a proof of concept code in a 1st person shooter cheat program, which froze the screenshot thread until the cheat HUD was disabled. I think it hooked BitBlt or something similar.
abababa22
+1  A: 

It's pretty hard to stop it completely... A user who is determined enough could just take a photo of the screen with a digital camera.

Mun
+25  A: 

Whatever you do, people will find a way around it. Suppose such a method existed, where you could reliably detect another program taking a screenshot of your application. To get around that, I could install VirtualBox, run your application inside the VM, and then have a program take screenshots of VirtualBox (which then contains your application). Your application would have absolutely no way to know it was having its picture taken.

Greg Hewgill
Unless VirtualBox simulates taking screenshots the same way windows does. From your answer, you're saying that it doesn't?
Claudiu
I'm not talking about VirtualBox taking the screenshot; I'm talking about another program taking a screenshot *of* VirtualBox. After all, VirtualBox is basically just a window with some pixels in it.
Greg Hewgill
Here's what I meant. In my head, a certain function gets called when "takeScreenshot()" is called. This function would recursively call the "takeScreenshot()" of all open windows (so the Desktop would call it on all the programs w/ open windows). VirtualBox could define its handler for "takeScreenshot()" to simulate calling this "takeScreenshot()" on all the apps it is simulating. I'm not sure if this is how it works at all, which is why I'm asking here.
Claudiu
Yeah, that's not how it works at all. Taking a screenshot involves opening a DC (device context) to the window in question, and reading the bits on the screen with BitBlt. Screenshots don't involve WM_PAINT or anything similar. A Win32 application will be unaware that the pixel copying process is happening. You might be able to prevent the Print Screen keystroke from doing its job, but you won't be able to detect another application simply reading bits off the screen.
Greg Hewgill
@Claudiu: Actually, if you have a running (but not focused) Virtualbox window, and you press PrintScreen, nothing will be passed to the virtual computer. No Printscreen key, no message, *nothing*. Tested and verified.
Piskvor
@Greg: Is it possible to detect whether some application is reading bits off the screen?
Zolomon
+18  A: 

Let me guess, you work for a startup company founded by the people who invented using JavaScript to disable right-clicking images on web pages?

Whatever
+1  A: 

I assume you really can't because one can always run your program in a window with virtual machine, then using a capture program on the outside platform, and knowing if this is happaning is mighty difficult. I suggest thinking more in ways of special rendering pace or interlacing, special contrasts, etc...

You can also run your outputs to the screen as if it was a movie, encode it with a low rate and resolution encoder, so that a still capture every 100ms will be in such a low quality that it would be worthless. (have you ever freezed a low quality movie?)

however you really should consider using other ways to protect your info.

Liran Orevi
+7  A: 

This is never going to work. Not only that, but attempts to provide this level of security are going to inconvenience 99% of your legitimate users.

You perhaps are best to approach the problem from the angle of trying to identify unwanted uses/copies of your information and approach the people/companies using that information.

Copyright law is appropriate for this approach, but I understand that there are some intances where this approach is not available.

Nat
+2  A: 

First, comments about using a virtual machine are completely pointless -- it is much easier to detect windows running under a virtualizer than to detect a screenshot being taken.

A good way to make screenshots difficult would be to rewrite your program to run in full screen mode under some ancestral dos extender.

A good way to ban 95% of users who ever attempted to take a screenshot is to display a huge flashing banner on startup ("screenshots prohibited! you be banned!"), and detect user pressing PrtScrn during the following 15 seconds.

anonymous
Hah at the last paragraph =).
Claudiu
I just wonder why this got so few upvotes...
BlaXpirit
+2  A: 

Another reason why I think it will be impossible to achieve this:

A long time ago, I failed to make a screen capture of the content of Windows Media Player, because (I assumed) WMP streamed that content to the videocard right away. (Fun detail: after pasting the screen capture, the video would continue playing in MS Paint, but saving the image would eventually yield a black square). Anyway, using VNC made it very easy to get the screen capture after all.

Arjan
The same thing happened to me, too. I always wondered why.
Claudiu
I don't think Media Player does this to prevent screenshots--that is a side effect. Any overlay like that cannot be captured normally. However, if you turn off hardware acceleration, it won't use overlay and you can take a screen shot of it.
Jordan Miner
Indeed, I also think it is a side effect. (Though Microsoft might like to stop screen recording for DRM protected content.)
Arjan
+3  A: 

You can (unreliably) do this by using SetWindowsHookEx.

Here is a complete VB.NET example.

However, there are many ways around this. A hook installed after yours will "override" your hook. Users can take pictures of their screen in many ways, as described in this thread. I'd try to consider other options for protection than this.

Reed Copsey
A: 

there is one way that i think might stop it. learn about the technology that blurs a graphical display when it is duplicated for example.

screenshot, photographed by digital camera screenshot from virtual os.

play with it , who knows you might invent something that will make u millions.

SarmenHB
"blurs a graphical display when it is duplicated" - that is sci-fi, not actual technology. The bits that become the display image are duplicated and modified a lot before they make it from the program through the OS to the hardware. The real issue here is deciphering intent, which is hard enough with humans, let alone computer instructions.
Piskvor