-4

I'm doing a bot to read images and transform it in text using Tesseract, but I have a problem with the target application named Tibia (Its a game in window mode screen), because it have a anti-screenshot protection. If I try, I got a black screen picture.

A already have try CopyFromScreen(), user32.dll, and gdi.dll functions but without success.

I tried these ways:

Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(printscreen as Image);
graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size);

And:

public static Bitmap GetDesktopImage()
{
    WIN32_API.SIZE size;

    IntPtr hDC = WIN32_API.GetDC(WIN32_API.GetDesktopWindow());
    IntPtr hMemDC = WIN32_API.CreateCompatibleDC(hDC);

    size.cx = WIN32_API.GetSystemMetrics(WIN32_API.SM_CXSCREEN);
    size.cy = WIN32_API.GetSystemMetrics(WIN32_API.SM_CYSCREEN);

    m_HBitmap = WIN32_API.CreateCompatibleBitmap(hDC, size.cx, size.cy);

    if (m_HBitmap != IntPtr.Zero)
    {
        IntPtr hOld = (IntPtr)WIN32_API.SelectObject(hMemDC, m_HBitmap);
        WIN32_API.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, WIN32_API.SRCCOPY);
        WIN32_API.SelectObject(hMemDC, hOld);
        WIN32_API.DeleteDC(hMemDC);
        WIN32_API.ReleaseDC(WIN32_API.GetDesktopWindow(), hDC);
        return System.Drawing.Image.FromHbitmap(m_HBitmap);
    }
    return null;
}

public class WIN32_API
{
    public struct SIZE
    {
        public int cx;
        public int cy;
    }
    public const int SRCCOPY = 13369376;
    public const int SM_CXSCREEN = 0;
    public const int SM_CYSCREEN = 1;

    [DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
    public static extern IntPtr DeleteDC(IntPtr hDc);

    [DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
    public static extern IntPtr DeleteObject(IntPtr hDc);

    [DllImport("gdi32.dll", EntryPoint = "BitBlt")]
    public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, int RasterOp);

    [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleBitmap")]
    public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);

    [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC")]
    public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

    [DllImport("gdi32.dll", EntryPoint = "SelectObject")]
    public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);

    [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
    public static extern IntPtr GetDesktopWindow();

    [DllImport("user32.dll", EntryPoint = "GetDC")]
    public static extern IntPtr GetDC(IntPtr ptr);

    [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
    public static extern int GetSystemMetrics(int abc);

    [DllImport("user32.dll", EntryPoint = "GetWindowDC")]
    public static extern IntPtr GetWindowDC(Int32 ptr);

    [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
    public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
}

Can anyone help me?

Have anyone api to capture print direct from GPU?

Victor Laio
  • 152
  • 12
  • what is anti-screenshot protection? for the whole screen or just a window? what comes back black? – Charles Dec 31 '19 at 12:42
  • Idk what is his anti-screenshot protection. If i try, i got the black screen just in the application window. – Victor Laio Dec 31 '19 at 12:44
  • did you try to run as admin? what application are you trying to capture? – Charles Dec 31 '19 at 12:46
  • I already try to run as admin, its really a screen shot protection due to prevent botting. Its one game named Tibia. That run in a window – Victor Laio Dec 31 '19 at 12:47
  • [Desktop Duplication API](https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/desktop-dup-api) – Jimi Dec 31 '19 at 19:37
  • @Jimi Can you give me a exemple using c#? – Victor Laio Dec 31 '19 at 20:41
  • 13
    stackoverflow should not help on theft of copyrighted material. – SQL Police Jan 01 '20 at 19:24
  • @SQLPolice Edited, but why i got 2 down votes? – Victor Laio Jan 01 '20 at 20:19
  • https://blogs.msdn.microsoft.com/dsui_team/2013/03/25/ways-to-capture-the-screen/ – Ken White Jan 02 '20 at 02:08
  • @KenWhite C# please :( – Victor Laio Jan 02 '20 at 03:19
  • 1
    C# has nothing to do with it. Those are various ways that you can capture a screen in Windows. I'm not doing your research for you. The WinAPI is written with C in mind, and you'll find the majority of documentation for it uses C as the language for examples and function declarations. The link I provided discusses alternative options for doing what you ask. Make an effort to investigate them. – Ken White Jan 02 '20 at 03:21
  • But i can use C# with a library .dll writen in C or C++ ? – Victor Laio Jan 02 '20 at 11:00
  • I don't remember the exact details, but it's possible the game isn't using some kind of block and it is related to display overlays. Usually a graphics driver will not render those in a screen shot and there is nothing at all you can do about it. – John Lord Jan 06 '20 at 05:59
  • window mode screen? did you try snipping tools? – Raynoceros Jan 07 '20 at 09:17
  • Snipping tools do not resolve for me – Victor Laio Jan 07 '20 at 11:05
  • By design, it's difficult from Windows itself to go around protections that Windows itself offers. Check this (also the chat discussion): https://stackoverflow.com/questions/56302217/prevent-desktop-sharing-of-a-particular-c-sharp-winforms-or-detect-desktop-shari The app developer may have simply used SetWindowDisplayAffinity. It also prevents the Desktop Duplication API to work I think. – Simon Mourier Jan 07 '20 at 19:28

2 Answers2

2

In order to get the screenshot you need to go a layer lower than device contexts and Gdi. The game is not doing the rendering on the device context of the hWnd and instead talking to the graphic card driver. So when you call CreateCompatibleBitmap there is essentially nothing rendered there. I am not sure if there are any public APIs to capture what is being rendered directly. Some games do this because they would like to have faster rendering and would prefer to skip GDI or GDI+.

Reza Jooyandeh
  • 761
  • 5
  • 19
2

DISCLAIMER: I am not responsible in any way for anything that anyone does with any code shared or made accessible from this answer.

I agree that the concept of screen capturing video games that feature any type of anti-cheat software is sketchy. The other side of that coin is that there could be any number of valid personal reasons to have a separate utility that can capture screenshots or video and process the content (i.e. custom notifications of in game activity, making the game more accessible to disabled persons by parsing messages and playing them through a synthesizer API, etc...).

All that being said, I downloaded and installed Tibia, copied the FullScreenshot code snippet from this article into a simple WinForms app project, and was able to save a screenshot of the game (shown below).

The WinForms app can be downloaded from here to test before playing with the code yourself.

Screenshot of Tibia from custom app: this screenshot

Troy
  • 557
  • 3
  • 15
  • I agree with your all adversings @TroyPalacino. This way works only for 15 min. After that the window became to black pixels again. – Victor Laio Jan 09 '20 at 11:36
  • Can you provide some more details? Do you mean after the game has been open for 15 minutes or taking screenshots for 15 minutes? How frequently does your app capture the screenshots? – Troy Jan 09 '20 at 12:29
  • 1
    After the game has been open for 15 minutes. I take screenshots every 400ms – Victor Laio Jan 09 '20 at 13:31
  • does the entire screen capture go blank or just the game window? also, during those 15 minutes are you actively interacting with the with the game window or just allowing the game window to be idle? – Troy Jan 09 '20 at 13:59
  • 1
    Just the game window. allowing the game window to be idle – Victor Laio Jan 09 '20 at 14:23
  • I suggest trying to interact with the window in some insignificant way programmatically ever couple of minutes. Perhaps move the mouse over the window and then off again or click on the title bar or something – Troy Jan 09 '20 at 14:34
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/205683/discussion-between-troy-palacino-and-victor-laio). – Troy Jan 09 '20 at 15:11