简单的QQ游戏中大家来找茬外挂编写思路

Posted on 2008-07-23 13:05  Samson小天  阅读(6029)  评论(3编辑  收藏  举报

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

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

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

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

 

 

    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, 00, rect.Width, rect.Height, dc1, 0013369376);
            
//释放掉屏幕的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, 
00);
                }

                i2
++;
            }

           g.DrawImage(bmp2, 
00);
}

 

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

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

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

Copyright © 2024 Samson小天
Powered by .NET 9.0 on Kubernetes