2013-08-13 17 views
5

Próbuję napisać kod, aby wykryć wallhacka do gry. Zasadniczo istnieje kilka hacków, które tworzą przezroczyste okno okna i przeciągają hak do tego zewnętrznego okna, więc nie można go wykryć, robiąc zrzut ekranu samej gry.Wykrywanie włamania do gry za pomocą analizy zrzutów ekranu C#

Moje podejście to: - 1. Wykonaj zrzut ekranu okna gry. 2. Wykonaj zrzut ekranu pulpitu Windows dla tych samych współrzędnych. 3. Wykonaj analizę obrazu, aby porównać zrzut ekranu 1 do zrzutu ekranu 2, aby zobaczyć, czy istnieje różnica.

Moim problemem jest to, że zrzut ekranu 1 i zrzut ekranu 2 nie są wykonywane równocześnie, więc można utworzyć nowe klatki gry między dwoma zrzutami ekranu, powodując fałszywe alarmy podczas porównywania obrazów.

Chciałbym wiedzieć, czy istnieje sposób na koordynowanie zrzutów ekranu, aby pojawiały się dokładnie w tym samym czasie? lub w jakiś sposób przerwać rysowanie nowych ramek ekranu, dopóki moje zrzuty ekranu nie zostaną ukończone?

To jest kod, którego używam do robienia zrzutów ekranu. Uwaga, próbowałem nawet wykonać 2 zrzuty ekranu równolegle, ustawiając w kolejce dwa elementy pracy. Jednak nawet to nie powoduje zrzutu ekranu w dokładnie tym samym czasie. Zastanawiam się, czy istnieje jakiś sposób, aby zatrzymać dalsze aktualizacje ekranu z karty graficznej, dopóki moje zrzuty ekranu się nie zakończą? Lub w inny sposób mogę to zrobić?

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

Nie wierzę, że to, co robisz, jest etyczne. Twój detektor "wallhack" zbiera informacje, których użytkownik nie chce ujawnić. Dlaczego użytkownik wyrazi zgodę na robienie zrzutów ekranu z ich pulpitu podczas gry? Zachowanie, które próbujesz wdrożyć, jest objęte klasyfikacją konia trojańskiego. To oczywiście, jeśli nie kłamiesz o celu twojego programu.

+0

Może to być odpowiednie użycie ['Parallel.Foreach'] (http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx). "ThreadPool" nie gwarantuje równoległości. – Romoku

+2

Załóżmy, że twoja gra jest otwarta w oknie, ale potem otwórz przeglądarkę internetową nad tym oknem na (google coś | sprawdź moje konto bankowe | przeglądaj Facebook | zrób coś nielegalnego) i zrób zrzut ekranu z tego.Nagrałeś fałszywe-pozytywne - że oszukuję, kiedy nie jestem, i jeśli zdecydujesz, że powinieneś przesłać "sfałszowany" zrzut ekranu do sprawdzenia/weryfikacji, możesz uchwycić moje prywatne dane przypadkowo. –

Odpowiedz

1

nie będą mogli mieć zarówno screeny jednocześnie, chyba że zasób do niektórych accelarators graficznych, co oznacza, że ​​nie będzie działać na każdym komputerze ...

O zatrzymaniu rendering, ponieważ to gra, myślę, że to nie jest dobry pomysł ... chcesz, żeby gra działała sprawnie.

Zamiast tego chciałbym zasugerować przechowywanie ostatnio renderowanych obrazów z Twojej gry w pamięci, a kiedy wykonasz zrzut ekranu, porównaj to z nimi. Jeśli możesz dodać jakąś wizualną wskazówkę, aby zdecydować, która z ostatnich ramek będzie porównywana, wtedy będzie działać znacznie lepiej, ponieważ w przeciwnym razie będziesz musiał porównać zrzut ekranu z wszystkimi z nich i na pewno zje trochę czasu CPU/GPU.

Czy używasz GDI do renderowania? jeśli tak, to chcesz przechowywać ramki swojej gry w DIB (niezależne od urządzenia bitmapy), aby móc je porównać.

Co do wskazówki, aby zdecydować, który obraz użyć, chciałbym przejść do pewnego czasu reprezentacji na ekranie, może jeden piksel, który zmienia kolor. Jeśli tak, odczytaj kolor tego piksela, użyj go, aby znaleźć odpowiednią ramkę, a następnie przetestuj cały obraz.

+0

Jeśli współpracujesz z grą, nie trzeba zapisywać starych klatek. Silna suma kontrolna starych ramek lub danych ukrytych w bitach o niskiej wartości kolorów przy użyciu steganografii byłaby całkowicie wystarczająca do określenia, czy przechwytywanie obrazu na ekranie zostało zmodyfikowane. –

Powiązane problemy