最近接到个项目,头大了很一阵,今天终于有时间写写自己喜欢的东西了。前几日和同学玩大家来找茬,老是输……于是终于决定发挥程序员的优势,编写一个大家来找茬的外挂,或者说作弊器更贴切点。

          首先我们理清思路,我们如何才能比较出两张图片的区别之处呢?首先我们知道图片是有像素组成的(就算是矢量图片传入显示器也会变成像素的吧)。大方向上我们就靠每个像素的分析来解决这个问题吧。

          既然是针对QQ游戏的作弊器,那么我们就要分析QQ游戏中“大家来找茬”的界面了。直接在QQ游戏上动手脚是不行的,所以我们需要把“大家来找茬”的两张图片截获下来。这有两种方法,捕获网络传输和对QQ游戏截图。我选择了后者,因为后者比较不容易被QQ游戏发现,而且上手也简单。

          那么我们就来看看如何截图。从《Programming Windows》中我们看到有一个叫BitBlt的函数。可以对指定设备的像素进行捕获。没错就是这个API了。但是一用到.net没提供的函数就是一件头大的事,这次也不例外。BitBlt函数要求有被截图的窗体的设备驱动器句柄,这就涉及到另外两个API函数,GetDC(hwnd),ReleaseDC()的调用了。GetDC()可以获得指定窗体句柄的设备驱动器句柄,但是要求有被获取窗体的窗体句柄,然后我们又要用FindWindow()函数,=_=||

 

 

python qq大厅游戏 大家来找茬辅助 qq游戏大家来找茬最新_句柄

public class Api
    
{
        [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
        private static extern bool BitBlt(
            IntPtr hdcDest, // 目标 DC的句柄 
            int nXDest,
            int nYDest,
            int nWidth,
            int nHeight,
            IntPtr hdcSrc, // 源DC的句柄 
            int nXSrc,
            int nYSrc,
            System.Int32 dwRop // 光栅的处理数值 
            );
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
        public extern static IntPtr FindWindow(string lpClassName,string lpWindowName);
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
        public extern static IntPtr GetDC( IntPtr hWnd);
        [System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
        public extern static int ReleaseDC(  IntPtr hWnd,IntPtr hDC);
    }

 

         有了这些API就能开始截图了....

 

 

public void SavePic()
{
            //获得当前窗体的大小 
            Rectangle rect = this.ClientRectangle;
            //创建一个以当前屏幕为模板的图象 
            Graphics g1 = this.CreateGraphics();
            //创建以此为大小的标准位图 
            Image MyImage = new Bitmap(rect.Width, rect.Height, g1);
            Graphics g2 = Graphics.FromImage(MyImage);
            //得到屏幕的DC 
            IntPtr dc1 = g1.GetHdc();
            //得到Bitmap的DC 
            IntPtr dc2 = g2.GetHdc();
            //调用此API函数,实现屏幕捕获 
            BitBlt(dc2, 0, 0, rect.Width, rect.Height, dc1, 0, 0, 13369376);
            //释放掉屏幕的DC 
            g1.ReleaseHdc(dc1);
            //释放掉Bitmap的DC 
            g2.ReleaseHdc(dc2);
            //以JPG文件格式来保存 
             MyImage.Save("Capture.jpg", ImageFormat.Jpeg);
            MessageBox.Show("当前屏幕已经保存为当前目录的capture.jpg文件!");
            g1.DrawImage(MyImage, this.ClientRectangle);//在窗体上画出被捕获的图片
}

 

          将以上代码复制到你的方法中就能进行截图了,只不过这里截的图是自己窗体的,所以就没有用到GetDC,FindWindow两个API。

          接下来是分析图片了。QQ游戏中左边那张图片位置是在X=10左右随机的,右边那张图在X=407的位置(在分辨率为1440*900条件下测试)。估计是反作弊用的。左边的位置我们可以让用户自己去确定。比如设个快捷键,让用户移到左边那张图片后按下快捷键。

          分析图片用如下代码:

          p1,p2是两个坐标,用于标记两张图片的起始位置。

          bmp2是一个Bitmap类型。就是当初截图截下来后用基类Image来指向的。

          出于效率考虑,这里之从起点坐标开始横向比较190个像素,纵向比较300个像素。此处请自己修改,否则会抛出IndexOutofRange异常的。

 

public void Analyze()
{
            Point p1,p2;
            Color c1 = Color.Blue;
            Color c2 = Color.Red;
            int i = Convert.ToInt32(p1.x), j;
            Graphics g = this.CreateGraphics();
            int i2 = Convert.ToInt32(p2.x);
            int iS = i + 190, js;
            for (; i < iS; i++)
            
{
                for (j = Convert.ToInt32(p1.y), js = j + 300; j < js; j++)
                
{
                    c1 = bmp2.GetPixel(i, j);
                    c2 = bmp2.GetPixel(i2, j);
                    if (c1 != c2)
                        bmp2.SetPixel(i, j, Color.FromArgb(c1.ToArgb() - c2.ToArgb()));
                    bmp2.SetPixel(i2, j, Color.Blue);
                    g.DrawImage(bmp2, 0, 0);
                }
                i2++;
            }
           g.DrawImage(bmp2, 0, 0);
}

 

          循环中,如果发现两者颜色不同就就像不同处用红色代替。

          程序就是这么简单了,本来是想写的好点的,但是这个程序分析图片的速度真是……完全没有想法,竟然要8秒!整个游戏都只有14秒……看来还是得用C++写比较好啊....=_=||

          代码贴出来仅供娱乐。欢迎大家提出意见。