关键词:龙之谷单机版;无敌;自动汇编;
作者:东京好嗨冷
无敌功能分析:
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直播授课
上传的附件: