发一个C#QQ连连看外挂(内存版)源代码
现在游戏的基址已经改变了大家只要重新查找一下基址就直接可以用了
里面用了最经典的寻路算法(比递归算法快100倍+)
Main.csusing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace llk_wg {    class Main {
        //游戏窗口标题
        const string GAME_CAPTION = "QQ游戏 - 连连看角色版";
        //棋盘基址
        static IntPtr GAME_BASE = (IntPtr)0x0012A47C;
        //声明一个棋盘数组
        static byte[,] boxs = new byte[11, 19];
        //游戏窗口句柄
        static IntPtr hwnd;
        //初始化棋盘数组
        static void InitBox() {
            //获取游戏句柄
            hwnd = Win32.FindWindow(null, GAME_CAPTION);
            //获取棋盘数组的内存基址
            IntPtr lpBufferbase = Marshal.UnsafeAddrOfPinnedArrayElement(boxs, 0);
            //获取pid
            int ProcessId;
            Win32.GetWindowThreadProcessId(hwnd, out ProcessId);
            //打开游戏线程
            IntPtr hObject = Win32.OpenProcess(Win32.STANDARD_RIGHTS_REQUIRED | Win32.SYNCHRONIZE | 4095, false, ProcessId);
            //读取棋盘数据
            Win32.ReadProcessMemory(hObject, GAME_BASE, lpBufferbase, boxs.Length, IntPtr.Zero);
            //关闭线程
            Win32.CloseHandle(hObject);
        }
        //发送鼠标消息(顺便把图片的高度宽度也算进去)
        static void SendMouseclick(int x, int y) {
            //获取游戏句柄
            hwnd = Win32.FindWindow(null, GAME_CAPTION);
            //lparam的高位就是y坐标低位就是x坐标y左移16就到高位去了
            int lparam = (y << 16) + x;
            Win32.PostMessage(hwnd, Win32.WM_LBUTTONDOWN, 0, lparam);
            Win32.PostMessage(hwnd, Win32.WM_LBUTTONUP, 0, lparam);
        }
        //消除1对图片(模拟2次鼠标单击)
        static void ClickTwo(int x1, int y1, int x2, int y2) {
            SendMouseclick(22 + x1 * 31, 194 + y1 * 35);
            SendMouseclick(22 + x2 * 31, 194 + y2 * 35);
        }
        //游戏开局
        public static void Start(int type) {
            int x = type == 1 ? 660 : 760;
            SendMouseclick(x, 570);
        }
        //找相同的图片(本工具的核心)
        static bool Select(int x1, int y1, int x2, int y2) {            if (x1 == x2 && y1 + 1 == y2) return true;
            if (y1 == y2 && x1 + 1 == x2) return true;            List<int> list1 = new List<int>();
            List<int> list2 = new List<int>();
            List<int> list3 = new List<int>();            bool flag;            list1.Add(x1);
            for (int i = x1 - 1; i >= 0; i--) if (boxs[i, y1] == 0) list1.Add(i); else break;
            for (int i = x1 + 1; i < 11; i++) if (boxs[i, y1] == 0) list1.Add(i); else break;            list2.Add(x2);
            for (int i = x2 - 1; i >= 0; i--) if (boxs[i, y2] == 0) list2.Add(i); else break;
            for (int i = x2 + 1; i < 11; i++) if (boxs[i, y2] == 0) list2.Add(i); else break;            list3 = list1.Intersect(list2).ToList();            for (int i = 0; i < list3.Count(); i++) {
                flag = true;
                for (int j = Math.Min(y1, y2) + 1; j < Math.Max(y1, y2); j++) { if (boxs[list3[i], j] != 0) { flag = false; break; } }
                if (flag) return true;
            }            list1.Clear(); list2.Clear(); list3.Clear();            list1.Add(y1);
            for (int i = y1 - 1; i >= 0; i--) if (boxs[x1, i] == 0) list1.Add(i); else break;
            for (int i = y1 + 1; i < 19; i++) if (boxs[x1, i] == 0) list1.Add(i); else break;            list2.Add(y2);
            for (int i = y2 - 1; i >= 0; i--) if (boxs[x2, i] == 0) list2.Add(i); else break;
            for (int i = y2 + 1; i < 19; i++) if (boxs[x2, i] == 0) list2.Add(i); else break;            list3 = list1.Intersect(list2).ToList();            for (int i = 0; i < list3.Count(); i++) {
                flag = true;
                for (int j = Math.Min(x1, x2) + 1; j < Math.Max(x1, x2); j++) { if (boxs[j, list3[i]] != 0) { flag = false; break; } }
                if (flag) return true;
            }            return false;
        }
        //消除一对
        public static void RemoveSingle() {
            InitBox();            for (int x1 = 0; x1 < 11; x1++) {
                for (int y1 = 0; y1 < 19; y1++) {
                    for (int x2 = 0; x2 < 11; x2++) {
                        for (int y2 = 0; y2 < 19; y2++) {
                            if (boxs[x1, y1] != 0 && boxs[x1, y1] == boxs[x2, y2] && !(x1 == x2 && y1 == y2)) {
                                if (Select(x1, y1, x2, y2)) {
                                    ClickTwo(y1, x1, y2, x2);
                                    return;
                                }
                            }
                        }
                    }
                }
            }
        }
        //消除所有
        public static void RemoveAll() {
            InitBox();
        Target:
            for (int x1 = 0; x1 < 11; x1++) {
                for (int y1 = 0; y1 < 19; y1++) {
                    for (int x2 = 0; x2 < 11; x2++) {
                        for (int y2 = 0; y2 < 19; y2++) {
                            if (boxs[x1, y1] != 0 && boxs[x1, y1] == boxs[x2, y2] && !(x1 == x2 && y1 == y2)) {
                                if (Select(x1, y1, x2, y2)) {
                                    ClickTwo(y1, x1, y2, x2);
                                    boxs[x1, y1] = 0;
                                    boxs[x2, y2] = 0;
                                    goto Target;
                                }
                            }
                        }
                    }
                }
            }
        }
        //获取其他玩家最小box数量值
        public static byte GetOtherUserMinNum() {
            byte value = 0;
            byte[] buffer = new byte[20];
            int lpBase = 0x0012E04C;// 0x00115CDC;//0012E04C
            //获取游戏句柄
            hwnd = Win32.FindWindow(null, GAME_CAPTION);
            //获取棋盘数组的内存基址
            IntPtr lpBufferbase = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
            //获取pid
            int ProcessId;
            Win32.GetWindowThreadProcessId(hwnd, out ProcessId);
            //打开游戏线程
            IntPtr hObject = Win32.OpenProcess(Win32.STANDARD_RIGHTS_REQUIRED | Win32.SYNCHRONIZE | 4095, false, ProcessId);
            //读取棋盘数据
            Win32.ReadProcessMemory(hObject, (IntPtr)lpBase, lpBufferbase, buffer.Length, IntPtr.Zero);
            //关闭线程
            Win32.CloseHandle(hObject);
            try { value = buffer.Where(o => o != 0).Min(); } catch { }
            return value;
        }
        //获取自己的图片数量
        public static byte GetShengyuNum() {
            byte[] buffer = new byte[4];
            //0012E048,00115CD8
            int lpBase = 0x0012E048;// 0x00115CDC;//0012E04C
            //获取游戏句柄
            hwnd = Win32.FindWindow(null, GAME_CAPTION);
            //获取棋盘数组的内存基址
            IntPtr lpBufferbase = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
            //获取pid
            int ProcessId;
            Win32.GetWindowThreadProcessId(hwnd, out ProcessId);
            //打开游戏线程
            IntPtr hObject = Win32.OpenProcess(Win32.STANDARD_RIGHTS_REQUIRED | Win32.SYNCHRONIZE | 4095, false, ProcessId);
            //读取棋盘数据
            Win32.ReadProcessMemory(hObject, (IntPtr)lpBase, lpBufferbase, buffer.Length, IntPtr.Zero);
            //关闭线程
            Win32.CloseHandle(hObject);
            return Marshal.ReadByte(lpBufferbase);
        }
    }
}

