好友
阅读权限20
听众
最后登录1970-1-1
|
网上的不遇敌修改器已经有了(风灵月影大佬那是永远滴神!),这篇文章主要是讲解一下不遇敌是如何实现的,以及如何追码。对于想要学习这方面知识的同学们应该算是一个思路分享。
其实我去研究P5S的不遇敌,是想了解大概机制,因为我最终的目的,是想要在rpcs3模拟的P5上面实现不遇敌。后来发现自己太天真了,模拟器上面的追码只能用四个字来形容,丧心病狂!
所以先把P5S的不遇敌思路整理出来,肯定是比新手入门要难一点,但绝对比模拟器简单多了。
先简单讲一下思路
看下图(请叫我灵魂画手)
打个比方,程序运行就像在路上走,一条大路往下走,然后这条大路上有N多个岔路口。而遇敌的机制就像是来到一个岔路口,判定不遇敌,那么走一边;判定遇敌,那么走另一边的路。而这判定遇敌的另一边,继续往下走会触发一系列的连锁反应,比如小怪追着你跑,游戏界面的改变,等等等等之类的东西。
所以我们要做的,就是
1.先对比出遇敌和不遇敌的不同点,这个不同点也就是我们的切入点
2.通过这个切入点,一层一层的反追上去,一直追到我们想要的那个遇敌判定的岔路口
3.通过一系列骚操作,明明已经判定为遇敌,拐个弯绕道,进到不遇敌的那条路
结合P5S,我们来进一步分析
首先,P5S遇敌有个机制:只要遇敌,那么就会显示当前的警戒值,而平时则不会显示。这就是个很好的切入点,因为它满足以下条件:只有遇敌的时候触发,平时不会触发。
那么再进一步换算一下:只要进入遇敌判断,必定会读取警戒值的数值。
所以我们先找到警戒值的地址,然后右键什么访问了该地址,再勾引小怪一次(不必进入战斗,只要显示警戒值即可)。此时我们就会得到一系列的地址
我选择第二个,显示反汇编,跟踪该地址。则根据警戒值,我们得到了切入点:
game.exe+6E53B6 - 44 89 81 500F0000 - mov [rcx+00000F50],r8d
(注意这里不是随意选的,因为第一个地址以我的水平追一半追不下去了,所以弃掉重新来)
第二步,就是根据切入点反追到遇敌判定的那个关键判断,也是最繁琐的一步。
进行这一步前,我们先要思考下,如何得知是否已经到了关键判断。也就是我们得明确反追的依据是什么,我们追的究竟又是什么。
回到一开始的那张思路图,可以看到最大的依据就是:遇敌触发,不遇敌不触发
换言之,只要一段代码,它平时不运行,只有遇敌时运行,那么就说它肯定还是在遇敌的那条路上。不管它是藏在大路上,还是藏在小路的岔路里,总之一定是在遇敌的那条路上,这种情况下我们就可以继续往上追。
结合操作就是,给一段代码下断,然后去勾引小怪,如果该断点触发了,我们就可以从这段代码往上追。如果该断点没有触发,那么要么你走过头了,要么就是走错路了。这时候我们就得重新回到上一次符合“遇敌触发,不遇敌不触发”这个条件的断点,然后重新往上追。
一直到什么情况呢?
我们先思考下,通常来说,遇敌的那个关键判断是不停的、一直的触发着的,这样才能保证你碰到小怪后,立马就能进入遇敌的那条路,从而进入战斗。
所以说,我们需要以“遇敌触发,不遇敌不触发”这个条件往上追码,一直追到出现一个断点,该断点不停的触发,那么则说明我们追过头了,这时就可以依据该断点,慢慢往下追。
打个比方,根据执行顺序,我们追码追出了如下断点:
断点4:一直触发
断点3:一直触发
断点2:遇敌触发,不遇敌不触发
断点1:遇敌触发,不遇敌不触发
那么关键判断通常都在断点2和断点3之间。这时就要在这两点之间的代码,反复下断,慢慢找关键判断。
结合P5S,我们来尝试下追码。
断点1:
首先是刚刚的切入点
game.exe+6E53B6 - 44 89 81 500F0000 - mov [rcx+00000F50],r8d
在这里下断,然后去勾引小怪,得到下图
这里我们可以直接跳出这个call,或者直接点击return address里的第一个地址,返回到上一个call。
断点2:
取消上一个断点(即,取消game.exe+6E53B6处的断点)。再返回上一个call后,返回地址的上面有一个call,记录一下该call的地址。
game.exe+6E4772 - E8 819199FF - call game.exe+7D8F8
然后运行程序,快速切回游戏,操作人物后退别进战斗
对该call下断,然后去勾引小怪。
(新人不用太纠结call是啥,理解成为一大段代码就可以了。这里跳出call然后下断的操作,就相当于往上跳了一大段代码再下断。)
(想要更进一步理解的话,就相当于第一个断点(game.exe+6E53B6)是位于一段代码的中间,第二个断点(game.exe+6E4772)位于一段代码的开头,用跳出call的操作能更快的找到代码的开头在哪里)
靠近小怪后发现又触发了
断点3:
取消断点2的断点,跳出call,运行程序,切游戏后退等等操作同断点2
跳出地址的上一个call是
game.exe+6D66AB - FF 50 40 - call qword ptr [rax+40]
这个call如果你对它下断,它会不停的触发,你可能会很高兴,因为这是不是说明了找过头了,关键判断就在这个断点以下。
但是这个call有个问题,就是这是个共用代码段,而且rax的值一直在变动,导致没法追。
如果我是一个小白的话,很可能就止步于此的,但是现在我们可以不求甚解一下,直接跳出这个call,如果下一个断点很幸运的只在遇怪的时候才触发,那么我们根本就不用纠结这个call。
跳出这个call,发现下一个断点是
game.exe+82EBC8 - E8 E2A484FF - call game.exe+790AF
下断,勾引小怪
然后我们就很幸运的发现,这个call平时不触发,只在触怪时候触发
断点4:
继续跳出,我们来到断点4
game.exe+6B674D - E8 EA4F9DFF - call game.exe+8B73C
对断点4下断后,发现一直触发。根据我们的判断,遇敌判定应该在断点4和断点3之间
那我们进入这个call去看看
发现直接给我们跳到了game.exe+6BA170,要知道我们断点3的地址是game.exe+82EBC8。
这里遇到麻烦,game.exe+6BA170和game.exe+82EBC8离得太远了,唯一的解释是此call里面有jump指令到82EBC8上面,然后往下走直接ret。这种情况下jump点比较难找,因为有可能来回跳,比如A跳B,B跳C,C跳到82EBC8附近
所以只能从game.exe+6BA170这里跟踪下去,一点点耐心的往下走,遇到call指令或者jump指令就下断尝试,需要找到遇敌会触发,平时不会触发的路段
断点5:
从game.exe+6BA170往下走,到
game.exe+6BA21C - E8 3E7899FF - call game.exe+51A5F
此断点平时不触发,只有遇怪触发。那么我们需要往上追。
断点6:
从game.exe+6BA21C往上走,到
game.exe+6BA213 - E8 E7F698FF - call game.exe+498FF
此断点又是只有遇怪触发,继续往上追
断点7:
从game.exe+6BA213往上走,到
game.exe+6BA1D6 - E8 5F0B9AFF - call game.exe+5AD3A
发现该断点一直触发,往下走
关键点1:
在game.exe+6BA1D6和game.exe+6BA213之间,通过一系列繁琐的下断→勾引小怪→下断→勾引小怪,发现了关键跳
game.exe+6BA1DB - 84 C0 - test al,al
game.exe+6BA1DD - 74 66 - je game.exe+6BA245
平常的时候会直接跳到game.exe+6BA245,遇敌的时候则不跳
进一步追踪上面的test al,al,发现只有遇敌的时候rax为1,其余的时候为地址
=====
补充下顺序的指令
game.exe+6BA170 - 40 53 - push rbx(函数头)
game.exe+6BA1D6 - E8 5F0B9AFF - call game.exe+5AD3A(一直触发)
game.exe+6BA1DB - 84 C0 - test al,al(关键判断,遇敌时rax=1,其余时候为地址)
game.exe+6BA1DD - 74 66 - je game.exe+6BA245(一直触发,平时直接跳到函数尾部,遇敌时不跳)
game.exe+6BA213 - E8 E7F698FF - call game.exe+498FF(只有遇敌才弹)
game.exe+6BA21C - E8 3E7899FF - call game.exe+51A5F(只有遇敌才弹)
game.exe+6BA245 - 48 83 C4 20 - add rsp,20(函数尾部)
=====
这个关键点就很符合我们要的那个岔路口的特征:一直触发,其中一条道只有遇敌的时候触发。但是这个关键点后面的“1”告诉我们事情没有那么简单。
我们先尝试下,可以通过代码注入把je改成jmp,或者把test al,al改成xor al,al
然后我们去勾引小怪。发现还是会遇敌,唯一的区别是原本应该显示的警戒界面,现在不显示了
也就是说,这个test al,al不是遇敌的岔路口,是显示警戒界面的岔路口!
我们追了大半天追了个寂寞!!
缓一口气,重整旗鼓。
没有关系,警戒和遇敌本来就一脉相承。
那么在现在这种情况下,我们就要去追这个rax是怎么变成1的,因为通常的逻辑是:
遇敌→rax变成1→显示警戒界面
在game.exe+6BA1DB - 84 C0 - test al,al上面,有一个
game.exe+6BA1D6 - E8 5F0B9AFF - call game.exe+5AD3A
我们需要进入这个call里去,找有没有给rax赋值的指令,然后根据逻辑下断,看是否符合遇敌才触发的判断
关键点2:
进入call game.exe+5AD3A后,有个jmp指令,直接把我们带到了
game.exe+6E48F0 - 4C 8B 05 F93BDC01 - mov r8,[game.exe+24A84F0]
通过一系列不停下断的操作,查找平时不触发,遇怪触发,以及rax赋值的指令,一直往下走,直到这里
game.exe+6E49D9 - 41 83 B9 840F0000 00 - cmp dword ptr [r9+00000F84],00
发现平常的时候,[r9+00000F84]的值为0,遇敌的时候为1。而当它为1的时候,正好可以跳到mov al,01的指令,给rax赋值,完美!
那么下一步,我们就要去追踪[r9+00000F84]是哪里来的
比较幸运的是,r9在这里是不会变动的,所以我们可以直接添加地址
000002A109851298+00000F84,此地址为关键地址
切入点2:
这个关键地址就成为了我们新的切入点,我们要追查它怎么变成1的
右键→查找什么改写了该地址→勾引小怪
有两段代码
第一段代码是把关键地址变成1,第二段是把关键地址变成0
所以我们能追踪的其实只有第一条
断点8:
对第一条代码显示反汇编,然后下断
game.exe+82ED1A - FF 82 840F0000 - inc [rdx+00000F84]
平时不触发,遇怪时触发,往上追
断点9:
从game.exe+82ED1A跳出call,对返回地址上面的call进行下断
game.exe+305D08 - E8 C4DBD0FF - call game.exe+138D1
平时不触发,遇怪时触发,往上追
断点10:
跳出call后,发现下一个是
game.exe+2F23B2 - 41 FF D7 - call r15
我们效仿一下断点3的操作,先不管这个call,再往上跳
game.exe+2F0926 - E8 6B62D5FF - call game.exe+46B96
对这个call下断,然后我们发现它是一直触发的
断点11:
现在我们就遇到一个问题,断点10一直触发,call r15也一直触发,断点9只有遇怪的时候触发
那么现在我们有两种选择
1.从断点10往下追
2.从断点9往上追
因为r15明显是共用代码段,最重要的是断点9往上有一大串的代码,所以我决定用第二种方法
先返回断点9:game.exe+305D08
往上走,下断
game.exe+305C8A - 74 35 - je game.exe+305CC1
平时不触发,遇怪时触发,往上追
关键点3:
继续往上走,来到
game.exe+305C3C - 84 C0 - test al,al
game.exe+305C3E - 0F84 C9000000 - je game.exe+305D0D
通过不断的下断→勾引小怪,可以得出结论
平时的时候,必定会跳到game.exe+305D0D,只有在遇怪的时候,会继续往下走,从而来到断点11(game.exe+305C8A)
再进一步,平时的时候rax为0,遇敌的时候rax为1
=====
补充下顺序的指令
game.exe+305C3C - 84 C0 - test al,al(关键点:平时的时候rax为0,遇敌的时候rax为1)
game.exe+305C3E - 0F84 C9000000 - je game.exe+305D0D(跳到函数尾部)
game.exe+305C8A - 74 35 - je game.exe+305CC1(只有遇敌触发)
game.exe+305D08 - E8 C4DBD0FF - call game.exe+138D1(只有遇敌触发)
game.exe+305D0D - 48 8B 5C 24 78 - mov rbx,[rsp+78](函数尾部)
game.exe+305D17 - C3 - ret
=====
同样的道理,这里的关键点也很符合遇敌判断岔路的特征:一直触发,其中一条道只有遇敌的时候触发
在这里关键点这里:
game.exe+305C3C - 84 C0 - test al,al
game.exe+305C3E - 0F84 C9000000 - je game.exe+305D0D
我们通过代码注入,把 je game.exe+305CC1改成 jmp game.exe+305CC1,或者把上面的test al,al改成xor al,al
然后去勾引下小怪,发现已经不会遇敌了,完美!
至此为止,P5S的不遇敌实战已经结束了,其实中间省略了很多,就比如切入点1的选择,其实有很多,当时追了好几条,有些追一半就追不下去,只能放弃选择下一条。文章中列出的断点只是我觉得比较重要的,当然还有很多琐碎的尝试我压根就没写进去了。
这篇文章花费我很长的时间、很大的精力,希望能给想要学习不遇敌却无从下手的人一点思路。因为我当初就是完全不知道从何入手,绕了很多弯子。
总体来说P5S的不遇敌还是有点难度的,如果是纯新手可能有点晕。
最后说一下,不遇敌,或者其他的游戏修改,乃至逆向,都是需要很大的热情以及耐心。找到一个切入点,然后一层层的抽丝剥茧下去,最终达到自己的目的,其实是一件很有成就感的事情。 |
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|