首页
社区
课程
招聘
[原创]龙之谷单机版--无敌分析
发表于: 2016-7-26 16:24 10214

[原创]龙之谷单机版--无敌分析

2016-7-26 16:24
10214

关键词:龙之谷单机版;无敌;自动汇编;
作者:东京好嗨冷
无敌功能分析:
1.切入点->人物血量
在定位变量时要确定数据类型,这非常重要
血量数据类型一般为dword,float,double
先找dword
通过差异定位法,最后定位到这两个地址

修改第一个为0会导致人物死亡,故第一个地址为真实的地址
第二个地址可能是游戏中其他逻辑功能所用到的地址
分析第一个为主
2.找到扣血事件
在13EF8E0C处下访问断点,可以找到好几条操作数比较大的代码
当人物被攻击时,会有几条操作血量的代码,这里被攻击了2次,所以有2个访问数

假设自己是游戏的开发者,在编写扣血事件中,肯定要写 被攻击者.血量=被攻击者.血量-攻击者.攻击力
当然,这只是一个模型,并不代表代码就是这样的,可能其中还有一些其他的代码,比如计算护甲或者BUFF加成之类的,不管如何,最后肯定是要写入内存的
以上汇编代码中符合这条件的也只有
00659085 - 89 06  - mov [esi],eax

其周围的代码为
longzhigupc.exe+259057 - 8B CE                 - mov ecx,esi
longzhigupc.exe+259059 - FF D0                 - call eax
longzhigupc.exe+25905B - D9 5C 24 0C           - fstp dword ptr [esp+0C]
longzhigupc.exe+25905F - 8B 8E 50060000        - mov ecx,[esi+00000650]
longzhigupc.exe+259065 - 8B 51 08              - mov edx,[ecx+08]
longzhigupc.exe+259068 - DB 84 32 B00B0000     - fild dword ptr [edx+esi+00000BB0]
longzhigupc.exe+25906F - 8D B4 32 B00B0000     - lea esi,[edx+esi+00000BB0]
longzhigupc.exe+259076 - D9 44 24 0C           - fld dword ptr [esp+0C]
longzhigupc.exe+25907A - D9C0                  - fld st(0)
longzhigupc.exe+25907C - DEEA                  - fsubp st(2),st(0)
longzhigupc.exe+25907E - D9C9                  - fxch st(1)
longzhigupc.exe+259080 - E8 BBAF2300           - call longzhigupc.exe+494040
longzhigupc.exe+259085 - 89 06                 - mov [esi],eax <-此处写入内存
longzhigupc.exe+259087 - 5E                    - pop esi
longzhigupc.exe+259088 - C2 0800               - ret 0008 { 8 }  <-返回到上一层
我们只关心最重要的东西,其他的细节不必一一分析
3.修改相关逻辑 JE/JNE->JMP & nop
在上面的那一层中没有相关判断语句,故到上一层分析
上层代码:
longzhigupc.exe+2619AB - D9 5C 24 14           - fstp dword ptr [esp+14]
longzhigupc.exe+2619AF - 8B 4C 24 30           - mov ecx,[esp+30]
longzhigupc.exe+2619B3 - 74 15                 - je longzhigupc.exe+2619CA
longzhigupc.exe+2619B5 - 83 E8 01              - sub eax,01 { 1 }
longzhigupc.exe+2619B8 - 75 1E                 - jne longzhigupc.exe+2619D8
longzhigupc.exe+2619BA - 8B 86 34090000        - mov eax,[esi+00000934]
longzhigupc.exe+2619C0 - 3B 81 34090000        - cmp eax,[ecx+00000934]
longzhigupc.exe+2619C6 - 74 10                 - je longzhigupc.exe+2619D8
longzhigupc.exe+2619C8 - EB 61                 - jmp longzhigupc.exe+261A2B
longzhigupc.exe+2619CA - 8B 96 34090000        - mov edx,[esi+00000934]
longzhigupc.exe+2619D0 - 3B 91 34090000        - cmp edx,[ecx+00000934]
longzhigupc.exe+2619D6 - 74 53                 - je longzhigupc.exe+261A2B <-该跳转跳过了扣血事件,故可能可以构成无敌功能,用OD观察会直观一些
longzhigupc.exe+2619D8 - 85 C9                 - test ecx,ecx
longzhigupc.exe+2619DA - 74 1F                 - je longzhigupc.exe+2619FB
longzhigupc.exe+2619DC - 8B 44 24 2C           - mov eax,[esp+2C]
longzhigupc.exe+2619E0 - 51                    - push ecx
longzhigupc.exe+2619E1 - 8B 4C 24 2C           - mov ecx,[esp+2C]
longzhigupc.exe+2619E5 - 50                    - push eax
longzhigupc.exe+2619E6 - 51                    - push ecx
longzhigupc.exe+2619E7 - E8 5475F2FF           - call longzhigupc.exe+188F40
longzhigupc.exe+2619EC - 83 C4 0C              - add esp,0C { 12 }
longzhigupc.exe+2619EF - 84 C0                 - test al,al
longzhigupc.exe+2619F1 - 74 08                 - je longzhigupc.exe+2619FB
longzhigupc.exe+2619F3 - 8B 44 24 30           - mov eax,[esp+30]
longzhigupc.exe+2619F7 - 85 C0                 - test eax,eax
longzhigupc.exe+2619F9 - 75 04                 - jne longzhigupc.exe+2619FF
longzhigupc.exe+2619FB - 33 C0                 - xor eax,eax
longzhigupc.exe+2619FD - EB 10                 - jmp longzhigupc.exe+261A0F
longzhigupc.exe+2619FF - 8B 90 50060000        - mov edx,[eax+00000650]
longzhigupc.exe+261A05 - 8B 4A 14              - mov ecx,[edx+14]
longzhigupc.exe+261A08 - 8D 84 01 50060000     - lea eax,[ecx+eax+00000650]
longzhigupc.exe+261A0F - 8B 16                 - mov edx,[esi]
longzhigupc.exe+261A11 - 8D 8E 58080000        - lea ecx,[esi+00000858]
longzhigupc.exe+261A17 - 51                    - push ecx
longzhigupc.exe+261A18 - 50                    - push eax
longzhigupc.exe+261A19 - 8B 82 2C010000        - mov eax,[edx+0000012C]
longzhigupc.exe+261A1F - 8B CE                 - mov ecx,esi
longzhigupc.exe+261A21 - FF D0                 - call eax <-扣血事件
longzhigupc.exe+261A23 - D9 5C 24 14           - fstp dword ptr [esp+14]
longzhigupc.exe+261A27 - 8B 4C 24 30           - mov ecx,[esp+30]
longzhigupc.exe+261A2B - 8B 96 50060000        - mov edx,[esi+00000650]
longzhigupc.exe+261A31 - 8B 42 08              - mov eax,[edx+08]
longzhigupc.exe+261A34 - DB 84 30 B00B0000     - fild dword ptr [eax+esi+00000BB0]
longzhigupc.exe+261A3B - D8 1D F0879600        - fcomp dword ptr [longzhigupc.exe+5687F0] { [00000000] }
longzhigupc.exe+261A41 - DFE0                  - fnstsw ax
longzhigupc.exe+261A43 - F6 C4 41              - test ah,41 { 65 }
longzhigupc.exe+261A46 - 7A 23                 - jp longzhigupc.exe+261A6B
longzhigupc.exe+261A48 - 8B 54 24 28           - mov edx,[esp+28]

