外挂逆向《某涯明月刀》BUFF及技能预判

Posted douluo998

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了外挂逆向《某涯明月刀》BUFF及技能预判相关的知识,希望对你有一定的参考价值。

为了提高游戏的可玩性,也为了提高外挂制作的难度,很多游戏对BOSS的技能伤害都设计的特别高,为了达到及时躲避的效果,我们需要对技能做预判。预判的方式有很多,比如通过收包的方式,这种方式判断的速度最快,但是代码写起来比较复杂,HOOK收包时也往往会被检测导致封号或崩溃。另一种方式就是在释放技能时进行遍历,很多游戏会加技能释放的状态和人物本身的BOSS存放在一起,比如《天涯明月刀》,《梦三国》等。接下来我们以天涯明月刀为例来分析下技能的预判。

首先我们通过搜索BUFF状态的名字,来找到技能状态库,这里要注意的是游戏内的汉字大多是以UTF-8编码的。过程很简单,我们就不去分析了,直接给公式。

[BUFF基地址]+1144]+64 BUFF名字遍历起始地址

[[BUFF基地址]+1144]+68 BUFF名字遍历数组成员数量

[[BUFF基地址]+1144]+5C BUFF名字遍历对象数量

[[[[BUFF基地址]+1144]+64]+n*4]+0 BUFFID

[[[[BUFF基地址]+1144]+64]+n*4]+4 BUFF对象

[[[[BUFF基地址]+1144]+64]+n*4]+8 BUFF链表

[[[[[BUFF基地址]+1144]+54]+n*4]+4]+0 BUFFID

[[[[[[BUFF基地址]+1144]+54]+n*4]+4]+4]+0 BUFF名字

我们得到一个数组套链表的结构,这个结构被广泛的应用于这款游戏当中。

接下来我们去分析NPC和角色当前所有的BUFF和技能状态。我们接着之前的BUFF库的代码继续分析,取状态名字的函数传入了一个技能ID的参数,当我们访问角色身上的BUFF时会断下(如图)

向上分析技能,我们发现追到了一个结构体数组,而我们角色当前BUFF状态和即将释放技能时的预备动作,都会存放在这个数组里,每一个动作都对应一个不同的ID。继续向上分析,发现这个数组是在角色对象下存放的(如图)

通过代码输出,我们发现这个数组也同样适用于怪物和其他玩家。公式如下

[NPC或角色对象]+304 BUFF数组起始地址

[NPC或角色对象]+308 BUFF数组结束地址

[[NPC或角色对象]+304]+80*n+0 BUFFID 技能预判ID

这个数组中出了ID,还有很多的未知数据,很有可能是当前释放技能的范围,目标,朝向,形状等信息,这需要通过大量的对比和分析来判断。

这样我们就达到了一个对技能的预判效果,通过遍历到BOSS的不同的技能名字采取不同的躲避方式即可

合金弹头 逆向分析与外挂制作报告内联HOOK

 

一、工具及游戏介绍

使用工具:Ollydbg,PEID,Cheat Engine

实现功能:玩家无敌

目标:找到全局数据,或关键代码块。

 

游戏版本:合金弹头1-5代珍藏版

技术分享图片

 

二、逆向逻辑

1、初始判断【CE数据】

通过游戏试玩,发现玩家是一次性死亡,但在复活开始阶段,有闪光的无敌状态。

可利用这点,实现无敌。

刚开始先通过CE找到类似秒数的 复活状态信息数据,并找到修改数据的代码段。

 

技术分享图片

2、OD调试【OD追踪关键代码块】

在秒数数据下硬件写入断点,得到修改数据的代码。

 

技术分享图片

 

回溯跟踪分析,分析DL的来源,追踪关键代码块。

在函数入口处下条件断点。

 

技术分享图片

 

往上分析,发现削减数据,DL来源于【EBX*4+0x5FE0A8】,

经多次验证,EBX == 0x0,所以数据来源0x5FE0A8

 

技术分享图片

 

此地址数据一直在变化,下硬件写入断点,得到相关计算的功能代码。

 

技术分享图片

 

跟踪分析,发现此函数返回未削减的数值,并准备调用削减功能代码。

 

技术分享图片

 

进入分析。

发现函数从固定地址0x711470 + EAX偏移(模块内),取出中间堆数据地址(堆内)。

再通过 中间堆数据地址 + ECX偏移,得到放在 堆中的无敌状态数值。

 

技术分享图片

技术分享图片

技术分享图片

技术分享图片

 

通过得到无敌状态数值,调用削减功能代码,进行削减后,

再发往0x5FE0A8处,再赋回堆0x39C60CB处。

3、分析和实现

所以,此处可对 EAX偏移,ECX偏移,进行判断。

准确锁定状态数据,并进行Hook代码。

实现内联HOOK,完成无敌。

 

技术分享图片

技术分享图片

 

三、总结:

1、总体逻辑

﹒﹒﹒﹒﹒﹒﹒﹒﹒Hook中间代码实现 ↓ 实现数据恒定

﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒(取出修改)

﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒↓↓↓--------------↑↑↑

固定数据------------>>>中间数据--------->>>中间堆数据

(复活初始赋值)(多种数据临时存放点) ﹒(无敌状态数据)

﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒(0x5FE0A8) ﹒﹒﹒﹒﹒(0x39C60CB)

﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒↓↓↓----------------↑↑↑

﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒(修改存放)

2、Hook Opcode

83 F1 01 3D 70 1C 71 00 75 0B 81 F9 84 04 10 00 75 03 B0 99 C3 8A 04 11 C3

3、功能代码

//找到进程

        HANDLE ReProcess = 0;

        PROCESSENTRY32 pe32;

        pe32.dwSize = sizeof(pe32);

        HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

        BOOL bMore = ::Process32First(hProcessSnap, &pe32);

 

        //多字节转宽字节

        WCHAR proname[20] = {};

        MultiByteToWideChar(CP_ACP, MB_COMPOSITE, "WinKawaks.exe", 20, proname, 20);

 

        while (bMore)

        {

            if (wcscmp(pe32.szExeFile, proname) == 0)

            {

                ReProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);

                printf("找到了\\n");

                break;

            }

            bMore = Process32Next(hProcessSnap, &pe32);

        }

 

        HANDLE process;

        process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 0xeb4);

 

        //Hook 地点

        DWORD attibute;

 

        VirtualProtectEx(ReProcess, (LPVOID)0x00444779, 0x6, PAGE_READWRITE, &attibute);

 

        //jmp HookOpcode

        BYTE OPecode1[] = { \\xE9, \\xB8, \\xC2, \\x07, \\x00, \\x90 };

        DWORD num;

 

        WriteProcessMemory(ReProcess, (LPVOID)0x00444779, OPecode1, 6, &num);

 

        VirtualProtectEx(ReProcess, (LPVOID)0x00444779, 0x6, attibute, &attibute);

 

        //Hook Opcode

        VirtualProtectEx(ReProcess, (LPVOID)0x004c0a36, 0x25, PAGE_READWRITE, &attibute);

 

        //HookOpcode

        BYTE OPecode2[] = { \\x83, \\xF1, \\x01, \\x3D, \\x70, \\x1C,

            \\x71, \\x00, \\x75, \\x0B, \\x81, \\xF9,

            \\x84, \\x04, \\x10, \\x00, \\x75, \\x03,

            \\xB0, \\x99, \\xC3, \\x8A, \\x04, \\x11, \\xC3 };

 

        WriteProcessMemory(ReProcess, (LPVOID)0x004c0a36, OPecode2, 25, &num);

 

        VirtualProtectEx(ReProcess, (LPVOID)0x004c0a36, 0x25, attibute, &attibute);

        CloseHandle(ReProcess); 

 

四、效果

完成无敌:

技术分享图片

 

个人总结:

虽然只是个小外挂,但找出了类似储存游戏数据的地方。虽然不太确定,但往这条路分析下去,以此达到其它功能,潜力还是蛮大的。

附件:

合金弹头外挂.exe

 

KID

以上是关于外挂逆向《某涯明月刀》BUFF及技能预判的主要内容,如果未能解决你的问题,请参考以下文章

天涯明月刀游戏引擎是什么 游戏引擎解读

合金弹头 逆向分析与外挂制作报告内联HOOK

学习逆向知识之用于游戏外挂的实现.第三讲,通过游戏外挂.分析红色警戒金钱基址.以及确定基址小技巧.

好课分享:易道云 C语言C++零基础到大神全栈课程(逆向游戏开发架构反外挂) 百度云

天涯明月刀剑荡八荒S2赛季落幕 四强出炉

逆向知识之CS1.6辅助/外挂专题.1.实现CS1.6主武器副武器无限子弹