2013-08-13 23 views
5

Ich versuche, etwas Code zu schreiben, um ein Wallhack für ein Spiel zu erkennen. Grundsätzlich gibt es einige Hacks, die ein transparentes Windows-Aero-Fenster erzeugen, und sie zeichnen den Hack auf dieses externe Fenster, so dass es nicht durch einen Screenshot des Spiels selbst entdeckt werden kann.Detect Spiel Hack durch Screenshot Analyse C#

Mein Ansatz ist im Moment - 1. Machen Sie einen Screenshot des Spielfensters. 2. Machen Sie einen Screenshot des Windows-Desktops für die gleichen Koordinaten. 3. Führen Sie eine Bildanalyse durch, um Screenshot 1 mit Screenshot 2 zu vergleichen, um festzustellen, ob ein Unterschied besteht.

Mein Problem ist, dass Screenshot 1 und Screenshot 2 nicht gleichzeitig ausgeführt werden, so dass neue Spiel-Frames zwischen den beiden Screenshots gezeichnet werden können, was beim Vergleich der Bilder zu Fehlalarmen führt.

Ich möchte wissen, ob es eine Möglichkeit gibt, die Screenshots zu koordinieren, so dass sie genau zur gleichen Zeit auftreten? oder höre irgendwie auf dem Bildschirm auf, neue Bilder zu zeichnen, bis meine Screenshots fertig sind?

Dies ist der Code, den ich für die Erstellung von Screenshots verwende. Hinweis: Ich habe sogar versucht, die zwei Screenshots parallel zu erstellen, indem ich zwei Arbeitsaufgaben in die Warteschlange bringe. Aber auch dies führt nicht dazu, dass die Screenshots genau zur selben Zeit ablaufen. Also ich frage mich, ob es eine Möglichkeit gibt, weitere Updates auf dem Bildschirm von der Grafikkarte zu stoppen, bis meine Screenshots fertig sind? Oder kann ich das anders machen?

public void DoBitBlt(IntPtr dest, int width, int height, IntPtr src) 
    { 
     GDI32.BitBlt(dest, 0, 0, width, height, src, 0, 0, GDI32.SRCCOPY); 
    } 

    public struct Windows 
    { 
     public Bitmap window; 
     public Bitmap desktop; 
    } 
    public Windows CaptureWindows(IntPtr window, IntPtr desktop, User32.RECT coords) 
    { 
     Windows rslt = new Windows(); 
     // get te hDC of the target window 
     IntPtr hdcSrcWindow = User32.GetWindowDC(window); 
     IntPtr hdcSrcDesktop = User32.GetWindowDC(desktop); 

     // get the size 
     int width = coords.right - coords.left; 
     int height = coords.bottom - coords.top; 

     // create a device context we can copy to 
     IntPtr hdcDestWindow = GDI32.CreateCompatibleDC(hdcSrcWindow); 
     IntPtr hdcDestDesktop = GDI32.CreateCompatibleDC(hdcSrcDesktop); 
     // create a bitmap we can copy it to, 
     // using GetDeviceCaps to get the width/height 
     IntPtr hBitmapWindow = GDI32.CreateCompatibleBitmap(hdcSrcWindow, width, height); 
     IntPtr hBitmapDesktop = GDI32.CreateCompatibleBitmap(hdcSrcDesktop, width, height); 
     // select the bitmap object 
     IntPtr hOldWindow = GDI32.SelectObject(hdcDestWindow, hBitmapWindow); 
     IntPtr hOldDesktop = GDI32.SelectObject(hdcDestDesktop, hBitmapDesktop); 
     // bitblt over 
     var handle1 = new ManualResetEvent(false); 
     var handle2 = new ManualResetEvent(false); 
     Action actionWindow =() => { try { DoBitBlt(hdcDestWindow, width, height, hdcSrcWindow); } finally { handle1.Set(); } }; 
     Action actionDesktop =() => { try { DoBitBlt(hdcDestDesktop, width, height, hdcSrcDesktop); } finally { handle2.Set(); } }; 
     ThreadPool.QueueUserWorkItem(x => actionWindow()); 
     ThreadPool.QueueUserWorkItem(x => actionDesktop()); 
     WaitHandle.WaitAll(new WaitHandle[] { handle1, handle2 }); 

     rslt.window = Bitmap.FromHbitmap(hBitmapWindow); 
     rslt.desktop = Bitmap.FromHbitmap(hBitmapDesktop); 

     // restore selection 
     GDI32.SelectObject(hdcDestWindow, hOldWindow); 
     GDI32.SelectObject(hdcDestDesktop, hOldDesktop); 
     // clean up 
     GDI32.DeleteDC(hdcDestWindow); 
     GDI32.DeleteDC(hdcDestDesktop); 
     User32.ReleaseDC(window, hdcSrcWindow); 
     User32.ReleaseDC(desktop, hdcSrcDesktop); 
     // free up the Bitmap object 
     GDI32.DeleteObject(hBitmapWindow); 
     GDI32.DeleteObject(hBitmapDesktop); 
     return rslt; 
    } 
