你的位置:首页 > ASP.net教程

[ASP.net教程]qq欢乐斗地主 基址 C# 详解


仅供学习交流,误用于非法用途.

 

转载请标明出处.

相信有很多朋友在搜索斗地主"基址"的时候发现这个"基址"总是会变,这是为什么呢?

因为这个所谓的基址其实上是"GameLogic.dll"模块相对地址,而每次加载"GameLogic.dll"模块的时候,"GameLogic.dll"模块的加载地址都会改变,所以我们找到的这个"基址"会变得不固定,一直变动.

我想到了两个方法来解决这个问题

方法一:

根据上面的理解,我们搜索到的地址会变动是因为"GameLogic.dll"模块的加载地址在变动,所以我们只要取到"GameLogic.dll"模块的加载地址,就可以通过计算取到我们想要的基址(牌的地址,座位号的地址....)

比如说:

我在右上角

    我的手牌 0x08dfc408

    右上|我出的牌 0x08dfc8f0
    左上|我的右边 0x08dfe6d0
    下边|我的左边 0x08dfd7e0

"GameLogic.dll"的起始地址是0x08d00000

那我们就可通过计算:

      我的手牌 0x08dfc408 - 0x08d00000 = FC408

      右上|我出的牌 0x08dfc8f0 - 0x08d00000 = ?
      左上|我的右边 0x08dfe6d0 - 0x08d00000 = ?
      下边|我的左边 0x08dfd7e0 - 0x08d00000 = ? //我这里不一一计算了

  在我们下次取地址的时候就可以根据"GameLogic.dll"模块的加载地址 + FC408,得到"我的手牌"的地址.

  以上是推论,地址是编的,不要直接拿来用

想要取得"GameLogic.dll"的起始地址,在c#里只需要两个类就可以完成,"Process"类和"ProcessModule"类,需要引用"System.Diagnostics"命名空间.

Process 是对进程访问.

ProcessModule 是对进程模块访问.

Process[] p = Process.GetProcessesByName("hlddzSDK");//GetProcessesByName是查找所有匹配的进程名称,返回一个Process的数组      foreach (ProcessModule pm in p[0].Modules)//遍历加载模块      {        if (pm.ModuleName == "GameLogic.dll")//如果加载的模块名称是"GameLogic.dll"        {          return pm.BaseAddress;//返回该模块的内存地址        }      }

  如果是其他语言需要调用api"CreateToolhelp32Snapshot",这里不多说了,请自行百度.

方法二:

这种方法比较繁琐,是我后来想到的,理论上是可以无视版本更新.

在CE里,我们发现记录牌的地址的数据是有规律的,

比如说我手牌有黑桃K,红桃Q,梅花J.那么在地址中的排列是这样的:

  01 0d 00 00 00 00 00 00 ?? ?? 00 00 02 0c 00 00 00 00 00 00 ?? ?? 00 00 03 0b 00 00 00 00 00 00 ?? ?? 00 00

不难发现01是黑桃,0d是k,02是红桃,0c是Q,03梅花,0b是J.??我猜测是数组的下标志.每一张牌中间相隔是个数据,根据这样的规律我们就可以遍历进程中所有的数据进行对比,

只要匹配的话我们就可以判断这段数据是记录牌的信息的一段数据.

想要实现这个功能,需要掉用api,

/// <summary>    /// 查询地址空间中内存地址的信息    /// </summary>    [DllImport("kernel32.dll")]    public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, int dwLength);    public struct MEMORY_BASIC_INFORMATION    {      public int BaseAddress;      public int AllocationBase;      public int AllocationProtect;      public int RegionSize;      public int State;      public int Protect;      public int lType;    }    public const int MEM_COMMIT = 0x1000;    //已物理分配    public const int MEM_PRIVATE = 0x20000;    public const int PAGE_READWRITE = 0x04;   //可读写内存

