昨天在楼上和
@卡_密_萨_玛 讨论发现无双战略版在xp上运行会出错win7反而可以的诡异问题,今天觉得不弄清楚具体原因始终不舒服。如果只是像以前那样以为完全不能用倒也不会去理会,现在这个现象实在是很少见很令人费解。然后忍不住去查看了错误报告,这才弄明白是怎么一回事。

如上图,报告里给出了最后运行出错的地方:41D511
查看那部分代码,完好无损,补丁动都没有动过这里:
push ebp
mov ebp,esp
sub esp,08
xor ecx,ecx
mov [ebp-04],ecx
jmp start.bat+1D4EB
inc byte ptr [ebp-04]
cmp byte ptr [ebp-04],0F //15
jnl start.bat+1D524
mov cl,[ebp-04]
call start.bat+D1110
mov [ebp-08],ecx
mov eax,[ecx]
mov ecx,[ebp-04]
add ecx,64
call start.bat+D1136
mov ecx,[ebp-08]
call start.bat+D10D0
mov eax,[ecx+1C] //Crash!!!
mov ecx,[ebp-04]
add ecx,00000083
call start.bat+D1136
jmp start.bat+1D4E8
mov esp,ebp
pop ebp
ret
从【cmp byte ptr [ebp-04],0F //15】 很容易就能联想到,这是对我军战场人物的循环操作。再结合出错时机是在进入战场瞬间,可以推断出这个应该是开局后对我军出场人物的数据进行某些初始化。
在【mov eax,[ecx+1C]】出错的地方设置断点,如果出场有三人,那么就会在第四次调用的时候由于引用了无效内存地址而报错。出场只有三人,按我的理解应该只循环三次在第四次就跳出循环体结束才对,这样就能避开无效内存的问题。为什么win7就不会出错或者原程序在xp下也没问题呢?这个按我的理解是侥幸,只要刚好那个指向的地址能读取就没问题,可是碰到未初始化的内存段就不行了。
补丁共享文件夹里添加了脚本【SpecialFix160215.txt】,是按我的理解对该程序做出的修复。由于该函数代码可修改空间实在有限,我也只能是迫不得已将【cmp byte ptr [ebp-04],0F //15】这句判断去掉,从而换取判断eax是否等于FFFF的代码(祥见下段)。如果哪位有更好的改法还请不吝赐教。
push ebp
mov ebp,esp
sub esp,08
xor ecx,ecx
mov [ebp-04],ecx
jmp start.bat+1D4EB
inc byte ptr [ebp-04]
mov cl,[ebp-04]
call start.bat+D1110
mov [ebp-08],ecx
mov eax,[ecx]
cmp ax,FFFF//Invalid Index
je start.bat+1D524
mov ecx,[ebp-04]
add ecx,64
call start.bat+D1136
mov ecx,[ebp-08]
call start.bat+D10D0
mov eax,[ecx+1C]
mov ecx,[ebp-04]
add ecx,00000083
call start.bat+D1136
jmp start.bat+1D4E8
mov esp,ebp
pop ebp
ret
这里说了那么多,主要是想给个例子,感兴趣的朋友以后遇到类似出错的时候可以尝试一下自己来解决。因为即使这样修改后在xp下音乐还是出不来,要正常播放音乐的话还得手动定位播放函数地址,所以要玩还是建议大家在win7+下玩。
最后测试时候还发现双暴率无法显示,顺便查了查,以下给出修正地址,自己在【显示双击暴击率】项那里设置一下就可以了:
【计算双击函数地址】004D2D3D
【计算暴击函数地址】004D3557