Sto provando a scrivere del codice per rilevare un wallhack per un gioco. Fondamentalmente, esistono alcuni hack che creano una finestra trasparente aera di Windows, e disegnano l'hack su questa finestra esterna, quindi non possono essere rilevati prendendo uno screenshot del gioco stesso.Rileva gioco hack tramite analisi screenshot C#
Il mio approccio al momento è quello di - 1. fare uno screenshot della finestra di gioco. 2. prendere uno screenshot del desktop di Windows per le stesse coordinate. 3. eseguire l'analisi delle immagini per confrontare lo screenshot 1 con lo screenshot 2 per vedere se c'è una differenza.
Il mio problema è che lo screenshot 1 e lo screenshot 2 non vengono eseguiti contemporaneamente, quindi è possibile disegnare nuovi frame di gioco tra i due screenshot, causando falsi positivi quando le immagini vengono confrontate.
Desidero sapere se esiste un modo per coordinare gli screenshot in modo che si verifichino esattamente nello stesso momento? o in qualche modo fermare lo schermo disegnando nuovi fotogrammi fino a quando i miei screenshot sono finiti?
Questo è il codice che uso per scattare screenshot. Nota, ho persino provato a prendere i 2 screenshot in parallelo accodando due elementi di lavoro. Tuttavia, anche questo non comporta che gli screenshot avvengano esattamente nello stesso momento. Quindi mi chiedo se c'è un modo per interrompere ulteriori aggiornamenti dello schermo dalla scheda grafica fino alla fine delle mie schermate? O in qualsiasi altro modo posso farlo?
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;
}
Non credo che quello che stai facendo sia etico. Il tuo rilevatore "wallhack" sta raccogliendo informazioni che un utente potrebbe non voler divulgare. Perché un utente acconsente a prendere catture di schermo del proprio desktop mentre gioca? Il comportamento che stai cercando di implementare rientra nella classificazione del cavallo di Troia. Questo è ovviamente se non stai mentendo sullo scopo del tuo programma. –
Questo potrebbe essere un uso appropriato di ['Parallel.Foreach'] (http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx). 'ThreadPool' non garantisce il parallelismo. – Romoku
Supponi di avere il tuo gioco aperto in una finestra, ma poi apri un browser web su quella finestra (google qualcosa | controlla il mio conto bancario | naviga su Facebook | fai qualcosa di illegale) e fai uno screenshot di quello.Registrerai un falso positivo - che sto imbrogliando quando non lo sono, e se decidi che dovresti caricare lo screenshot "falso" per prova/verifica, potresti catturare accidentalmente i miei dettagli privati. –