最近有朋友分享了安卓上的playstation模拟器,我又开始玩起ps上的怪物农场2.这是一个怪物养成类游戏,玩家要养育,训练怪物,并参加比赛.

游戏制作公司是Tecmo,游戏中怪物的模型贴图等非常优秀,合体系统也是我见过最好的(从某种角度上看,完爆真女神转生).

该游戏有个特色系统是,可以通过ps的换盘机制,从光盘生成不同的怪物,甚至生成稀有的怪物.因此玩家需要收集各种各样的光盘(模拟器可以使用光盘镜像)来生成怪物.

虽然我10年前就开始玩这个游戏,断断续续玩了很久,还是有很多稀有的怪物收集不到.因此早就想通过破解来收集所有的怪物.

那么就开始填这个10年前的坑吧.

这里记录下修改的过程.

首先在网上瞎找,找到no$psx模拟器\调试器,试跑了下,感觉不太好用.

之后换了PSX,感觉似乎好些,运行和调试都没问题,但是完全不知道要怎么入手.

汇编是MIPS的,还不熟悉,内存也没法搜索.试着随意调试了下,暂时不知道要如何找到生成怪物的那个函数.

于是继续在网上寻找资料,找到了slowbeef汉化Policenauts的日志.

slowbeef做的第一步是找到游戏中的文本,修改文本,并在游戏界面中可以观察到变化.文本通常是破解的切入点之一.

所以这也是我要做的第一步,找到游戏中的某个文本,修改它.

游戏开始时,会让玩家输入自己的名字,就决定先在内存中找到自己的名字好了.

只能输8位,所以我只能输入unigauld啦.

选择确定后,后续的对话中出现了我的名字.

slowbeef在他的文章中介绍了一种方法,叫Statesave hacking,就是利用模拟器的Quick Save(快照)功能来分析内存.

这种方式基本上等同于内存Dump.模拟器在保存快照时,会把当前的内存数据保存到文件.在读取快照时,会从文件恢复内存数据.处理器当前的状态应该也有保存(我的猜测).

我们使用Quick Save 1保存,在模拟器的saves目录下生成quicksave_SLPS_019.06_1.psv这个文件.

使用这种方法的好处是,可以修改快照内存,之后直接使用Quick Load,可以直接使改动的内容生效.

OK,既然"unigauld"这样的字符串被显示在了屏幕上,那在内存中肯定也能找到.

使用二进制编辑器010Editor,搜索"unigauld",结果什么都搜不到.将编码调成日文,搜索"さん",也是一样无果.

试着搜索字符串,查找出一些字符串,但是显示在对话中的字符串根本找不到.

slowbeef的文章中介绍了一种方法,叫relative search,即不直接搜索"unigauld",而是根据相邻字符间的差距来查找.

正常ASCII的a是0x61,b是0x62,c是0x63,但是很可能游戏中对字符串编码做了处理,例如存储时,每个字符都增加0x10,这样abc就变成了0x71,0x72,0x73.直接使用ASCII码查找自然没办法找到.

恩,所以需要写个脚本来做relative search.虽然c++比较熟,但是人生苦短,我还是决定用python.简单撸了个脚本,开始搜索,结果还是搜索不到.

难不成使用了其他方式对字符串进行加密,连字符间的相对顺序都变了?不死心继续搜索,无意中发现了下面这个字符表,和取名字时的那个很像.

这里右边使用的是shift-jis编码.仔细观察发现,u是95 82,n是8E 82.试着使用这里的编码搜索,还是无果.

感觉暂时是没法找到了,肯定是经过什么奇怪的加密处理了.于是洗澡去了,洗完突然灵光一现,想到可以试试用relative search以2个字节为单位搜索.

于是改改脚本,很土但是能用.

def relative_search(filepath,word):f = open(filepath,"rb")f.seek(0,2)size = f.tell()print(ord('n')-ord('u'))for i in range(size-20):f.seek(i,0)s = f.read(18)if ord(s[0])-ord(s[2]) == ord('u')-ord('n') \and ord(s[2])-ord(s[4]) == ord('n')-ord('i') \and ord(s[4])-ord(s[6]) == ord('i')-ord('g') \and ord(s[6])-ord(s[8]) == ord('g')-ord('a') \and ord(s[8])-ord(s[10]) == ord('a')-ord('u') \and ord(s[10])-ord(s[12]) == ord('u')-ord('l') \and ord(s[12])-ord(s[14]) == ord('l')-ord('d') :print(s[0],s[2],s[4],s[8],s[10],s[12],s[14],s[16],i)if s[0] < s[1]:print("ok")else:print("false")relative_search("quicksave_SLPS_019.06_1.psv","uni")
input()

果然找到了3处地方.

其中485936(0x76A30)对应了如下数据.

619019(0x9720B)对应了如下数据.

2094970(0x1FF77A)对应了如下数据.

看起来前两个字符串到FF 00就结束了,也就是只有"unigauld".而最后一个字符串比较长,看不出到哪结束,应该是界面上对话使用的字符串.

