第一篇在这里:
http://bbs.winsong.org/read-htm-tid-139961.html上一篇找到了扣钱的地方,但是那段代码复用率极高,改了之后发现出现了很多bug,比如打怪秒杀(这个bug满好的-_-~~)、掉钱都是0金钱、跑步速度都是普通(估计加速或者减速效果都无效了,猜的)、掉的箭和毒瓶都是0个、武器耐久都是0。。。这是稍微测试一下就出来的,还没有深入测试。
后来,我从编程的角度去看这个问题,可以看出来,这个是一个函数,很多地方都调用,所以,函数不能随意改的话,就在调用函数的地方改掉就好了。
回忆一下,上次找到一个地址是00C46D17,当时我们在钱的地址上下了写入中断,然后买东西的时候olly就会中断到00C46D17。这个地址是属于上文提到的函数中的一个语句,这次不用注意这些细节问题,只需要从宏观上来看。
下面开始:
打开olly,载入并运行暗黑1.10,记住还是要用窗口化,要不中断的时候olly该看不到了。
按alt+E,打开“可执行模块”窗口,找到“D2Common”模块。为什么要找这个模块呢?因为00C46D17这个地址是在这个模块中,从模块间的基地址就可以很容易看出来我们所要的地址在哪个模块。双击“D2Common”模块进去代码窗口,拖滚动条找到我们要的地址00C46D17,下中断。
去买东西,会断下来,按Ctrl+F9运行到函数结尾的return指令,再按一次F8单步执行,发现我们到函数外面了,可以看到:
00C47668 E8 A3F5FFFF call D2Common.00C46C10
00C4766D 8B43 10 mov eax,dword ptr ds:[ebx+10]
现在我们是刚从函数中执行出来,当前指令是00C4766D这一句。在00C47668这个call这里下中断;
按F9继续运行,还是中断到00C46D17了,再按Ctrl+F9到函数结尾,F8出去,看到:
00C478D8 E8 33F3FFFF call D2Common.00C46C10
00C478DD 8B47 10 mov eax,dword ptr ds:[edi+10]
不是刚才那个,说明买东西的时候还有别的动作,我们需要判断一下。在00C478D8这个call里也下中断;
再按F9继续游戏,这次没有再中断了,那么开始判断到底哪个是真的。买个东西,中断在00C47668,F9继续,有时候会突然断在00C478D8。
判断的标准是什么呢?我们上次修改就是因为函数被太多地方调用,导致改了之后其他的地方也不正常,所以现在就是做一些其他的事情(比如跑两步,杀个怪之类的),看看哪个地址是只有在买东西的时候才会中断出来,在其他事情上也中断的我们不要-_-~~
跑步的时候就可以看到,00C478DD中断了,我怀疑这个地址牵扯到精力值的计算。那么答案就出来了,00C47668经过多次测试,只在买东西的时候才中断出来。
现在已经可以进行修改了,把00C47668这个call已经上面的push都nop掉就可以了。不过现在的领空是D2Common.dll的,个人建议不要在dll文件中修改,因为可能别的地方也用到了,我们还是在主程序中修改比较合适。
那么,清除其他的中断,只留下00C47668这个,然后买东西,中断出来,按Ctrl+F9,再F8,发现还是在:
00C47668 E8 A3F5FFFF call D2Common.00C46C10
00C4766D 8B43 10 mov eax,dword ptr ds:[ebx+10]
这个估计是00C47668这个call里调用了自身,有可能是递归。这个跟咱们没关系,继续Ctrl+F9,再F8,这次是在:
6FCC8F1A E8 9B290500 call <jmp.&D2Common.#10518>
6FCC8F1F EB 5C jmp short D2Game.6FCC8F7D
观察代码窗口的标题,是D2Game的,这个就是游戏主程序了,开始修改:
6FCC8F0D E8 96290500 call <jmp.&D2Common.#10517>
6FCC8F12 EB 69 jmp short D2Game.6FCC8F7D
6FCC8F14 6A 00 push 0
6FCC8F16 53 push ebx
6FCC8F17 6A 0E push 0E
6FCC8F19 56 push esi
6FCC8F1A E8 9B290500 call <jmp.&D2Common.#10518>
6FCC8F1F EB 5C jmp short D2Game.6FCC8F7D
6FCC8F21 8BDD mov ebx,ebp
地址6FCC8F14开始的push是属于6FCC8F1A的call的参数入栈,前面的一个是call一个是jmp,明显和参数入栈没有联系。一直到6FCC8F1A,这一段都要nop掉。如果不把push指令nop掉的话,会导致栈溢出,然后程序崩溃(刚才试着改的时候就是因为没nop掉push指令导致游戏崩溃了)。修改好之后就是这样:
6FCC8F0D E8 96290500 call <jmp.&D2Common.#10517>
6FCC8F12 EB 69 jmp short D2Game.6FCC8F7D
6FCC8F14 90 nop
6FCC8F15 90 nop
6FCC8F16 90 nop
6FCC8F17 90 nop
6FCC8F18 90 nop
6FCC8F19 90 nop
6FCC8F1A 90 nop
6FCC8F1B 90 nop
6FCC8F1C 90 nop
6FCC8F1D 90 nop
6FCC8F1E 90 nop
6FCC8F1F EB 5C jmp short D2Game.6FCC8F7D
6FCC8F21 8BDD mov ebx,ebp
这样,本次游戏就可以实现买东西不花钱了,而且没有bug。
现在主要讲的是思路,以后也可能会讲一些比较使用的修改,请大家多多支持~~