吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 11979|回复: 86
收起左侧

[游戏安全] 【CE】女神异闻录5S的不遇敌实现思路以及追码过程

  [复制链接]
geleisisisi 发表于 2021-3-22 11:02
网上的不遇敌修改器已经有了(风灵月影大佬那是永远滴神!),这篇文章主要是讲解一下不遇敌是如何实现的,以及如何追码。对于想要学习这方面知识的同学们应该算是一个思路分享。
其实我去研究P5S的不遇敌,是想了解大概机制,因为我最终的目的,是想要在rpcs3模拟的P5上面实现不遇敌。后来发现自己太天真了,模拟器上面的追码只能用四个字来形容,丧心病狂!
所以先把P5S的不遇敌思路整理出来,肯定是比新手入门要难一点,但绝对比模拟器简单多了。

先简单讲一下思路
看下图(请叫我灵魂画手)
思路.png
打个比方,程序运行就像在路上走,一条大路往下走,然后这条大路上有N多个岔路口。而遇敌的机制就像是来到一个岔路口,判定不遇敌,那么走一边;判定遇敌,那么走另一边的路。而这判定遇敌的另一边,继续往下走会触发一系列的连锁反应,比如小怪追着你跑,游戏界面的改变,等等等等之类的东西。
所以我们要做的,就是
1.先对比出遇敌和不遇敌的不同点,这个不同点也就是我们的切入点
2.通过这个切入点,一层一层的反追上去,一直追到我们想要的那个遇敌判定的岔路口
3.通过一系列骚操作,明明已经判定为遇敌,拐个弯绕道,进到不遇敌的那条路

结合P5S,我们来进一步分析
首先,P5S遇敌有个机制:只要遇敌,那么就会显示当前的警戒值,而平时则不会显示。这就是个很好的切入点,因为它满足以下条件:只有遇敌的时候触发,平时不会触发。
那么再进一步换算一下:只要进入遇敌判断,必定会读取警戒值的数值。
所以我们先找到警戒值的地址,然后右键什么访问了该地址,再勾引小怪一次(不必进入战斗,只要显示警戒值即可)。此时我们就会得到一系列的地址
警戒值.PNG
我选择第二个,显示反汇编,跟踪该地址。则根据警戒值,我们得到了切入点:
game.exe+6E53B6 - 44 89 81 500F0000     - mov [rcx+00000F50],r8d
切入点.PNG
(注意这里不是随意选的,因为第一个地址以我的水平追一半追不下去了,所以弃掉重新来)

第二步,就是根据切入点反追到遇敌判定的那个关键判断,也是最繁琐的一步。
进行这一步前,我们先要思考下,如何得知是否已经到了关键判断。也就是我们得明确反追的依据是什么,我们追的究竟又是什么。
回到一开始的那张思路图,可以看到最大的依据就是:遇敌触发,不遇敌不触发
换言之,只要一段代码,它平时不运行,只有遇敌时运行,那么就说它肯定还是在遇敌的那条路上。不管它是藏在大路上,还是藏在小路的岔路里,总之一定是在遇敌的那条路上,这种情况下我们就可以继续往上追。
结合操作就是,给一段代码下断,然后去勾引小怪,如果该断点触发了,我们就可以从这段代码往上追。如果该断点没有触发,那么要么你走过头了,要么就是走错路了。这时候我们就得重新回到上一次符合“遇敌触发,不遇敌不触发”这个条件的断点,然后重新往上追。
一直到什么情况呢?
我们先思考下,通常来说,遇敌的那个关键判断是不停的、一直的触发着的,这样才能保证你碰到小怪后,立马就能进入遇敌的那条路,从而进入战斗。
所以说,我们需要以“遇敌触发,不遇敌不触发”这个条件往上追码,一直追到出现一个断点,该断点不停的触发,那么则说明我们追过头了,这时就可以依据该断点,慢慢往下追。
打个比方,根据执行顺序,我们追码追出了如下断点:
断点4:一直触发
断点3:一直触发
断点2:遇敌触发,不遇敌不触发
断点1:遇敌触发,不遇敌不触发
那么关键判断通常都在断点2和断点3之间。这时就要在这两点之间的代码,反复下断,慢慢找关键判断。