试着将第一个字节修改成2F,保存文件.

使用模拟器的Quick load 1加载快照文件.发现改动生效了,u变成了v.

接下来试着改改unigauld后面的字符,这里是"さん".

改完还是保存,使用Quick load 1加载快照.发现"さん"变成了”しが”.

到这里,第一步算是完成了.

后续可以做的事情,

尝试找到读取CDROM的相关函数,如果知道读取了什么数据,那就可以伪造这部分数据,进而控制生成的怪物.

尝试找到生成怪物的函数及怪物ID的参数,这样就能控制最后生成的怪物了.

弄清这里的字符串编码规则,可以考虑写脚本来扫出这些字符串.

To be continued...

转载于:https://www.cnblogs.com/unigauldoth/p/4631834.html

怪物农场2修改日志1 - FirstBlood相关推荐

  1. 怪物农场2修改日志3 - 年轮

    接上篇,怪物农场2修改日志2 - 奇妙能力歌 bgm是神秘妹纸唱的超好听的年轮 上篇中,我们顺利找到了"已收集怪物Id"这个列表. 接下来该做什么呢? 根据上篇的推理,当玩家生成新 ...

  2. Spring Boot 2动态修改日志级别

    本文基于:Spring Boot 2.1.3,理论支持Spring Boot 2.x所有版本. 作为程序猿,定位问题是我们的日常工作,而日志是我们定位问题非常重要的依据.传统方式定位问题时,往往是如下 ...

  3. log4j2动态修改日志级别及拓展性使用

    一.供参考的完整日志配置 <?xml version="1.0" encoding="UTF-8"?><!-- 配置LoggerConfig, ...

  4. 使用RestTemplate模版实现 Rest 服务调用、Swagger 集成、动态修改日志级别

    Spring 与 Restful 整合才是微架构的核心,虽然在整个 SpringBoot(SpringCloud)之中提供有大量的 服务方便整合,但是这些 整合都不如 Rest 重要,因为 Rest ...

  5. java日志——修改日志管理器配置+日志本地化

    [0]README 0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理解 java日志--修改日志管理器配置+日志本地化 的相关知识: [1]修改日志管理器配置 1.1 ...

  6. 日志级别_SpringBoot实战(十三):Admin动态修改日志级别

    强烈推荐一个大神的人工智能的教程:http://www.captainbed.net/zhanghan [前言] 之前关于线上输出日志一直有个困惑:如何可以动态调整的日志级别,来保证系统在正常运行时性 ...

  7. 求你了,别再随便打日志了,教你动态修改日志级别!

    GitHub 19k Star 的Java工程师成神之路,不来了解一下吗! 之前写过一篇文章<明明有自动清理,日志还是把我的服务干爆了!>,介绍过一次大促故障,是因为日志量激增,导致服务器 ...

  8. springboot 日志级别_SpringBoot实战(十三):Admin动态修改日志级别

    强烈推荐一个大神的人工智能的教程:http://www.captainbed.net/zhanghan [前言] 之前关于线上输出日志一直有个困惑:如何可以动态调整的日志级别,来保证系统在正常运行时性 ...

  9. Spring Boot动态修改日志级别

    1. pom中引入 org.springframework.boot       spring-boot-starter-actuator 2. 发送POST请求: 地址: http://[服务地址] ...

最新文章

  1. 如何利用极致业务基础平台主界面容器工具配置出漂亮的业务系统
  2. 华硕笑傲珠峰,网络口碑营销巧打奥运擦边球
  3. OJ系列之---单词倒排
  4. iOS开发(3)UIButton
  5. 数据:哈佛大学新生近五成是富二代!
  6. C++求复数的角度_【研读.教材分析】“勾股定理”教学——基于单元整体的角度再思考...
  7. soa---java 多线程的---锁
  8. Using BLAS and LAPACK from C/C++
  9. Liunx 常用命令 学习备份
  10. 计算机二级刷题库刷的到原题吗,刷题能过计算机二级吗?
  11. windows PE结构解析
  12. 做大数据的公司_技术
  13. 风螺旋线公切线的算法
  14. Intellij Idea 全屏设置
  15. 数据结构(Java)-树-堆排序的实现
  16. vue01-前端知识体系(狂神)
  17. 随机产生单词java_JavaGUI实现随机单词答题游戏
  18. BUU刷题记录(四)
  19. 使用普通打印机打印条码标签
  20. 光纤收发器测试方法大全

热门文章

  1. 张家俊:ChatGPT八个技术问题的猜想
  2. 新书推荐 | OpenShift在企业中的实践:PaaS DevOps 微服务
  3. android移动支付——微信支付,flutter瀑布流内存
  4. 免费文件服务器储存技术
  5. java日记_Java实现超级实用的日记本
  6. 重装Ubuntu时如何保留/home分区中的数据
  7. 【仪器仪表专题】万用表“几位半”中半位的含义
  8. esp32/arduino使用snap7与SIMENS plc通信
  9. 根据温度自动调节显卡风扇速度
  10. 【翻译】Image Style Transfer Using Convolutional Neural Networks