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,有问题加我

时间: 2024-12-21 09:08:32

qq欢乐斗地主 基址 C# 详解的相关文章

使用cocos2d-x模仿QQ欢乐斗地主手机版的界面控件

前段时间在做一款斗地主游戏,需要实现类似QQ欢乐斗地主主里面的效果.见下面效果图. 实现细节就不细说了,参见源码.大体就是将一个使用椭圆算法(参考<计算机图形学(第三版)>3.10)生成一个椭圆,在椭圆上每隔90度放置一个精灵.然后滑动的时候再计算每个精灵的新位置,并且根据与中心上的精灵的距离更新每个精灵的颜色.大小.层级等属性. 说说使用,这个在使用上也是比较简单的,如下所示. bool HelloWorld::init() { //////////////////////////////

欢乐茶园系统开发详解——果园种植类的商业模式怎么做?

欢乐茶园系统开发 联系 苏念 188.1414.7927 欢乐茶园游戏开发 欢乐茶园种植开发 欢乐茶园app开发 管理学大师彼得·德鲁克曾经说过:"当今企业之间的竞争,不是产品之间的竞争,而是商业模式之间的竞争.在互联网思维被赋予多重定义的时代,商业模式和传统的商业模式最大的区别在于,不再是关于成本和规模的讨论,而是关于重新定义客户价值的讨论.商业模式就是如何创造和传递客户价值和公司价值的系统.可见,客户价值以及客户价值主张的重要性非同一般. 1   商业模式创新企业几个共同特征,或者说构成商业

第三方登录(QQ登录)开发流程详解

原文  http://www.cnblogs.com/it-cen/p/4338202.html 主题 OpenID 近排由于工作的繁忙,已经一个星期没写博文做分享了,接下来我对网站接入第三方登录----QQ登录的实现逻辑做一个详细的讲解. 对于整个流程的详细文档可以到QQ互联官网( http://wiki.connect.qq.com )查看,我这里就简单地进行描述,主要是分析代码的实现过程. 我用的是CI框架(MVC模式),模板引擎用的是smarty. 下图为整个接入流程: 一.准备工作 接

(转)第三方登录(QQ登录)开发流程详解

近排由于工作的繁忙,已经一个星期没写博文做分享了,接下来我对网站接入第三方登录----QQ登录的实现逻辑做一个详细的讲解. 对于整个流程的详细文档可以到QQ互联官网(http://wiki.connect.qq.com)查看,我这里就简单地进行描述,主要是分析代码的实现过程. 我用的是CI框架(MVC模式),模板引擎用的是smarty. 下图为整个接入流程: 一.准备工作 接入QQ登录前,网站需首先进行申请,获得对应的appid与appkey,以保证后续流程中可正确对网站与用户进行验证与授权.

详解C++引用——带你走进引用的世界

 一.介绍引用 首先说引用是什么,大家可以记住,引用就是一个别名,比如小王有个外号叫小狗,他的妈妈喊小狗回家吃饭,那就是在喊小王回家吃饭. 接下来我们用两行代码来声明一个引用(就拿小王和小狗来说吧): int xiaoW; int &xiaoG=xiaoW; 上面就是一个引用,说明几点要注意的地方: 1.&不是取地址符,而是引用运算符: 2.xiaoG是xiaoW的别名,所以这两个变量的值和地址都是一样的: 3.引用只能初始化,而不能先声明再赋值,因为引用就相当于一个常量: 4.在声明

SwipeListView 详解 实现微信,QQ等滑动删除效果

Linux的shell编程 1.什么是shell? 当一个用户登录Linux系统之后,系统初始化程序init就为每一个用户运行一个称为shell(外壳)的程序. shell就是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用shell来启动.挂起.停止甚至是编写一些程序.一般的Linux系统都将bash作为默认的shell. 2.几种流行的shell 目前流行的shell有ash.bash.ksh.csh.zsh等,可以用下面的命令来查看she

详解C# 网络编程系列:实现类似QQ的即时通信程序

引言: 前面专题中介绍了UDP.TCP和P2P编程,并且通过一些小的示例来让大家更好的理解它们的工作原理以及怎样.Net类库去实现它们的.为了让大家更好的理解我们平常中常见的软件QQ的工作原理,所以在本专题中将利用前面专题介绍的知识来实现一个类似QQ的聊天程序.  一.即时通信系统 在我们的生活中经常使用即时通信的软件,我们经常接触到的有:QQ.阿里旺旺.MSN等等.这些都是属于即时通信(Instant Messenger,IM)软件,IM是指所有能够即时发送和接收互联网消息的软件. 在前面专题

小甲鱼PE详解之基址重定位详解(PE详解10)

今天有一个朋友发短消息问我说“老师,为什么PE的格式要讲的这么这么细,这可不是一般的系哦”.其实之所以将PE结构放在解密系列继基础篇之后讲并且尽可能细致的讲,不是因为小甲鱼没事找事做,主要原因是因为PE结构非常重要,再说做这个课件的确是很费神的事哈.在这里再次强调一下,只要是windows操作程序,其就要遵循PE格式,再说人家看雪的网址就是www.pediy.com. 简单的讲是可以,但是怕就怕有些朋友知识点遗漏了或者错误理解意思.不能深刻体会等,这样的效果是不好的~所以,小甲鱼尽管这系列视频可

腾讯技术分享:GIF动图技术详解及手机QQ动态表情压缩技术实践

本文来自腾讯前端开发工程师" wendygogogo"的技术分享,作者自评:"在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦." 1.GIF格式的历史 GIF ( Graphics Interchange Format )原义是"图像互换格式",是 CompuServe 公司在1987年开发出的图像文件格式,可以说是互联网界的老古董了. GIF 格式可以存储多幅彩色图像,如果将这些图像((https://www.q