标题: OD动态分析调试实例 -- 瓦崗(WaGan.wa)绝招伤害计算修改
性别:男-离线 蛇夫座

Rank: 3Rank: 3Rank: 3
组别 士兵
级别 仁勇校尉
功绩 2
帖子 200
编号 293516
注册 2008-10-5
来自 永不言弃!
家族 轩辕学院


发表于 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 22:39 +60 教程帖奖励


顶部
性别:男-离线 蛇夫座

Rank: 3Rank: 3Rank: 3
组别 士兵
级别 仁勇校尉
功绩 2
帖子 200
编号 293516
注册 2008-10-5
来自 永不言弃!
家族 轩辕学院


发表于 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


顶部
性别:男-离线 蛇夫座

Rank: 3Rank: 3Rank: 3
组别 士兵
级别 仁勇校尉
功绩 2
帖子 200
编号 293516
注册 2008-10-5
来自 永不言弃!
家族 轩辕学院


发表于 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


附件: [武将能力调整程序] 武将能力调整程序.rar (2009-12-13 16:43, 3.16 K)
该附件被下载次数 240


附件: [源代码] 源代码.rar (2009-12-13 16:43, 5.88 K)
该附件被下载次数 218
顶部
性别:男-离线 狂煞∑小星
(Myth阿杨)

Rank: 5Rank: 5
组别 士兵
级别 破虏将军
功绩 7
帖子 720
编号 308223
注册 2009-1-29
家族 轩辕学院


发表于 2009-12-8 20:38 资料 个人空间 短消息 只看该作者 QQ
话说好久不见你了,老兄,这会儿又上来发帖了?支持下。
顶部
性别:男-离线 蛇夫座

Rank: 3Rank: 3Rank: 3
组别 士兵
级别 仁勇校尉
功绩 2
帖子 200
编号 293516
注册 2008-10-5
来自 永不言弃!
家族 轩辕学院


发表于 2009-12-8 20:55 资料 短消息 只看该作者
暂停上网了, 在外面上网好多不便。下了。。




                                            谢谢各位!!
顶部
性别:男-离线 小小KS

Rank: 7Rank: 7Rank: 7Rank: 7
组别 校尉
级别 右将军
功绩 11
帖子 1063
编号 294403
注册 2008-10-11


发表于 2009-12-8 21:00 资料 文集 短消息 只看该作者 QQ
LZ这帖神的我都懒得看= =
顶部
性别:男-离线 godtype
(毅)

刘国公
广南东路经略使
枢密直学士
★★★★★★★★★★★★
★★★

Rank: 24Rank: 24Rank: 24
柱国(正二品) 轩辕春秋年度最佳(轩辕工作室)
组别 经略使
级别 卫将军
好贴 1
功绩 1314
帖子 6207
编号 111321
注册 2007-2-18
来自 我家
家族 轩辕学院


发表于 2009-12-8 21:29 资料 个人空间 短消息 只看该作者
查找、调试的思路是对了。但是没有理解好小管的绝招,也没有查清楚相关代码的用途。

QUOTE:

       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的引擎里面的必杀就在好多地方都加上了这个发动的测试,但是瓦岗的就等八岁来说明了,我没有认真查看过。
顶部

正在浏览此帖的会员 - 共 1 人在线




当前时区 GMT+8, 现在时间是 2025-2-13 03:55
京ICP备2023018092号 轩辕春秋 2003-2023 www.xycq.org.cn

Powered by Discuz! 5.0.0 2001-2006 Comsenz Inc.
Processed in 0.021658 second(s), 10 queries , Gzip enabled

清除 Cookies - 联系我们 - 轩辕春秋 - Archiver - WAP