解决方案 »

  1.   

    Win32.csusing System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;namespace llk_wg
    {
        /// <summary>
        /// win32API函数声明
        /// </summary>
        class Win32
        {        [DllImport("user32.dll", EntryPoint = "FindWindowA")]
            public static extern IntPtr FindWindow( string lpClassName,  string lpWindowName);        [DllImport("user32.dll", EntryPoint = "PostMessageA")]
            public static extern bool PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);        [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
            public static extern int GetWindowThreadProcessId( IntPtr hWnd, out int lpdwProcessId);        [DllImport("kernel32.dll", EntryPoint = "OpenProcess")]
            public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);        [DllImport("kernel32.dll", EntryPoint = "CloseHandle")]
            public static extern bool CloseHandle(IntPtr hObject);        [DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")]
            public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, IntPtr lpNumberOfBytesRead);        public const int WM_LBUTTONDOWN = 513;
            public const int WM_LBUTTONUP = 514;
            public const int STANDARD_RIGHTS_REQUIRED = 983040;
            public const int SYNCHRONIZE = 1048576;    }
    }
      

  2.   

    Program.csusing System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;namespace llk_wg
    {
        static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
        }
    }
      

  3.   

    Form1.csusing System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;namespace llk_wg
    {
        public partial class Form1 : Form
        {
            bool flag = false;        public Form1()
            {
                InitializeComponent();
            }        private void btnStart_Click(object sender, EventArgs e)
            {
                Main.Start(1);
            }        private void btnLianxi_Click(object sender, EventArgs e)
            {
                Main.Start(2);
            }        private void btnSingle_Click(object sender, EventArgs e)
            {
                Main.RemoveSingle();
            }        private void btnAll_Click(object sender, EventArgs e)
            {
                Main.RemoveAll();
            }        private void btnAuto_Click(object sender, EventArgs e)
            {
                flag = !flag;            if (flag)
                {
                    this.btnAuto.Text = "停止挂机";
                    this.timer1.Start();
                }
                else 
                {
                    this.btnAuto.Text = "挂机";
                    this.timer1.Stop(); 
                }
            }        private void timer1_Tick(object sender, EventArgs e)
            {
                this.timer1.Interval = 100;
                int otherMin = Main.GetOtherUserMinNum();
                int selfMin = Main.GetShengyuNum();
                if (otherMin - 2 <= selfMin) Main.RemoveSingle();
                if (selfMin == 0) Main.Start(1);
            }
        }
    }
      

  4.   

    帮忙插楼,希望有能力的童靴做一个检测dota开挂的软件.
      

  5.   

    新学 。net 
    look下!~
      

  6.   

    囧rz 直接发网盘就好了 这么麻烦贴代码 o(︶︿︶)o 唉
    不过支持下
      

  7.   

    我是搞java的 ,看到这个算法 不禁使我想起一些往事,每当有人说他是搞C的时候,我总要情不自禁的去看看他的头发。
      

  8.   

    请问如何获得的基址,原来用的CE,但是现在有SX检测了,过不了,求楼主解答~~
      

  9.   

    0x0012A47C  我估计这个基址 你找不到
      

  10.   

    新人路过,对外挂还完全不入门的表示说(但挺想学的)。
    求段示例性代码的帖子,如何获得游戏发来的数据,又如何发过去
    另外,连连看的AI算法感觉好高端,纯搜索估计要超时,会让用户蛋碎本人学C#1年(大二,编程课只开了C语言),算法略通(好吧ACM的水题,擅长搜索题 汗!——)
    高级的搜索算法只接触过五子棋的AI,好吧,极大极小搜索,那算不上算法,αβ剪枝,略有点意思,但也不高端
    技术方面,接触过socket,asp.net略知一二(好吧,这没关系)
    差不多看的陈广->传智播客的视频被英语折磨1年了(估计这次6级挂了,但不想学了)谁能指条明路