/// <summary>    /// 从指定内存中读取字节集数据    /// </summary>    /// <param name="handle">进程句柄</param>    /// <param name="address">内存地址</param>    /// <param name="data">数据存储变量</param>    /// <param name="size">读出的数据大小</param>    /// <param name="read">数据的实际大小</param>    [DllImport("Kernel32.dll")]    public static extern bool ReadProcessMemory(IntPtr handle, int address, byte[] data, int size,byte[] read);

以上是引用非托管类库,

VirtualQueryEx应该很少有人用到,解释一下
程序的内存是由页组成的,每个页的访问权限和等等是不一样的,
VirtualQueryEx就是访问远程进程的页的信息,得到的信息储存在lpBuffer结构体里.
ps:用这个函数是可以实现类似于ce的内存搜索工具的.

下面是代码:

MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();      int qkdz = 0x000000;//区块地址,从0开始读      IntPtr jcjb = Process.GetProcessesByName("hlddzSDK")[0].Handle;//进程句柄       while (qkdz <= 0x7fffffff)//0x7fffffff之前是用户地址,只要读0-0x7fffffff就可以了      {        VirtualQueryEx(jcjb, (IntPtr)qkdz, out mbi, Marshal.SizeOf(mbi));//读出本次读取的页的信息        if (mbi.State == MEM_COMMIT && mbi.Protect == PAGE_READWRITE)//如果该页的信息已经分配,并且可读写        {          byte[] dcdsj = new byte[mbi.RegionSize];//读出的数据          byte[] sjdcdsj = new byte[mbi.RegionSize];//实际读出的数据          int qbppdxb = -1;//全部匹配的数组下标                    ReadProcessMemory(jcjb, qkdz, dcdsj, mbi.RegionSize, sjdcdsj);//把该页面的所有信息读取的 dcdsj 数组里          for (int i = 0; i < dcdsj.Length - 203; i++)//循环判断匹配牌的格式的的数据          {            int jy = i;            #region 判断             if (dcdsj[jy] > 4) { continue; }//如果这个数值大于4,就说明不是花色的信息,跳出本次循环,进行下一次循环            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }//如果这个数值大于15或者小于1,就说明这不是牌的信息,跳出本次循环,进行下一次循环            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;//因为中间有两个值不确定,所以不进行匹配,直接跳过去            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] > 4) { continue; }            jy++;            if (dcdsj[jy] > 15 || dcdsj[jy] < 1) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy += 3;            if (dcdsj[jy] != 0) { continue; }            jy++;            if (dcdsj[jy] != 0) { continue; }            jy++;            #endregion            //一直匹配17张牌,这个是手牌,如果全部匹配的话会运行到这里            //全部符合匹配条件之后发现还是有不是牌的数据,只有再添加一个筛选.先把每张牌都添加进一个字符串里,            //然后判断字符串里是否已经有了这张牌,如果有了,说明这次匹配的数据不对,因为扑克牌的数据是不会出现重复的,出现重复自然就不是了            string s = "";            bool sfyjcz = true;//是否已经存在            for (int i1 = 0; i1 < 204; i1 += 12)            {              string bcpk = dcdsj[i + i1].ToString() + "-" + dcdsj[i + i1 + 1].ToString();//本次扑克              if (s.IndexOf(bcpk) == -1)              {                s = s + bcpk + ",";              }              else              {                sfyjcz = false;                break;              }            }            if (sfyjcz)//如果所有牌都不一样,就把i的值赋值给qbppdxb,否则的话qbppdxb是-1            {              qbppdxb = i;            }          }          if (qbppdxb != -1)//如果qbppdxb的值不是-1说明读出了牌的地址          {            return mbi.BaseAddress + qbppdxb;//BaseAddress该页的地址,返回牌的地址          }        }        qkdz += mbi.RegionSize;//RegionSize该页的大小,读下一个页      }

 

就这样了其他代码我以后可能会写,看完请回复.

737355009,这是我qq,有问题加我