结合P5S,我们来尝试下追码。
断点1:
首先是刚刚的切入点
game.exe+6E53B6 - 44 89 81 500F0000     - mov [rcx+00000F50],r8d
在这里下断,然后去勾引小怪,得到下图
断点1.PNG
这里我们可以直接跳出这个call,或者直接点击return address里的第一个地址,返回到上一个call。

断点2:
取消上一个断点(即,取消game.exe+6E53B6处的断点)。再返回上一个call后,返回地址的上面有一个call,记录一下该call的地址。
game.exe+6E4772 - E8 819199FF           - call game.exe+7D8F8
然后运行程序,快速切回游戏,操作人物后退别进战斗
断点2.PNG
对该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]
call40.PNG
这个call如果你对它下断,它会不停的触发,你可能会很高兴,因为这是不是说明了找过头了,关键判断就在这个断点以下。
但是这个call有个问题,就是这是个共用代码段,而且rax的值一直在变动,导致没法追。
如果我是一个小白的话,很可能就止步于此的,但是现在我们可以不求甚解一下,直接跳出这个call,如果下一个断点很幸运的只在遇怪的时候才触发,那么我们根本就不用纠结这个call。
跳出这个call,发现下一个断点是
game.exe+82EBC8 - E8 E2A484FF           - call game.exe+790AF
断点3.PNG
下断,勾引小怪
然后我们就很幸运的发现,这个call平时不触发,只在触怪时候触发

断点4:
继续跳出,我们来到断点4
game.exe+6B674D - E8 EA4F9DFF           - call game.exe+8B73C
断点4.PNG
对断点4下断后,发现一直触发。根据我们的判断,遇敌判定应该在断点4和断点3之间
那我们进入这个call去看看
call8B73C1.PNG call8B73C2.PNG
发现直接给我们跳到了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
断点5.PNG
此断点平时不触发,只有遇怪触发。那么我们需要往上追。

断点6:
从game.exe+6BA21C往上走,到
game.exe+6BA213 - E8 E7F698FF           - call game.exe+498FF
断点6.PNG
此断点又是只有遇怪触发,继续往上追

断点7:
从game.exe+6BA213往上走,到
game.exe+6BA1D6 - E8 5F0B9AFF           - call game.exe+5AD3A
断点7.PNG
发现该断点一直触发,往下走

关键点1:
在game.exe+6BA1D6和game.exe+6BA213之间,通过一系列繁琐的下断→勾引小怪→下断→勾引小怪,发现了关键跳
game.exe+6BA1DB - 84 C0                 - test al,al
game.exe+6BA1DD - 74 66                 - je game.exe+6BA245
关键点1.PNG
平常的时候会直接跳到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]
call5AD3A.PNG
通过一系列不停下断的操作,查找平时不触发,遇怪触发,以及rax赋值的指令,一直往下走,直到这里
game.exe+6E49D9 - 41 83 B9 840F0000 00  - cmp dword ptr [r9+00000F84],00
关键点2.PNG
发现平常的时候,[r9+00000F84]的值为0,遇敌的时候为1。而当它为1的时候,正好可以跳到mov al,01的指令,给rax赋值,完美!
那么下一步,我们就要去追踪[r9+00000F84]是哪里来的
比较幸运的是,r9在这里是不会变动的,所以我们可以直接添加地址
000002A109851298+00000F84,此地址为关键地址
关键地址.PNG

切入点2:
这个关键地址就成为了我们新的切入点,我们要追查它怎么变成1的
右键→查找什么改写了该地址→勾引小怪
切入点2.PNG
有两段代码
第一段代码是把关键地址变成1,第二段是把关键地址变成0
所以我们能追踪的其实只有第一条

断点8:
对第一条代码显示反汇编,然后下断
game.exe+82ED1A - FF 82 840F0000        - inc [rdx+00000F84]
断点8.PNG
平时不触发,遇怪时触发,往上追

断点9:
从game.exe+82ED1A跳出call,对返回地址上面的call进行下断
game.exe+305D08 - E8 C4DBD0FF           - call game.exe+138D1
断点9.PNG
平时不触发,遇怪时触发,往上追