+3

Ich glaube nicht, was Sie tun, ist ethisch. Ihr "Wallhack" -Detektor sammelt Informationen, die ein Benutzer möglicherweise nicht preisgeben möchte. Warum würde ein Nutzer zustimmen, dass er Screenshots von seinem Desktop nimmt, während er ein Spiel spielt? Das Verhalten, das Sie implementieren möchten, wird als trojanisches Pferd klassifiziert. Das ist natürlich, wenn Sie nicht über den Zweck Ihres Programms lügen.

+0

Dies könnte eine angemessene Verwendung von ['Parallel.Foreach'] sein (http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx). Der 'ThreadPool' garantiert keine Parallelität. – Romoku

+2

Angenommen, ich habe dein Spiel in einem Fenster geöffnet, öffne dann aber einen Webbrowser über dieses Fenster (etwas überprüfen | Mein Bankkonto durchsuchen | Facebook durchsuchen | etwas illegal machen) und du machst einen Screenshot davon.Du nimmst ein falsches Positiv auf - dass ich betrüge, wenn ich es nicht bin, und wenn du beschließt, dass du den "gefälschten" Screenshot zum Beweis/Verifizieren hochladen solltest, könntest du meine privaten Daten versehentlich erfassen. –

Antwort

1

Sie sind nicht beide Screenshots in der Lage sein gleichzeitig zu haben, es sei denn, Sie einige Grafik accelarators Ressource, dass bedeutet, dass nicht in jedem Computer arbeiten ...

Über Rendering zu stoppen, wie es ist ein Spiel, ich denke, das ist keine so gute Idee ... Sie wollen, dass Ihr Spiel reibungslos läuft.

Stattdessen möchte ich vorschlagen, kürzlich gerenderte Bilder Ihres Spiels im Speicher zu speichern, und wenn Sie den Screenshot nehmen, vergleichen Sie sie mit ihnen. Wenn Sie einen visuellen Hinweis hinzufügen können, um zu entscheiden, mit welchen der letzten Bilder Sie dann vergleichen, wird es viel besser funktionieren, denn sonst müssen Sie den Screenshot mit allen vergleichen und das wird sicherlich einige CPU/GPU-Zeit kosten.

Verwenden Sie GDI zum Rendern? Wenn dies der Fall ist, möchten Sie die Frames Ihres Spiels in DIBs (Device Independent Bitmaps) speichern, um sie vergleichen zu können.

Wie für den Schlüssel zu entscheiden, welches Bild zu verwenden, würde ich für eine Art Zeitdarstellung auf dem Bildschirm gehen, vielleicht ein einzelnes Pixel, das die Farbe ändert. Wenn ja, lesen Sie die Farbe dieses Pixels, verwenden Sie es, um den richtigen Frame zu finden, und verfahren Sie, um das ganze Bild zu vergleichen.

+0

Wenn Sie mit dem Spiel zusammenarbeiten, müssen Sie keine alten Frames speichern. Eine starke Prüfsumme von alten Rahmen oder Daten, die in den niedrigen Farbbits unter Verwendung von Steganographie verborgen sind, würde vollkommen ausreichen, um zu bestimmen, ob die Bildaufnahme auf dem Bildschirm modifiziert wurde. –