![Board logo](images/default/logo_bg.jpg)
标题: OD动态分析调试实例 -- 瓦崗(WaGan.wa)绝招伤害计算修改 [打印本页]
作者:
蛇夫座 时间: 2009-12-8 20:28 标题: OD动态分析调试实例 -- 瓦崗(WaGan.wa)绝招伤害计算修改
OD动态分析调试实例 -- 瓦崗(WaGan.wa)绝招伤害计算修改
分析篇: (以修改绝招伤害计算为主线进行OLLYICE 动态分析调试的一个完整过程, 相信对新手有一定帮助)
首先猜想绝招伤害计算是对物理攻击重新计算又或者是对物理攻击伤害值进行加成
参考周瑜的《曹操传exe部分函数功能》, 获取函数功能和入口信息
0043BC4B ; 获取ECX武将对08栈武将的物理伤害, 10栈为是否实际值, 是则考虑是否命中和随机数
; 这个函数最值得注意
用OLLYICE打开WaGan.wa 文件, (文件类型下拉框中选择: 任何文件(*.*) )
在反汇编窗口 CTRL + G, 在[输入要跟随的表达式]对话框中输入: 0043BC4B
光标停在0043BC4B 一行, 信息提示面板显示:
本地调用自 00405EB4, 00438ABF, 00438EB8, 004406AB
现在要调试游戏, 要去到调用这个函数的地方下断, 再运行游戏看游戏有没有停下来
由于《瓦崗》是双进程所以对其调试要有点技巧, 按CTRL+ F2 重新开始
先对入口点设置断点:
004817E0 > $ 55 push ebp
改为:
004817E0 > CC int3
保存文件
然后设置OLLYICE为实时调试器, 点菜单的[选项] ==> [实时调试器设置] ==> [设置OLLYICE为实时调试器]
==> [附加前无需确认] ==> [完成]。
双击《瓦崗山異聞録.exe》调试器将自动捕获陷阱
光标停在入口点: 004817E0 > CC int3
双击int3 所在栏目弹出[汇编于此处: 004817E0]对话框中输入: push ebp ; 还原入口处的指令
现在就可以实时断点、单步、修改寄存器、看数据窗、看堆栈窗等操作, 可以开始调试了!!
首先读取进度进入到战场上(当时存档中的关卡是[救难临潼山 - 楂树岗之战 - (第 3回合)])
将反汇编窗口的滚动条拖到最顶
CTRL + F, 在[查找命令]对话框中输入: CALL 0043BC4B
光标停在: 00405EB4 . E8 925D0300 call 0043BC4B 一行按F2 下断点
由于先前观察共有四处调用, 再CTRL + F 回车
光标停在: 00438ABF |. E8 87310000 call 0043BC4B 一行按F2 下断点
同样CTRL + F 回车于
00438EB8 |. E8 8E2D0000 |call 0043BC4B
004406AB . E8 9BB5FFFF call 0043BC4B
两处下断点, 直到显示: 条目未找到
ALT + B 弹出[断点窗口]可以管理断点, 现如下:
Breakpoints
地址 模块 激活 反汇编 注释
00405EB4 WaGan 始终 call 0043BC4B
00438ABF WaGan 始终 call 0043BC4B
00438EB8 WaGan 始终 call 0043BC4B
004406AB WaGan 始终 call 0043BC4B
F9 运行游戏, 移动<管毅>接近敌人点[攻击], (当时存档中的敌人为[周治])
游戏停在: 004406AB . E8 9BB5FFFF call 0043BC4B
但问题出来了, 现在不管点战场那里不能响应, 为什么?
只能取消那一行的断点了, 在004406AB 一行按F2, 现按F9 运行游戏, 这时光标可以自由移动和点击了
发现没有, 当光标移动到攻击范围内的敌将身上(当时存档中的敌人为<周治>), 会显示红色一段的伤害值
看来上面的问题答案就是: 显示伤害值之前调用 0043BC4B函数来计算了
左键点击敌人, 这时光标停在: 00405EB4 . E8 925D0300 call 0043BC4B
再按F9 运行游戏, 我方武将对敌方武将产生攻击动作了
奇怪游戏这时又停在: 00405EB4 . E8 925D0300 call 0043BC4B
继续按F9 运行游戏, 这时敌方武将对我方武将产生攻击动作了
就此看来00405EB4 处就是[攻击]伤害的关键了
在反汇编窗口 CTRL + G, 在[输入要跟随的表达式]对话框中输入: 00405EB4
00405E78 . 8B4D F4 mov ecx, dword ptr [ebp-C]
00405E7B . 33D2 xor edx, edx
00405E7D . 8A51 01 mov dl, byte ptr [ecx+1]
00405E80 . 8BCA mov ecx, edx
00405E82 . 6BC9 24 imul ecx, ecx, 24
00405E85 . 81C1 502C4B00 add ecx, 004B2C50
00405E8B . E8 E0970500 call 0045F670
00405E90 . 6BC0 48 imul eax, eax, 48
00405E93 . 05 0000D600 add eax, 0D60000
00405E98 . 8945 F8 mov dword ptr [ebp-8], eax
00405E9B . 33C0 xor eax, eax
00405E9D . 3B05 042E4900 cmp eax, dword ptr [492E04]
00405EA3 . 1BC9 sbb ecx, ecx
00405EA5 . F7D9 neg ecx
00405EA7 . 51 push ecx
00405EA8 . 6A 01 push 1
00405EAA . 8B55 F8 mov edx, dword ptr [ebp-8]
00405EAD . 52 push edx
00405EAE . 8B45 F4 mov eax, dword ptr [ebp-C]
00405EB1 . 8B48 0C mov ecx, dword ptr [eax+C]
00405EB4 . E8 925D0300 call 0043BC4B
; 获取ECX武将对08栈武将的物理伤害
00405EB9 . 8B4D FC mov ecx, dword ptr [ebp-4]
00405EBC . 81E1 FF000000 and ecx, 0FF
00405EC2 . 8B55 F4 mov edx, dword ptr [ebp-C]
00405EC5 . 89848A 84000000 mov dword ptr [edx+ecx*4+84], eax ; 保存物理伤害值
读取游戏进度, 移动<管毅>接近敌人点[攻击], (当时存档中的敌人为<周治>)
光标停在: 00405EB4 . E8 925D0300 call 0043BC4B
按F8 单步步过call指令, 执行到: 00405EB9 . 8B4D FC mov ecx, dword ptr [ebp-4]
看寄存器窗:
EAX 0000001E ; 函数(0043BC4
的返回值, 等于十进制: 30 (注: 1)
注: 1. 可以OLLYICE界面下方[Command]命令行输入: 0000001E
回车后显示: HEX: 1E - DEC: 30 - ASCII:
接着F9 运行游戏, 我方武将对敌方武将产生攻击动作了, 打出30 点的伤害
这时游戏再一次暂停在: 00405EB4 . E8 925D0300 call 0043BC4B
同样按F8 单步步过call指令, 执行到: 00405EB9 . 8B4D FC mov ecx, dword ptr [ebp-4]
看寄存器窗:
EAX 00000021 ; 函数(0043BC4
的返回值, 等于十进制: 33
接着F9 运行游戏, 敌方武将对我方武将产生攻击动作了, 打出33 点的伤害
再看看反汇编指令:
00405EB4 . E8 925D0300 call 0043BC4B
00405EB9 . 8B4D FC mov ecx, dword ptr [ebp-4]
00405EBC . 81E1 FF000000 and ecx, 0FF
00405EC2 . 8B55 F4 mov edx, dword ptr [ebp-C]
00405EC5 . 89848A 84000000 mov dword ptr [edx+ecx*4+84], eax ; 保存物理攻击伤害值
哈哈, 现在已经知道物理攻击伤害值存放在那里了
再一次读取游戏进度, 移动<管毅>接近敌人点[绝招], (当时存档中的敌人为<周治>)
光标停在: 00405EB4 . E8 925D0300 call 0043BC4B
还是刚才的位置, 看来绝招伤害计算与物理伤害计算有关
按F8 单步步过call指令, 执行到: 00405EB9 . 8B4D FC mov ecx, dword ptr [ebp-4]
看寄存器窗:
EAX 0000001F ; 函数(0043BC4
的返回值, 等于十进制: 31
接着F9 运行游戏, <管毅>对敌方武将放出[苍龙过阵枪], 打出37 点的伤害
看来是对物理攻击伤害值进行加成计算了
好, 按ALT + B打开[断点窗口]删除所有断点, 并将光标停在:
00405EC5 . 89848A 84000000 mov dword ptr [edx+ecx*4+84], eax
这一行, 按F2下断点, 移动<管毅>接近敌人点[绝招], (当时存档中的敌人为<周治>)
光标停在: 00405EC5 . 89848A 84000000 mov dword ptr [edx+ecx*4+84], eax
看寄存器窗:
EAX 0000001E
ECX 00000000
EDX 004927F0 WaGan.004927F0
EBX 00000000
ESP 0022FD60
EBP 0022FD7C
ESI 00242360
EDI FFFFFFFF
EIP 00405EC5 WaGan.00405EC5
现在要算一下表达式: edx+ecx*4+84 的结果是多少
OLLYICE界面下方[Command]命令行输入: 004927F0+00000000*4+84
回车后显示: HEX: 492874 - DEC: 4794484 - ASCII: I(t
点数据窗, CTRL + G 在[输入要在数据窗口中跟随的表达式]对话框中输入: 492874
00492874 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
全部是0, 是未初始化数据?? 暂时不知道
按F7 单步步入下一条指令, 光标停在: 00405ECC . 8B45 FC mov eax, dword ptr [ebp-4]
点数据窗, CTRL + G 在[输入要在数据窗口中跟随的表达式]对话框中输入: 492874
00492874 1E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
注意前四字节的值改变为: 1E 00 00 00; 由于是机器码实质为: 00 00 00 1E, 等于十进制: 30
由于猜测是对物理攻击伤害值进行加成计算, 这样我们可以试着在00492874 处设置内存写入断点
(注: 2)
注: 2. 可以对数据或代码设置内存访问断点、内存写入断点, 还可以设置硬件断点, 但硬件断点最多
只可以设置四个(想详细了解建议看书或者看使用说明)
点数据窗的1E位置, 右键 ==> 断点 ==> 内存写入(W)
F9 运行游戏, 游戏停在: 00405F5F 89848A 84000000 mov dword ptr [edx+ecx*4+84], eax
看反汇编代码:
00405F38 8B55 FC mov edx, dword ptr [ebp-4]
00405F3B 81E2 FF000000 and edx, 0FF
00405F41 8B45 F4 mov eax, dword ptr [ebp-C]
00405F44 8B8490 84000000 mov eax, dword ptr [eax+edx*4+84] ; 刚才存放物理伤害的地方
00405F4B 6BC0 03 imul eax, eax, 3 ; 取出物伤*3后存入EAX
00405F4E 99 cdq ; EAX符号扩展至EDX
00405F4F 2BC2 sub eax, edx ; EDX貌似总为0
00405F51 D1F8 sar eax, 1 ; 算术右移1位, 符号位不变
00405F53 8B4D FC mov ecx, dword ptr [ebp-4]
00405F56 81E1 FF000000 and ecx, 0FF
00405F5C 8B55 F4 mov edx, dword ptr [ebp-C]
00405F5F 89848A 84000000 mov dword ptr [edx+ecx*4+84], eax ; 将加成后的物伤保存回原位
按F7 单步步入下一条指令, 光标停在: 00405F66 8B45 F4 mov eax, dword ptr [ebp-C]
看数据窗:
00492874 2D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 $...............
等于十进制: 45
F9继续运行游戏, <管毅>对敌方武将放出[苍龙过阵枪], 打出45 点的伤害
点数据窗的2D位置, 右键 ==> 断点 ==> 删除内存断点(M)
总结: 原绝招伤害 = 物理攻击伤害 * 3 / 2
要修改绝招伤害, 只要修改00405F4B 处开始的指令即可
现在我想修改绝招伤害计算使之与双方武力相关, 并且重新定义计算方法
首先就要获取双方武力
参考周瑜的《曹操传exe部分函数功能》, 获取函数功能和入口信息
0040709A ; 获取ECX武将的武、统、智、敏、运, 并乘2,跟据08栈值0~4
; 这个函数最值得注意
按ALT + B打开[断点窗口]删除所有断点
点反汇编窗口, CTRL + G, 在[输入要跟随的表达式]对话框中输入: 0040709A
这时光标停在: 0040709A /$ 55 push ebp
信息面板提示: 本地调用自 0041DE40, 0041DE80, 0041DEC0, 0041DF00, 0041DF40
点反汇编窗口, CTRL + G, 在[输入要跟随的表达式]对话框中输入: 0041DE40
这时光标停在: 0041DE40 |. E8 5592FEFF call 0040709A
这里是一个函数内镶调用:
0041DE30 /$ 55 push ebp
0041DE31 |. 8BEC mov ebp, esp
0041DE33 |. 51 push ecx
0041DE34 |. 894D FC mov [local.1], ecx
0041DE37 |. 8B45 08 mov eax, [arg.1]
0041DE3A |. 50 push eax ; 0C栈是什么, 接下来会分析
0041DE3B |. 6A 00 push 0 ; 跟据解释, 08栈为0时则获取武力值
0041DE3D |. 8B4D FC mov ecx, [local.1] ; ECX输入参数是什么, 接下来会分析
0041DE40 |. E8 5592FEFF call 0040709A ; 当时我没看到周瑜的这个函数, 搞到
; 从SetDlgItemInt 这个API开始跟踪..
0041DE45 |. 8BE5 mov esp, ebp
0041DE47 |. 5D pop ebp
0041DE48 \. C2 0400 retn 4
下断点于: 0041DE40 一行, 再按F9运行游戏
在战场武将<管毅>上点鼠标右键时, 游戏暂停下来, 再按F7单步步入
执行到: 0040709B |. 8BEC mov ebp, esp
看堆栈:
0022FCC8 /0022FCDC ; EBP 原EBP值
0022FCCC |0041DE45 ; EBP+4 CALL 指令返回地址, 返回到 WaGan.0041DE45
0022FCD0 |00000000 ; EBP+8 获取武力值
0022FCD4 |00000001 ; EBP+0CH
再看寄存器窗:
ECX 00D60000 ; 传入参数, 暂时不知是什么, 貌似为指针或者基地址
点数据窗, CTRL + G 在[输入要在数据窗口中跟随的表达式]对话框中输入: 00D60000
00D60000 00 10 00 00 00 00 00 00 B9 DC D2 E3 00 00 00 00 .......管毅....
00D60010 00 3B 00 47 00 44 00 3B 00 3D 00 00 88 00 00 00 .;.G.D.;.=..?..
00D60020 2A 2A 31 2D 2A 2B 00 02 00 00 00 00 06 3B 17 01 **1-*+.....;
00D60030 2F 26 02 13 FF FF FF B9 DC D2 E3 00 00 00 00 00 /&
作者:
蛇夫座 时间: 2009-12-8 20:32
修改篇:
这是上一篇获知的绝招伤害计算方法:
00405F38 8B55 FC mov edx, dword ptr [ebp-4]
00405F3B 81E2 FF000000 and edx, 0FF
00405F41 8B45 F4 mov eax, dword ptr [ebp-C]
00405F44 8B8490 84000000 mov eax, dword ptr [eax+edx*4+84] ; 刚才存放物理伤害的地方
00405F4B 6BC0 03 imul eax, eax, 3 ; 取出物伤*3后存入EAX
00405F4E 99 cdq ; EAX符号扩展至EDX
00405F4F 2BC2 sub eax, edx ; EDX貌似总为0
00405F51 D1F8 sar eax, 1 ; 算术右移1位, 符号位不变
00405F53 8B4D FC mov ecx, dword ptr [ebp-4]
00405F56 81E1 FF000000 and ecx, 0FF
00405F5C 8B55 F4 mov edx, dword ptr [ebp-C]
00405F5F 89848A 84000000 mov dword ptr [edx+ecx*4+84], eax ; 将加成后的物伤保存回原位
目标武将SAV映射 = DATA人物编号* 48H + 常量0D60000H
新计算方法: 物理攻方伤害 * 175% *(双方武力差值 * 2 + 100) / 100 (注: 4)
最大输出: 未知 (极端情况下可能到达一般物理攻击伤害约2.5 ~ 3倍,
如: 攻方武127 或以上, 被攻方武0)
最少输出: 物理攻击伤害120%
注: 4. 在物理攻击伤害175% 上下浮动,受双方武力影响, 武力越高则伤害越大, 反之伤害越少
(实际测试发现当攻方武力少于被攻方武力22 时也只能输出物理攻击伤害的 120%)
函数原型伪代码为:
<返回值: 新绝招伤害> <函数名: 新绝招伤害计算> PROTO STDCALL <参数1: 物理攻击伤害>,
<参数2: 攻击方武将DATA人物编号>, <参数3: 被攻击方武将SAV映射>
注: 5. 原来想改成 <新伤害> <函数> PROC STDCALL <物伤>, <攻SAV映射>, <被攻SAV映射>
由于00405F44 位置不足, 跳来跳去又不美观, 所以没有这样写
004D0C80 55 push ebp
004D0C81 8BEC mov ebp, esp
004D0C83 83EC 08 sub esp, 8
004D0C86 8B45 08 mov eax, dword ptr [ebp+8] ; 取出参数1 物理攻击伤害
004D0C89 B9 78000000 mov ecx, 78
004D0C8E F7E1 mul ecx ; 物理攻击伤害*120
004D0C90 B9 64000000 mov ecx, 64
004D0C95 33D2 xor edx, edx
004D0C97 F7F1 div ecx ; 物理攻击伤害*120/100
004D0C99 8945 FC mov dword ptr [ebp-4], eax
004D0C9C 8B4D 10 mov ecx, dword ptr [ebp+10] ; (函数0040709A) 参数ECX, 被攻方SAV
004D0C9F 6A 01 push 1 ; (函数0040709A) 参数2, 结果需乘2
004D0CA1 6A 00 push 0 ; (函数0040709A) 参数1, 获取武力
004D0CA3 E8 F263F3FF call 0040709A ; 获取ECX武将的武力
004D0CA8 8945 F8 mov dword ptr [ebp-8], eax
004D0CAB B9 48000000 mov ecx, 48
004D0CB0 8B45 0C mov eax, dword ptr [ebp+C] ; 取出参数2 攻击方DATA人物编号
004D0CB3 F7E1 mul ecx ; DATA人物编号乘以结构数组间隔48H
004D0CB5 05 0000D600 add eax, 0D60000 ; 加SAV映射基地址0D60000H
004D0CBA 8BC8 mov ecx, eax ; (函数0040709A) ECX参数, 攻方SAV映射
004D0CBC 6A 01 push 1
004D0CBE 6A 00 push 0
004D0CC0 E8 D563F3FF call 0040709A
004D0CC5 2B45 F8 sub eax, dword ptr [ebp-8] ; 攻方武力 - 被攻方武力
004D0CC8 83F8 CE cmp eax, -32 ; 检查差值与-50, 避免后续计算产生负数
004D0CCB 7D 05 jge short 004D0CD2 ; 若大于等于-50, 则跳转
004D0CCD 8B45 FC mov eax, dword ptr [ebp-4] ; 否则取出最少输出物理攻击伤害120%
004D0CD0 EB 25 jmp short 004D0CF7 ; 跳转至结束
004D0CD2 D1E0 shl eax, 1 ; 武力差值*2
004D0CD4 90 nop ; 预留一点再修改空间
004D0CD5 90 nop
004D0CD6 90 nop
004D0CD7 90 nop
004D0CD8 83C0 64 add eax, 64 ; 武力差值*2+100
004D0CDB 8945 F8 mov dword ptr [ebp-8], eax
004D0CDE 8B45 08 mov eax, dword ptr [ebp+8] ; 取出物理攻击伤害
004D0CE1 BA AF000000 mov edx, 0AF
004D0CE6 F7E2 mul edx ; 物理攻击伤害*175
004D0CE8 B9 64000000 mov ecx, 64
004D0CED 33D2 xor edx, edx
004D0CEF F7F1 div ecx ; 物理攻击伤害*175/100
004D0CF1 F765 F8 mul dword ptr [ebp-8] ; 物*175/100*(差*2+100)
004D0CF4 33D2 xor edx, edx
004D0CF6 F7F1 div ecx ; 物*175/100*(差*2+100)/100
004D0CF8 3B45 FC cmp eax, dword ptr [ebp-4] ; 将计算结果与物理攻击伤害120% 比较
004D0CFB ^ 72 D0 jb short 004D0CCD ; 若小于则输出物理攻击伤害120%
004D0CFD 8BE5 mov esp, ebp
004D0CFF 5D pop ebp
004D0D00 C2 0C00 retn 0C
调用处修改:
00405F44 . 8D8C90 84000000 lea ecx, dword ptr [eax+edx*4+84] ; 取[eax+edx*4+84]的偏移
00405F4B 51 push ecx ; 保护偏移量不被修改
00405F4C 8B09 mov ecx, dword ptr [ecx] ; 内存[ecx]处存放物理攻击伤害
00405F4E 8B55 F8 mov edx, dword ptr [ebp-8] ; [ebp-8]存放被攻方SAV映射
00405F51 52 push edx ; 参数3
00405F52 8B45 F4 mov eax, dword ptr [ebp-C]
00405F55 8B50 0C mov edx, dword ptr [eax+C]
00405F58 8B02 mov eax, dword ptr [edx] ; 攻击方DATA编号
00405F5A 50 push eax ; 参数2
00405F5B 51 push ecx ; 参数1
00405F5C E8 1FAD0C00 call 004D0C80 ; (新绝招伤害计算)函数
00405F61 59 pop ecx ; 弹出[eax+edx*4+84]的偏移
00405F62 8901 mov dword ptr [ecx], eax ; 保存计算后的结果
00405F64 90 nop
00405F65 90 nop
堆栈结构: 测试时的堆栈窗显示如下:
高地址 /. [ebp+10] 被攻击方SAV映射 0022FD58 00D61488
|. [ebp+C] 攻击方DATA编号 0022FD54 00000000
|. [ebp+8] 物理攻击伤害 0022FD50 00000020
|. [ebp+4] CALL 指令返回地址 0022FD4C 00405F61 WaGan.00405F61
|. [ebp] 原EBP的值 0022FD48 0022FD7C
|. [ebp-4] 存放物理攻击伤害120% 0022FD44 00000026
低地址 \. [ebp-8] 临时变量 0022FD40 00000068
作者:
蛇夫座 时间: 2009-12-8 20:34
杂项篇:
五围能力在DATA以及SAV文件是游戏中显示数值除2 存储的, 从内存中读出逻辑左移1 位再显示
喜欢单数显示, 就要先修改一下EXE, 然后再将DATA和SAV文件中将五围能力乘2, 要修改1024个
武将实在要花一段时间, 最好是写个小程序来自动实施。(这里不打算提供程序)
先看DATA.WA文件五围能力的存放:
0x018CH : B9 DC D2 E3 00 00 00 00 ; 解释为字符串 "管毅"
0x019EH : 2A ; 十进制42, 再乘以2 等于84
0x019FH : 31 ; 十进制49, 再乘以2 等于98
0x01A0H : 2D ; 十进制45, 再乘以2 等于90
0x01A1H : 2A ; 十进制42, 再乘以2 等于84
0x01A2H : 2B ; 十进制43, 再乘以2 等于86
0x01A3H : 6A 00 ; 十进制106
0x01A5H : 24 ; 十进制36
0x01A6H : 00 ; ?
0x01A7H : 01 ; 初始等级
再看SvXXd.WAS文件五围能力的存放:
0x14E0H : 3B 00 ; 十进制59, 当时存档中<管毅>攻击力为 59
0x14E2H : 47 00 ; 十进制71, 当时存档中<管毅>防御力为 71
0x14E4H : 44 00 ; 十进制68, 当时存档中<管毅>精神力为 68
0x14E6H : 3B 00 ; 十进制59, 当时存档中<管毅>爆发力为 59
0x14E8H : 3D 00 ; 十进制61, 当时存档中<管毅>士气为 61
0x14EAH : 2A ; 十进制42, 再乘以2 等于84, 当时存档中<管毅>武力为 84
0x14EBH : 31 ; 十进制49, 再乘以2 等于98, 当时存档中<管毅>统率为 98
0x14ECH : 2D ; 十进制45, 再乘以2 等于90, 当时存档中<管毅>智力为 90
0x14EDH : 2A ; 十进制42, 再乘以2 等于84, 当时存档中<管毅>敏捷为 84
0x14EEH : 2B ; 十进制43, 再乘以2 等于86, 当时存档中<管毅>运气为 86
0x14EFH : 88 00 ; 十进制136, 当时存档中<管毅>HP为 136
0x14F1H : 2A ; 十进制42, 当时存档中<管毅>MP为 42
0x14F2H : 00 ; ?
0x14F3H : 06 ; 十进制6, 当时存档中<管毅>等级为 6
0x14F4H : 3B ; 十进制59, 当时存档中<管毅>经验为 59
0x14F5H : 17 ; 十进制23, 当时存档中<管毅>装备武器《轩辕神枪》可能是它的编号
0x14F6H : 01 ; 十进制1, 当时存档中<管毅>武器《轩辕神枪》的等级为1
0x14F7H : 2F ; 十进制47, 当时存档中<管毅>武器《轩辕神枪》的经验为47
0x14F8H : 26 ; 十进制38, 当时存档中<管毅>装备防具《鱼鳞甲》可能是它的编号
0x14F9H : 02 ; 十进制2, 当时存档中<管毅>防具《鱼鳞甲》的等级为2
0x14FAH : 13 ; 十进制19, 当时存档中<管毅>防具《鱼鳞甲》的经验为19
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
注: 6. 参见《武将能力调整程序》源代码中的CAPACITY_STORAGE.inc 文件
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
调整瓦崗兵种能力档显示(参考自STAR175 的《增加一个能力档的详细改法》)
004072D4 /$ 55 push ebp
004072D5 |. 8BEC mov ebp, esp
004072D7 8B45 08 mov eax, dword ptr [ebp+8] ; 取出参数1, 未调整的显示档次
004072DA 25 FF000000 and eax, 0FF ; 高24 位清0
004072DF 08C0 or al, al ; 刷新CPU 零标志
004072E1 74 0A je short 004072ED ; 若EAX为0 则显示"E"
004072E3 2C 01 sub al, 1 ; 否则将EAX的值减1
; DATA部队属性设置为1 时显示"E"
004072E5 3C 06 cmp al, 6 ; 再比较EAX与6
004072E7 72 02 jb short 004072EB ; 若小于6 则跳转
004072E9 B0 06 mov al, 6 ; 未修正前大于6时会显示中文字符
004072EB D1E0 shl eax, 1 ; NULL 结尾的字符串
004072ED 05 70545500 add eax, 00555470 ; UNICODE字符串 "EDCBASX"
004072F2 8BE5 mov esp, ebp
004072F4 5D pop ebp
004072F5 C2 0400 retn 4
再将以下几处 00477CF7, 00477D30, 00477D69, 00477DA0, 00477DD9 的原指令:
00477CF7 |. 25 FF000000 and eax, 0FF
00477CFC |. D1E0 shl eax, 1
00477CFE |. 05 70545500 add eax, 00555470 ; UNICODE "EDCBASX"
改为:
00477CF7 50 push eax
00477CF8 E8 D7F5F8FF call 004072D4
00477CFD 90 nop
00477CFE 90 nop
00477CFF 90 nop
00477D00 90 nop
00477D01 90 nop
00477D02 90 nop
在OLLYICE 中查看输入表: CTRL + N
调用表: 右键 ==> 查找 ==> 所有模块间的调用
字符串表: 右键 ==> 查找 ==> 所有参考文本字符串
打开字符表来看看吧:
004102AC push 0048B348 ASCII "EEX"
00410F0D push 0048BB60 ASCII "Data.wa"
00411133 dd WaGan(ol.00410A2D ASCII LF,"A"
00411772 push 0048B3AC ASCII "可以吗?"
0041420E push 0048BBF8 ASCII "Xben.wa"
00417FA1 mov dword ptr [ebp-18], 0048B390 ASCII "R_xx.WAGAN"
00417FAA mov dword ptr [ebp-18], 0048B3A0 ASCII "S_xx.WAGAN"
00419506 push 0048B3F4 ASCII "WAGAN"
004752D1 push 00555058 ASCII "sge.wa"
再打开一个岱大新引擎来对比一下:
004102AC push 0048B348 ASCII "EEX"
00410F0D push 0048BB60 ASCII "DATA.E5"
00411133 dd ekd5.00410A2D ASCII LF,"A"
00411772 push 0048B3AC ASCII "可以吗?"
0041420E push 0048BBF8 ASCII "MEFF.E5"
00417FA1 mov dword ptr [ebp-18], 0048B390 ASCII "R_xx.eex"
00417FAA mov dword ptr [ebp-18], 0048B3A0 ASCII "S_xx.eex"
00419506 push 0048B3F4 ASCII "WAGAN"
004752D1 push 00555058 ASCII "TOU.dll"
找个试下吧, 点数据窗CTRL + G 在[输入要在数据窗口中跟随的表达式]对话框中输入: 00555058
00555058 73 67 65 2E 77 61 00 00 4C 4F 47 2E 61 76 69 00 sge.wa..LOG.avi.
在0055505C 处按CTRL + E, 将77 修改为6F 70 68, 如下:
00555058 73 67 65 2E 6F 70 68 00 4C 4F 47 2E 61 76 69 00 sge.oph.LOG.avi.
右键 ==> 复制到可执行文件, 此时进入游戏, 真彩头像不见了
退出游戏, 再将sge.wa 文件名改为sge.oph
再一次进入游戏, 真彩头像又再一次出现了
现在相信各位都知道如何对自己的MOD 作简单的文件名变换加\解密了。
文章较长, 提供文本下载
由于暂停上网, 提问可能无法在短期内回复, 有错处请版主代为修正, 谢谢!!
占楼, 谢谢各位!!
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
更新一下: 三楼附上《武将能力调整程序》 和源代码, 目前只支持新引擎的武将五围自动调整
若需要用于旧引擎, 可以自己修改一下结构定义和源代码。
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
[ 本帖最后由 蛇夫座 于 2009-12-13 16:43 编辑 ]
附件:
[OD动态分析调试实例 -- 瓦崗(WaGan.wa)绝招伤害计算修改]
OD动态分析调试实例 -- 瓦崗(WaGan.wa)绝招伤害计算修改.rar (2009-12-13 16:43, 10.31 K) / 该附件被下载次数 265
http://xycq.org.cn/forum/attachment.php?aid=84956
附件:
[武将能力调整程序]
武将能力调整程序.rar (2009-12-13 16:43, 3.16 K) / 该附件被下载次数 240
http://xycq.org.cn/forum/attachment.php?aid=85161
附件:
[源代码]
源代码.rar (2009-12-13 16:43, 5.88 K) / 该附件被下载次数 218
http://xycq.org.cn/forum/attachment.php?aid=85162
作者:
狂煞∑小星 时间: 2009-12-8 20:38
话说好久不见你了,老兄,这会儿又上来发帖了?支持下。
作者:
蛇夫座 时间: 2009-12-8 20:55
暂停上网了, 在外面上网好多不便。下了。。
谢谢各位!!
作者:
小小KS 时间: 2009-12-8 21:00
LZ这帖神的我都懒得看= =
作者:
godtype 时间: 2009-12-8 21:29
查找、调试的思路是对了。但是没有理解好小管的绝招,也没有查清楚相关代码的用途。
00405F38 8B55 FC mov edx, dword ptr [ebp-4]
00405F3B 81E2 FF000000 and edx, 0FF
00405F41 8B45 F4 mov eax, dword ptr [ebp-C]
00405F44 8B8490 84000000 mov eax, dword ptr [eax+edx*4+84] ; 刚才存放物理伤害的地方
00405F4B 6BC0 03 imul eax, eax, 3 ; 取出物伤*3后存入EAX
00405F4E 99 cdq ; EAX符号扩展至EDX
00405F4F 2BC2 sub eax, edx ; EDX貌似总为0
00405F51 D1F8 sar eax, 1 ; 算术右移1位, 符号位不变
00405F53 8B4D FC mov ecx, dword ptr [ebp-4]
00405F56 81E1 FF000000 and ecx, 0FF
00405F5C 8B55 F4 mov edx, dword ptr [ebp-C]
00405F5F 89848A 84000000 mov dword ptr [edx+ecx*4+84], eax ; 将加成后的物伤保存回原位
按F7 单步步入下一条指令, 光标停在: 00405F66 8B45 F4 mov eax, dword ptr [ebp-C]
看数据窗:
00492874 2D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 $...............
等于十进制: 45
F9继续运行游戏, <管毅>对敌方武将放出[苍龙过阵枪], 打出45 点的伤害
点数据窗的2D位置, 右键 ==> 断点 ==> 删除内存断点(M)
总结: 原绝招伤害 = 物理攻击伤害 * 3 / 2
要修改绝招伤害, 只要修改00405F4B 处开始的指令即可
看一下大白的这帖:
http://www.xycq.net/forum/thread-161663-1-1.html
上面引用的代码是所有引擎中都有的爆击150%伤害效果,不是对应绝招的,包括苍龙过阵枪在内的个别绝招才有爆击效果。所以如果按照LZ的改法,会连其他人的爆击也一并改掉。真正要修改绝招的伤害,还要加上绝招发动的判断测试,例如STAR的引擎里面的必杀就在好多地方都加上了这个发动的测试,但是瓦岗的就等八岁来说明了,我没有认真查看过。
欢迎光临 轩辕春秋文化论坛 (http://xycq.org.cn/forum/) |
Powered by Discuz! 5.0.0 |