006619D6     /74 53         JE SHORT longzhig.00661A2B  
修改成
006619D6     /EB 53         JMP SHORT longzhig.00661A2B

这样就可以无敌了,但是这种构成无敌的方法有缺陷,会导致怪物也无敌,因为所有对象的扣血都经过这里,而这里没有进行对象筛选,但这个函数的上几层,游戏在编写的时候可能有分开处理人物跟怪物,即调用树可能是这样:

上图的每一个框并不代表一个层,因为游戏可能会将上面的逻辑进行层层封装,但大致的逻辑就是如此
如果说要人物无敌,可以在人物层修改相关逻辑,也可以在扣血层,进行筛选对象无敌
在人物层实现的无敌方法,可能代码会非常精简,修改某个判断即可达到目的,或者修改某个人物属性也可以实现目的,这种方法需要逆向的代码会比较多
在扣血层实现的无敌方法则需要钩子
下面介绍扣血层实现无敌的方法

longzhigupc.exe+2619CA - 8B 96 34090000        - mov edx,[esi+00000934] 被攻击者
longzhigupc.exe+2619D0 - 3B 91 34090000        - cmp edx,[ecx+00000934] 攻击者
longzhigupc.exe+2619D6 - 74 53                 - je longzhigupc.exe+261A2B

