功能实现:子弹回旋
实现基础
1. 子弹x坐标可以增长,也可以反向减少
2. 子弹具有流程
击中僵尸:子弹产生 -> 子弹飞行 -> 子弹击中僵尸 -> 僵尸掉血 -> 子弹爆炸 -> 子弹消失
未击中僵尸:子弹产生 -> 子弹飞行 -> 检查边界 -> 子弹消失
3. 子弹可以穿透
实现分析
逻辑分析
1. 首先根据子弹产生,消失标记由1变0;子弹击中,消失标记由0变1 -> 可以得到修改此处代码 0046EB2B - C6 46 50 01 - mov byte ptr [esi+50],01 为0赋值,以使子弹在击中后不消失
2. 其次,找子弹飞行相关代码,这个可以根据子弹x坐标变化找到三处(飞行时、击中时、产生时),检察飞行时的相关代码,可以得到子弹x坐标减少和增长的代码段
[Asm] 纯文本检察 复制代码0046DBD7 - D9 43 30 - fld dword ptr [ebx+30] { 子弹x坐标减少 }0046DBDA - DC 25 A0966700 - fsub qword ptr [006796A0] { (3.33) }0046DBE0 - D9 5B 30 - fstp dword ptr [ebx+30]
[Asm] 纯文本检察 复制代码0046DBE8 - D9 43 30 - fld dword ptr [ebx+30] { 子弹x坐标增长 }0046DBEB - DC 05 A0966700 - fadd qword ptr [006796A0] { (3.33) }0046DBF1 - D9 5B 30 - fstp dword ptr [ebx+30]
3. 末了,找子弹边界检查相关代码,我们可以在这里实行代码注入(其实也可以在上面代码处注入),边界代码如下,见代码分析
[Asm] 纯文本检察 复制代码0046CE9D - D9 45 30 - fld dword ptr [ebp+30] { 子弹x坐标 }0046CEA0 - DC 1D 38976700 - fcomp qword ptr [00679738] { 左边界 }0046CEA6 - DFE0 - fnstsw ax0046CEA8 - F6 C4 41 - test ah,41 { 若 子弹x坐标 >= 左边界,则跳 }0046CEAB - 0F84 96010000 - je 0046D0470046CEB1 - DB 45 10 - fild dword ptr [ebp+10]0046CEB4 - D8 45 30 - fadd dword ptr [ebp+30] { 子弹x坐标 }0046CEB7 - DC 1D 98926700 - fcomp qword ptr [00679298] { 右边界 }0046CEBD - DFE0 - fnstsw ax0046CEBF - F6 C4 05 - test ah,05 { 若 子弹x坐标 < 右边界,则跳 }0046CEC2 - 0F8B 7F010000 - jnp 0046D047
代码分析
[Asm] 纯文本检察 复制代码[ENABLE]//code from here to '[DISABLE]' will be used to enable the cheatalloc(newmem,2048)label(returnhere)label(originalcode)label(exit)// 代码逻辑:先开发一段可用空间,用来存放方向标记;然后根据(当前子弹x坐标地址 - 首颗子弹x坐标地址) / 0x94(0x94为子弹x坐标的间隔) 可以得到当前是第几颗子弹,从而取到方向标记;末了根据方向标记来决定子弹x坐标是增长还是减少,并对越过边界的子弹修改其方向标记newmem: //this is allocated memory, you have read,write,execute access//place your code herepush ecxpush ebxpush eaxpush edxxor edx,edxmov ecx,[6A9EC0]mov ecx,[ecx+768]mov ecx,[ecx+c8] // 子弹x坐标首地址lea eax,[ebx+30] // 子弹x坐标现地址sub eax,ecxmov ecx,94 // 子弹x坐标间隔(第1颗子弹与第2颗子弹)div ecx // eax:第几个, 从0开始xor edx,edx // 清零add eax,00699000 // 00699000+index, 用来存放子弹的方向标记mov ecx,eaxmov dl,[ecx] // 只存在低字节cmp edx,0pop edxpop eaxpop ebx // 临时不弹ecx, 因为ecx还有效je addxsubx: // 子弹x坐标减少fld dword ptr [ebp+30]fsub qword ptr [006796A0]fsub qword ptr [006796A0]fstp dword ptr [ebp+30]coml: // 左边界检查push eaxfild dword ptr [ebp+10]fadd dword ptr [ebp+30]fcomp qword ptr [00679298]fnstsw axtest ah,05 // 若子弹x坐标 < 0, 则跳jnp leftbpop eaxpop ecxjmp 0046CEC8leftb: // 越过左边界, 则置相反标记mov byte ptr [ecx],00pop eaxpop ecxjmp 0046CEC8addx: // 子弹x坐标增长fld dword ptr [ebp+30]fadd qword ptr [006796A0]fadd qword ptr [006796A0]fstp dword ptr [ebp+30]comr: // 右边界检查push eaxfldpifld dword ptr [ebp+30]fadd st(0),st(1)fcomp qword ptr [00679738]fnstsw axtest ah,41 // 若子弹x坐标 >= 800, 则跳je rightbpop eaxpop ecxjmp 0046CEC8rightb: // 超出右边界, 则置相反标记mov byte ptr [ecx],01pop eaxpop ecxjmp 0046CEC8originalcode://fld dword ptr [ebp+30]//fcomp qword ptr [00679738]jmp newmemexit:jmp returnhere"PlantsVsZombies.exe"+6CE9D:jmp newmemnop 4returnhere: [DISABLE]//code from here till the end of the code will be used to disable the cheatdealloc(newmem)"PlantsVsZombies.exe"+6CE9D:fld dword ptr [ebp+30]fcomp qword ptr [00679738]fnstsw axtest ah,41je 0046D047fild dword ptr [ebp+10]fadd dword ptr [ebp+30]fcomp qword ptr [00679298]fnstsw axtest ah,05jnp 0046D047//Alt: db D9 45 30 DC 1D 38 97 67 00
现实结果
末了总结
虽然代码上逻辑没啥大题目,但会产生几个bug:①下一关再开,可能植物/僵尸不会重绘 ②僵尸可以走第6行 ③某些僵尸过分重绘
到此为止,植物大战僵尸能改的都改了,可能超过子弹跟踪和子弹回旋的难度很难再有,前者为修改关键跳,后者为修改步伐逻辑
此贴可能会继承更新,只是把一些bug解决。。。。。。
end
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |