2013-08-13 39 views
5

Bir oyun için bir wallhack tespit etmek için bir kod yazmaya çalışıyorum. Temel olarak, bir pencere aero şeffaf pencere oluşturan bazı korsanlar var, ve bu harici pencereye hack çekiyorlar, bu yüzden oyunun ekran görüntüsünü alarak tespit edilemez.Tespit oyunu ekran görüntüsü analizi ile kesmek C#

Şu anki yaklaşımım - 1. Oyun penceresinin ekran resmini alma. 2. Aynı koordinatlar için windows masaüstünün ekran görüntüsünü alın. 3. Bir fark olup olmadığını görmek için ekran görüntüsü 1 ekran görüntüsü 2 ile karşılaştırmak için resim analizi yapın.

Sorunum, ekran görüntüsü 1 ve ekran görüntüsü 2'nin aynı anda gerçekleştirilmemesidir, böylece iki ekran görüntüsü arasında yeni oyun kareleri çizilebilir ve resimler karşılaştırıldığında yanlış pozitif sonuçlara neden olabilir.

Ekran görüntülerini koordine etmenin bir yolu olup olmadığını öğrenmek için tam olarak aynı anda oluşmasını istiyorum. ya da bir şekilde ekran görüntüleri tamamlanana kadar yeni kareler çizerek ekranı durdurur mu?

Bu, ekran görüntülerini almak için kullandığım koddur. Not: İki ekran öğesini sıraya sokarak paralel olarak 2 ekran görüntüsünü almaya çalıştım. Bununla birlikte, bu bile ekran görüntülerinin tam olarak aynı anda gerçekleşmesine neden olmaz. Bu yüzden, ekran kartım ekrana gelene kadar ekran kartından başka güncellemeleri durdurmak için bir yol olup olmadığını merak ediyorum. Ya da başka bir şekilde bunu yapabilirim? Bunun gibi oluşturma durdurma Hakkında Sen her bilgisayarda çalışmaz yani bazı grafik accelarators için kaynak sürece, aynı anda her iki ekran görüntüleri edebilmek için gidiş değildir

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

Yaptığınız şeyin ahlaki olduğuna inanmıyorum. 'Wallhack' dedektörünüz, bir kullanıcının ifşa etmek istemeyeceği bilgileri toplamaktadır. Bir kullanıcı neden bir oyun oynarken masaüstünün ekran görüntülerini almayı kabul eder? Uygulamaya çalıştığınız davranış, truva atının sınıflandırması altında geliyor. Elbette, programınızın amacı hakkında yalan söylemiyorsan.

+0

'a taşındı. Bu, ['Parallel.Foreach'] 'ın uygun bir kullanımı olabilir (http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx). ThreadPool, paralellik garanti etmez. – Romoku

+2

Oyunun bir pencerede açıldığını varsayalım, ancak o pencerenin üzerindeki bir web tarayıcısını açmak için (google bir şey | banka hesabımı kontrol et | gözat Facebook | yasadışı bir şeyler yap) ve bunun bir ekran görüntüsünü al.Yanlış pozitif bir kayıt yapacaksınız - ben yokken aldattığım ve ispat/doğrulama için "sahte" ekran görüntüsünü yüklemeniz gerektiğine karar verirseniz, özel bilgilerimi yanlışlıkla ele geçirebilirsiniz. –

cevap

1

...

bir oyun, bence bu iyi bir fikir değil ... oyununuzun sorunsuz bir şekilde yürümesini istiyorsun.

Bunun yerine, oyununuzun yakın zamanda oluşturulmuş resimlerini bellekte saklamanızı ve ekran görüntüsünü aldığınızda bunları onlarla karşılaştırmanızı öneririz. Son karelerden hangisinin karşılaştırılacağına karar vermek için biraz görsel ipucu ekleyebilirseniz daha iyi çalışır, aksi takdirde ekran görüntüsünü hepsiyle karşılaştırmanız ve kesinlikle CPU/GPU zamanını tüketmeniz gerekir.

Oluşturmak için GDI kullanıyor musunuz? eğer öyleyse, istediğiniz şey onları karşılaştırmak için oyununuzun karelerini DIB'lerde (Aygıt Bağımsız Bitmap'ler) saklamaktır.

Hangi görüntünün kullanılacağına karar vermenin ipucu olarak, ekranda bir çeşit zaman gösterimi, belki de renk değiştiren tek bir piksele giderim. Eğer öyleyse, o pikselin rengini okuyacak, doğru çerçeveyi bulmak için onu kullanacak ve tüm resmi karşılaştırmak için prosedürü uygulayacaksınız.

+0

Oyundan işbirliğiniz varsa, aslında eski kareleri kaydetmeniz gerekmez. Eski çerçevelerin güçlü bir toplamı veya steganografi kullanarak düşük renk bitlerine gizlenen veriler, ekran üzeri görüntü yakalamanın değiştirilip değiştirilmediğini belirlemek için mükemmel bir şekilde yeterli olacaktır. –

İlgili konular