其实说实话,我写这类文章有些牵强,因为我也是新手。刚学习这个技术所以我所了解的东西实在是太少,没有什么太多的东西分享给大家,只希望写这点东西能帮助到那些跟我一样或者比我还菜的新手朋友。

做外挂,貌似是很多高手所不齿的一个偏行,但似乎又是在现在这个游戏横行年代中很流行的技术话题,但若是我们仔细探究其根源:做外挂似乎也没什么太高的技术含量,说到底就是编程。

今天,就由我来带领大家了解一下做外挂这个“技术”的方方面面吧。

一、        引子

由于我在外挂方面也是一个刚入门的新人,这里所讲的也仅仅是我所接触层面上的一些知识,肯定是不全面的,因此,我在这里就尽量把我所了解到的知识讲的尽可能详细,以弥补我知识面上的欠缺,希望大家能够谅解,也希望大家莫要笑话我……

本文,我将从基础的数据分析开始着手,到程序实现,再到过保护,再到节省系统资源等,以这样层层递进的方式来讲述我要展现给大家的东西。

在每个知识点讲解的时候,我会尽量的分好每一个小节,争取让它更有条理,希望这样讲述大家能够接受也希望大家在技术上有所突破。

在正式开始我们的旅程之前,希望大家能够提前了解下如下一些知识:

1、    OD的使用方法。

2、    了解些内存搜索工具的用法。

3、    掌握些基础的编程思想

希望大家在思考所有问题的时侯,都能从编程的角度去考虑,因为这样就可以有更多的思路、更多的分析方法,更多的技巧,这些是那些不懂编程的朋友永远得不到的强处。

二、        关于数据分析

在网上,尤其像广海,断点这样的外挂论坛,上面有很多关于数据分析的教程,其中很多文章讲的就是用搜索工具查找数据指针,而且似乎很多人都不厌其烦的在讲,在写,在讨论,但是当我仔细去问究为什么的时候,似乎没几个人能给一个令我满意的答案。

相信看这个文章的读者肯定看过很多像我刚才说的那样的文章了,我也相信很多的朋友都会也知道为什么用搜索工具搜数据指针。当然也有很多的朋友不知道的,这里我就从最基础的开始说。

1、基础属性数据的分析

A.        需求分析

当我们在做挂的时候,我们需要根据角色的血量,魔法量的多少来吃药,以保证角色不死掉来提高挂机的效率。在挂机的时候,怕角色乱跑,所以我们需要根据坐标来定一个挂机范围,因此,我们需要分析角色的基础属性。

B.        起始思路

找基础属性,有这么几个方法,思路是这样的:

i.              想很多教程中写的,根据血量、等级、经验、攻击等任何一个属性值的变化,来搜索变化的值,然后用CE找数据指针。

ii.              从编程角度来考虑,任何一个在屏幕上显示的数据都是字符,游戏中显示的属性信息都是字符,比如血量在游戏的数据结构中应该是整型数据,在显示到屏幕上需要进行类型转换,调用类似sprintf这样的函数,比如:

004E8E01  |.  8B86 B0020000 mov     eax, dword ptr [esi+0x2B0]  ; 取出当前血量

004E8E07  |.  8B8E 78020000 mov     ecx, dword ptr [esi+0x278]  ; 取出最大血量

004E8E0D  |.  50                    push    eax

004E8E0E  |.  51                    push    ecx

004E8E0F  |.  8D5424 58             lea     edx, dword ptr [esp+0x58]

004E8E13  |.  68 88BE9C00           push    009CBE88       ;  UNICODE "%d / %d"

004E8E18  |.  52                    push    edx

004E8E19  |.  FFD5                  call    ebp         ; sprintf函数

这样,我们就可以通过在OD中搜索相应的字符串来定位到如上这样的代码,在仔细分析ESI的来历,这样我们就可以得到相应数据结构的指针。

C.       调试过程

这里我举一个例子,就像我前些日子分析的口袋西游。

内存搜索,找力量值,得到结果如下:

106CC99C      6

内存访问断点,来到如下代码:

004E8F01  |.  8B86 18030000 mov     eax, dword ptr [esi+0x318]       ;  最大力量

004E8F07  |.  8B8E 14030000 mov     ecx, dword ptr [esi+0x314]       ;  最小力量