通过重复被攻击的过程,可以得知esi 跟 ecx 分别是什么对象
ESI为被攻击者的对象
ECX为攻击者的对象

我们可以在longzhigupc.exe+2619CA - 8B 96 34090000        - mov edx,[esi+00000934]
此处写个钩子,判断被攻击者是什么,如果是人物则构造跳转成立的条件
至于以什么作为判断的标志,可以是判断地址,也可以是判断上层调用地址,也可以是对象的某个属性
这里以判断地址为例,经过内存搜索可以发现longzhigupc.exe+5C5D40指向主角的对象地址
钩子模型:

CE的自动汇编代码:

alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

newmem: //this is allocated memory, you have read,write,execute access
//place your code here
mov eax,[longzhigupc.exe+5C5D40]
cmp esi,eax  //通过判断对象地址来筛选无敌对象,即只让主角无敌
jne originalcode
mov edx,1
jmp exit

originalcode:
mov edx,[esi+00000934]

exit:
jmp returnhere

"longzhigupc.exe"+2619CA:
jmp newmem
nop
returnhere:

以上的无敌方法,只可以达到被怪物攻击后,不扣血,但被攻击后还是有反应的

直接修改人物对象的934偏移处的属性可以发现,怪物攻击人是完全无反应的,以及人物吸引不了怪物的仇恨,以及人物攻击不了怪物,等等现象说明访问该属性的代码不只有扣血的地方,这里也可以用类似的方法,将一些副反应筛掉,继续深入分析可以实现傻怪等等功能


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 3
支持
分享
最新回复 (11)
雪    币: 457
活跃值: (353)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
谢谢楼主的分享,有人龙之谷。
2016-7-26 17:46
0
雪    币: 11
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢楼主分享经验,学习了
2016-7-26 20:33
0
雪    币: 6182
活跃值: (4967)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
4
分析真到位。     一图Boss会召唤小弟,通过怪物数量入手可以追到一个比较像召唤call的地方 而后发现只要boss使用技能此call就会断下,然后模拟相关参数进行调用 崩溃    请问分析思路是否正确?  望楼主指点一二。
2016-7-27 02:22
0
雪    币: 324
活跃值: (60)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
感谢楼主,请教一下什么是差异定位法
2016-7-27 10:24
0
雪    币: 405
活跃值: (1071)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
6
这个思路是可以的,如果定位到的CALL,调用崩溃,请检查ECX ESI等寄存器,看一下对象是否构造了,还有各参数是否正确,以及平栈。实在不行可以在当前call的上层来模拟call,可能参数会更加简单一些
2016-7-27 11:02
0
雪    币: 405
活跃值: (1071)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
7
内存中可能会有许多地址的值与血量恰好相等或瞬间相等,此时第一次搜索的值会有许多干扰因素,通过多次改变血量的值,来重复搜索,筛掉不符合条件的地址,最后得到准确符合条件的地址
2016-7-27 11:07
0
雪    币: 324
活跃值: (60)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
好的,多谢了
2016-7-27 11:21
0
雪    币: 6182
活跃值: (4967)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
9
已在上上层调用   但是无效果   希望有空您可以分析下
2016-7-28 02:22
0
雪    币: 433
活跃值: (1910)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
10
呵呵...
。。。。通过血量来过滤,是不是有点****
在受攻击之前,一定会判断人物是否死亡,在那里直接jmp即可.
2016-7-28 02:38
0
雪    币: 405
活跃值: (1071)
能力值: ( LV7,RANK:105 )
在线值:
发帖
回帖
粉丝
11
934偏移处的属性具体的定义是什么并不确定,但是修改人物的该处偏移确实可以达到无敌的状态,但是同时会有攻击不了怪物的副作用,你怎么能够确定游戏在编写攻击怪物的时候有没有判断人物是否死亡。我这里只是引出其中一种思路,并不代表这是唯一一种方法。我在文中也有介绍,在人物层可能会判断人物的某种属性来确定是否执行扣血事件,这里介绍的是在扣血层实现的方法。
2016-7-28 03:23
0
雪    币: 433
活跃值: (1910)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
12
还我怎么确定攻击是否要判断是否死亡...那我问你,你人物死掉的时候被怪物碰撞会发生移动 扣血等状况吗?
我好心跟你说这个层面不稳定和有副作用你不相信...写一大堆分析出来,尽管思路正确,但是的确也会有不好的地方不是么....
2016-7-28 05:17
0
游客
登录 | 注册 方可回帖
返回
//