断点10:
跳出call后,发现下一个是
game.exe+2F23B2 - 41 FF D7              - call r15
call r15.PNG
我们效仿一下断点3的操作,先不管这个call,再往上跳
game.exe+2F0926 - E8 6B62D5FF           - call game.exe+46B96
断点10.PNG
对这个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
断点11.PNG
平时不触发,遇怪时触发,往上追

关键点3:
继续往上走,来到
game.exe+305C3C - 84 C0                 - test al,al
game.exe+305C3E - 0F84 C9000000         - je game.exe+305D0D
关键点3.PNG
通过不断的下断→勾引小怪,可以得出结论
平时的时候,必定会跳到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的不遇敌还是有点难度的,如果是纯新手可能有点晕。
最后说一下,不遇敌,或者其他的游戏修改,乃至逆向,都是需要很大的热情以及耐心。找到一个切入点,然后一层层的抽丝剥茧下去,最终达到自己的目的,其实是一件很有成就感的事情。

免费评分

参与人数 27威望 +1 吾爱币 +40 热心值 +23 收起 理由
烦躁的兔子 + 1 + 1 我很赞同!
史上最渣 + 1 + 1 谢谢@Thanks!
S11ence + 1 用心讨论,共获提升!
庆少 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
posheng + 1 + 1 感谢您的详细指导~
xrryz + 1 + 1 谢谢@Thanks!
瑜槿轩 + 1 + 1 热心回复!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
幽幽洛 + 1 谢谢@Thanks!
潘志豪 + 1 + 1 用心讨论,共获提升!
muyu1314520 + 1 我很赞同!
LoveMiku233 + 1 + 1 我很赞同!
asd5478 + 1 + 1 感谢分享!
netspirit + 1 谢谢@Thanks!
bugof52pj + 1 + 1 谢谢@Thanks!
jjdisco + 1 用心讨论,共获提升!
Dxx9527 + 1 + 1 我很赞同!
ladiosfei + 1 + 1 我很赞同!
Waik + 1 我很赞同!
pglcsu + 1 谢谢@Thanks!
tyeshablanco + 1 谢谢@Thanks!
my_lift + 1 感谢大佬发布原创作品,吾爱破解论坛因你更精彩!
天天go + 1 谢谢@Thanks!
谷幽兰 + 1 + 1 用心讨论,共获提升!
koitatouko + 1 + 1 我很赞同!
lyl610abc + 1 + 1 我很赞同!
fanvalen + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

du.fan 发表于 2021-3-23 18:49
geleisisisi 发表于 2021-3-23 15:26
据我所知,OD并不支持64位的软件调试。
我个人的话是CE用的比较顺手
但是由于OD和X64DBG我用的不多,很 ...

跟一些复杂的数据结构的时候,比如链表结构、二叉树结构的时候

od一般逆向的比较准确

ce数据结构可能体现的不明显吧

od x64 有很多魔改啦
 楼主| geleisisisi 发表于 2021-3-23 15:26
du.fan 发表于 2021-3-22 16:47
为啥不用od下断点呢?

据我所知,OD并不支持64位的软件调试。
我个人的话是CE用的比较顺手
但是由于OD和X64DBG我用的不多,很想知道这两款软件比起CE来有哪些先进的功能
简简单单。 发表于 2021-3-22 11:16
xscbelieve 发表于 2021-3-22 11:33
至今还没有学会破解
paullan7410 发表于 2021-3-22 11:48
楼主写的十分详细,跟着楼主的思路走学到了不少东西,谢谢分享。
c00144 发表于 2021-3-22 12:22
写的十分详细,感谢分享.
asm848 发表于 2021-3-22 12:59
楼主辛苦了,谢谢
俺是大绅士 发表于 2021-3-22 13:16
厉害了,我的哥
stefankuok 发表于 2021-3-22 13:26
用心讨论,共获提升!
bisong1988 发表于 2021-3-22 13:44
虽然看不懂,但很厉害的样子
wildfire_810 发表于 2021-3-22 14:00
你这个又有大局观,又有具体细节。很厉害了。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-21 18:46

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表