004E8F0D  |.  50            push    eax

004E8F0E  |.  51            push    ecx

004E8F0F  |.  8D5424 58     lea     edx, dword ptr [esp+0x58]

004E8F13  |.  68 24969C00   push    009C9624                ;  UNICODE "%d-%d"

004E8F18  |.  52            push    edx

004E8F19  |.  FFD5          call    ebp                              ;  显示出来

这些代码由此向下,有很多的数据都是这个结构体的成员,具体的含义大家可以跟一下,对比游戏中显示的数据猜出其具体含义。

004E8B19  |.  E8 3249FEFF   call    004CD450

{

004CD450  /$  A1 4C28A200   mov     eax, dword ptr [0xA2284C]

004CD455  |.  8B48 1C       mov     ecx, dword ptr [eax+0x1C]

004CD458  |.  8B41 28       mov     eax, dword ptr [ecx+0x28]

004CD45B  /.  C3            retn

}

004E8B1E  |.  8BF0          mov     esi, eax

下面总结一下:

0xA2284C]+0x1C]+0x28]

+3C X

+40  Z

+44  Y

+264:   角色ID

+26C:   角色职业       1:灵剑,2:日羽,3:枪侠,4:萨满,5:法皇,6:药王

+270:   角色等级

+278:   当前血量

+27C:   当前魔法

+280:   当前异能

+284:   当前精力

+2B0:   最大血量

+2B4:   最大魔法

+2B8:   最大异能

+2BC:   最大精力

+348:   背包金钱

+434:   名字

+704:   移动速度

+8F4:   选择的目标ID

这样我们的角色基础属性就算是分析完成了,可以根据编程需要将它整理成对应的结构体。比如:

// 个人属性信息结构

typedef struct _GAME_CHAR_INFO

{

DWORD         UnKnown1[15];          //   未知 offset   0

float         fX;                    //   X坐标    offset   0x3C

float         fZ;                    //   Z坐标    offset   0x40

float         fY;                    //   Y坐标    offset   0x44

DWORD         UnKnown2[135];         //   未知 offset   0x48

DWORD         dwSID;                 //   角色ID   offset   0x264

DWORD         UnKnown3;              //   未知 offset   0x268

DWORD         dwZhiYe; //   职业 offset 0x26C 1:灵剑,2:日羽,3:枪侠,4:萨满,5:法皇,6:药王

DWORD         dwLv;                       //   等级 offset   0x270

DWORD         UnKnown4;              //   未知 offset   0x274

DWORD         dwCurHP;               //   当前HP   offset   0x278

DWORD         dwCurMP;               //   当前MP   offset   0x27C

DWORD         dwCurYN;               //当前异能    offset   0x280

DWORD         dwCurJL;               //当前精力    offset   0x284

DWORD         UnKnown5[10];          //   未知 offset   0x28C

DWORD         dwMaxHP;               //   最大HP   offset   0x2B0

DWORD         dwMaxMP;               //   最大MP   offset   0x2B4

DWORD         dwMaxYN;               //最大异能    offset   0x2B8

DWORD         dwMaxJL;               //最大精力    offset   0x2BC

DWORD         UnKnown6[34];          //   未知 offset   0x2C0

DWORD         dwMoney;               //   金钱 offset   0x348

DWORD         UnKnown7[58];          //   未知 offset   0x34C

wchar_t* strName;               //人物名称    offset   0x434

DWORD         UnKnown8[0x12F];       //   未知 offset   0x438

DWORD         dwTSID;                //   目标实例offset     0x8F4

DWORD         UnKnown9[0x2B];        //   未知 offset   0x8F8

PGAME_BAG_FIRST    pGBF;              // 背包结构指针offset 0x9A4

PGAME_BAG_FIRST    pGBF;              // 装备结构指针offset 0x9A8

DWORD         UnKnown10[0x28];       // 未知       offset 0x9AC

PGAME_SKILL_LIST pGSL;               // 技能列表   offset 0xA4C

DWORD         nCurSkillNum;          // 当前技能数量offset 0xA50(基础是x17,学一个技能加)

DWORD         nMaxSkillNum;          // 最大技能数量offset 0xA54

} GAME_CHAR_INFO, *PGAME_CHAR_INFO;

到这里,无论是从分析的角度还是从编程的角度,这个数据的分析就算是完工了。下面我们来看一下怎么用代码来操作这些数据。

D.       代码实现

关于读取内存的代码几乎不同的人都有不同的写法,当然各有利弊,我这里写我比较习惯的方法吧。

关于定位数据结构的首地址:

/************************************************************************/

/* 获取人物信息指针                                                    */

/* [g_dwBasePointAddr]+0x1C]+0x28]                                      */

/************************************************************************/

__declspec(naked) PGAME_CHAR_INFO WINAPI GetCharInfoPoint()

{

__asm

{

mov      eax, dword ptr [g_dwBasePointAddr]

test      eax, eax

je       NULL_POINT

mov      eax, dword ptr [eax]

test      eax, eax

je       NULL_POINT

mov      eax, dword ptr [eax+0x1C]

test      eax, eax

je       NULL_POINT

mov      eax, dword ptr [eax+0x28]

NULL_POINT:

retn

}

}

这样,只要我们调用这个函数就可以定位到PGAME_CHAR_INFO结构,关于这个结构的定义和分析参考本数据的分析部分。

具体的使用,我给出我的MFC的显示函数:

/************************************************************************/

/* 功能:显示人物信息                                                   */

/* 参数:无                                                             */

/* 返回:无                                                             */

/************************************************************************/

void CFirstTask::ShowRoleInfo()

{

wchar_t            szTemp[512] = {0};

PGAME_CHAR_INFO pGCI = GetCharInfoPoint();

SetDlgItemTextW(IDC_MYNAME,pGCI->strName);

switch (pGCI->dwZhiYe)

{

case 1:

lstrcpyW(szTemp, L"灵剑/0");

break;

case 2:

lstrcpyW(szTemp, L"日羽/0");

break;

case 3:

lstrcpyW(szTemp, L"枪侠/0");

break;

case 4:

lstrcpyW(szTemp, L"萨满/0");

break;

case 5:

lstrcpyW(szTemp, L"法皇/0");

break;

case 6:

lstrcpyW(szTemp, L"药王/0");

break;

default:

lstrcpyW(szTemp, L"未知/0");

break;

}

SetDlgItemTextW(IDC_MYZHIYE, szTemp);

wsprintfW(szTemp, L"%d/%d", pGCI->dwCurHP,pGCI->dwMaxHP);

SetDlgItemTextW(IDC_MYHP, szTemp);

wsprintfW(szTemp, L"%d/%d", pGCI->dwCurMP,pGCI->dwMaxMP);

SetDlgItemTextW(IDC_MYMP, szTemp);

wsprintfW(szTemp, L"%d/%d", pGCI->dwCurYN,pGCI->dwMaxYN);

SetDlgItemTextW(IDC_MYYN, szTemp);

wsprintfW(szTemp, L"%d/%d", pGCI->dwCurJL,pGCI->dwMaxJL);

SetDlgItemTextW(IDC_MYJL, szTemp);

swprintf(szTemp, L"%.0f,%.0f,%.0f↑", pGCI->fX, pGCI->fY, pGCI->fZ);

SetDlgItemTextW(IDC_MYXYZ, szTemp);

wsprintfW(szTemp, _T("%d金%d银%d铜"),

pGCI->dwMoney / 10000, (pGCI->dwMoney % 10000) / 100, (pGCI->dwMoney % 10000) % 100);

SetDlgItemTextW(IDC_MYMONEY, szTemp);

wsprintfW(szTemp, L"%d", pGCI->dwLv);

SetDlgItemTextW(IDC_MYLEVEL, szTemp);

}

贴一下显示的效果:
            

浅析游戏辅助工具的开发相关推荐

  1. 【网络游戏§绿色DOTA2魔笛V1.001 官方最新版§DOTA游戏辅助工具§】

    [网络游戏§绿色DOTA2魔笛V1.001 官方最新版§DOTA游戏辅助工具§] 软件大小:11.53MB 软件语言:简体中文 软件授权:免费软件 更新时间:2013-06-19 01:27:40 应 ...

  2. 以前写的网页游戏辅助工具源码 传奇类的HOOK 封包 按钮

    以前写的网页游戏辅助工具源码 传奇类的HOOK 封包 按钮. 限量出源码,有需要的 116327160

  3. 萝卜游侠-一款搜索和修改内存地址的游戏辅助工具

    上次我发布的GameEnchanter也是一个强大的游戏修改工具.不知道的可以点GameEnchanter打开研究下.今天我就大家带来的是另一款游戏修改工具.萝卜游侠是一款搜索和修改内存地址的游戏辅助 ...

  4. 史上最全的程序猿工具集(辅助工具、开发工具、技术栈、学习网站、博客论坛)

    您的关注,是我前进的最大动力,各位老铁,看完收藏一波,你值得拥有 前言 在平时的开发工作中我们需要使用到很多的工具来辅助我们的开发,也经常会查阅很多的网站来收集资料.下面具体总结一下开发过程中的一些工 ...

  5. C#使用 WebBrowser制作网页游戏辅助工具关键技术分析

    使用WebBrowser控件,实现起来确实很方便,但灵活性差,比不上直接组包发包.对三国风云这款网页游戏来 说,WebBrowser用的好的话理论上可以实现想要的功能(我只实现了整点自动"举 ...

  6. \t\tFlash网页游戏辅助工具制作简析

    <热血三国>好像是比较热,玩的人也挺多的,年前一个朋友希望能让我写一个这个游戏的外挂,也出于无聊,所以去玩了一下,谁知道一玩就有点喜欢这个游戏了,当然玩归玩,东西还是要做地,当然还不能算得 ...

  7. Delphi居于HOOK钩子的Apex游戏辅助工具

    2019年新出的一款免费游戏Apex,很火:然后看到有类似与CF那样切换武器可以实现子弹自动上膛的官方bug,所以有想法写一个辅助工具(捍卫者单喷变连喷)现在是已经完成了,测试也很OK.所以,写个文档 ...

  8. QQ游戏辅助工具-大家来找碴(附源码)

    前几天看到一个朋友在QQ上玩找碴游戏,战绩实在是惨不忍睹,便想到写一个辅助工具.(难道这是程序员的职业病,什么问题都想通过编程解决?) 原理和程序都简单,有一定编程基础和基本图像处理知识的人只要有点耐 ...

  9. C++编写网页游戏辅助工具~~~~~~~

    有人肯定会问,简单游,按键精灵,C#等, 这么轻松就能写辅助,为什么还用C++? 别人写的辅助也都用过不少,简单功能模拟按键确实能做到,但是存在非常多的问题,软件缓存大,开2个号就非常卡.等等. 而且 ...

最新文章

  1. 数组按时间(字符串-Date)排序
  2. UIImageView01
  3. 6万人同时离场,竟然一点都不挤?原来用了这个神器
  4. redis在php中的应用(string篇)
  5. git 修改tag 备注_【Git】第十二章:Git高级实战技巧
  6. Redis学习-性能与优化(五)
  7. php 科学计数 位数,PHP采用超长位数字运算防止数字以科学计数法显示的实例
  8. 判断页面环境是否在小程序的webview中
  9. 如何制作扫描版的文档
  10. jQuery打印插件JQPRINT
  11. [开源]快速构建验证码
  12. [20171225]变态的windows批处理4.txt
  13. Spring MVC中使用Swagger生成API文档和完整项目示例Demo,swagger-server-api
  14. 6.形容词性物主代词用法
  15. 社群编码识别黑灰产攻击实践
  16. Java之自动装箱与自动拆箱
  17. gradle依赖管理_依赖管理
  18. 51单片机之电子钟设计
  19. python: python语法
  20. 【QGIS】导入dwg文件并导出shp文件

热门文章

  1. Windows Shell编程-第十六章.命名空间扩展
  2. IntelliJ IDEA 自动导入包 关闭重复代码提示
  3. fortran使用MKL函数库求解普通稀疏矩阵与向量的乘积
  4. winform无法屏蔽回车事件、KeyPress事件不执行问题解决
  5. JavaScript-ES5和ES6基础讲解(上)
  6. 【Linux编程】6个问题带你弄懂Linux
  7. 如何获取多线程执行结果-java
  8. 护眼台灯基本要求是什么?2022护眼灯国家级最高标准
  9. POI 3.17版本 XSSF 获取指定单元格excel合并列数
  10. ntp时间服务器——时间同步