RPG Game Reverse 0
source link: https://taardisaa.github.io/2022/03/28/RPG%20Game%20Reverse%200/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
RPG游戏逆向
RPG Game Reverse 0
没心情玩恐怖游戏,疯狂死。于是准备逆一下看看剧本。
暂时遇到的工具。不是所有都有用。
RPG Maker VX Ace
RPG游戏制作工具。需要破解。
RPGVXAce_RTP
RPG VX Ace Runtime Package,是游戏运行库,想要正常运行RPG Maker的游戏需要先安装这个。
RGSS加密文件解包器
RPG Maker制作的游戏核心逻辑位于Game.rgss3a
资源文件中。此工具可以解包,获得图片,地图等资源。
RpgMakerSaveEdit
可以用于修改Save.rvdata2
保存文件,用于魔改游戏进度。
但是对于其他.rvdata2
资源文件无效。
rvdata2json
Ruby脚本
将rvdata2
转化成json
序列化文件。
缺少某些依赖,放弃使用。
rvdata2_parser
Python脚本
可以将rvdata2
解析
根据实践发现可以将除了MAP.rvdata2
地图文件以外的资源文件进行解析,生成Python字典格式。
RPG游戏结构
以某恐怖RPG游戏为例。
此游戏似乎没有做强加密,属于没有任何保护。
.
├── Audio
│ ├── BGM
│ ├── BGS
│ ├── ME
│ └── SE
├── Game.exe
├── Game.ini
├── Game.rgss3a
├── RGSS300.dll
├── Save
│ └── GSave.rxdata
├── Save01.rvdata2
├── System
│ └── RGSS300.dll
├── readme.txt
└── simhei
└── simhei.ttf
Audio
各种格式的音频资源。
Game.exe
游戏启动器。根据逆向发现,并没有核心算法,大部分为标准库函数,属于RPG游戏的默认启动器。
Game.ini
[Game]
RTP=RPGVXAce
Library=System\RGSS300.dll
Scripts=Data\Scripts.rvdata2
Title=the LifT
定义了脚本,库,游戏名以及制作工具为RPGVXAce
(RPG Maker底下还有3个不同子版本)
simhei
文件夹名含义未知,但是里面有中文字体配置文件。
GSave.rxdata
猜测是用于记录存档的,但是发觉全都保存在主文件夹的SaveXX.rvdata2
下了。
RGSS300.dll
Ruby Game Scripting System
,Ruby游戏扩展,有Aspack压缩壳。
SaveXX.rvdata2
各个存档文件。可以使用RpgMakerSaveEdit
进行魔改。
Game.rgss3a⭐
资源文件存档,可以解包后拿到各种资源文件。核心分析点。
据说若有加密,则解包后也只会得到一些加密数据。就需要分析RGSS300.dll
中有没有调用什么解密流程了。
在没被加密,能够直接拆包的情况下,
.
├── Data
│ ├── Actors.rvdata2
│ ├── Animations.rvdata2
│ ├── Armors.rvdata2
│ ├── Classes.rvdata2
│ ├── CommonEvents.rvdata2
│ ├── Enemies.rvdata2
│ ├── Items.rvdata2
│ ├── Map001.rvdata2
│ ├── Map105.rvdata2
│ ├── MapInfos.rvdata2
│ ├── Scripts.rvdata2
│ ├── Skills.rvdata2
│ ├── States.rvdata2
│ ├── System.rvdata2
│ ├── Tilesets.rvdata2
│ ├── Troops.rvdata2
│ └── Weapons.rvdata2
├── Graphics
│ ├── Characters
│ ├── Faces
│ ├── Parallaxes
│ ├── Pictures
│ ├── System
│ ├── Tilesets
│ └── Titles1
└── extract.log
其中省略了若干MapXXX.rvdata2
。皆是地图资源文件。
2个主文件夹
Graphics
.
├── Characters
├── Faces
├── Parallaxes
├── Pictures
├── System
├── Tilesets
└── Titles1
都是图片文件。Pictures
文件夹下有剧情相关图片,剧透警告。
充满了各种.rvdata2
资源文件。本质上是Ruby
数据对象序列化后的样子;和Python中PyObject与.pyc
文件的关系有异曲同工之妙。
使用rvdata2_parser
能够解码除了Map以外的文件。
或者塞到某个RPG Maker的新建项目里面也能够直接看到相应数据。
Actors
游戏内人物,主角的数据。
Animations
若干回合制格斗中的技能设定。此游戏是恐怖游戏,没有回合制格斗,所以这应该是项目创建时RPG Maker默认提供的。
Armors
回合制格斗中的盔甲设定。
Classes
种族/阶级分类。
比如此游戏中的主角是个苦逼社畜。
[None, RubyObject({'@name': '上班族', '@learnings': ...]
CommonEvents
应该是事件设定。直接看序列化文件看不出名堂。
[None,
RubyObject(
{'@trigger': 2,
'@name': 'Light',
'@switch_id': 23,
'@list': [
RubyObject(
{
'@indent': 0,
'@code': 122,
'@parameters': [12, 12, 0, 3, 5, -1, 3]
}
),
RubyObject({'@indent': 0, '@code': 122, '@parameters': [13, 13, 0, 3, 5, -1, 4]}),
RubyObject({'@indent': 0, '@code': 231, '@parameters': [2, 'Light-2', 1, 1, 12, 13, 100, 100, 255, 0]}),
RubyObject({'@indent': 0, '@code': 0, '@parameters': []})], '@id': 1}), ...]
需要RPG Maker配合分析
Enemies
根据名称猜测,应该是默认的敌人种类和分类。
具体于这个游戏:
[None,
RubyObject({
'@description': '',
'@name': 'flag1',
'@consumable': False,
'@occasion': 0,
'@icon_index': 192,
'@price': 0,
'@scope': 7,
'@animation_id': 37,
'@note': '',
'@speed': 0,
'@id': 1,
'@features': [],
'@effects': [RubyObject({'@code': 11, '@data_id': 0, '@value1': 0.0, '@value2': 500.0})],
'@damage': RubyObject({'@type': 0, '@element_id': 0, '@formula': '0', '@variance': 20, '@critical': False}),
'@success_rate': 100,
'@hit_type': 0,
'@itype_id': 1,
'@repeats': 1,
'@tp_gain': 0}
),
RubyObject({'@description': '', '@name': 'flag2', '@consumable': True, '@occasion': 0, '@icon_index': 0, '@price': 0, '@scope': 7, '@animation_id': 0, '@note': '', '@speed': 0, '@id': 2, '@features': [], '@effects': [], '@damage': RubyObject({'@type': 0, '@element_id': 0, '@formula': '0', '@variance': 20, '@critical': False}), '@success_rate': 100, '@hit_type': 0, '@itype_id': 1, '@repeats': 1, '@tp_gain': 0}),
RubyObject({'@description': '', '@name': 'flag3', '@consumable': True, '@occasion': 0, '@icon_index': 0, '@price': 0, '@scope': 7, '@animation_id': 0, '@note': '', '@speed': 0, '@id': 3, '@features': [], '@effects': [], '@damage': RubyObject({'@type': 0, '@element_id': 0, '@formula': '0', '@variance': 20, '@critical': False}), '@success_rate': 100, '@hit_type': 0, '@itype_id': 1, '@repeats': 1, '@tp_gain': 0}),
RubyObject({'@description': '', '@name': 'flag4', '@consumable': True, '@occasion': 0, '@icon_index': 0, '@price': 0, '@scope': 7, '@animation_id': 0, '@note': '', '@speed': 0, '@id': 4, '@features': [], '@effects': [], '@damage': RubyObject({'@type': 0, '@element_id': 0, '@formula': '0', '@variance': 20, '@critical': False}), '@success_rate': 100, '@hit_type': 0, '@itype_id': 1, '@repeats': 1, '@tp_gain': 0}),
RubyObject({'@description': '', '@name': 'flag5', '@consumable': True, '@occasion': 0, '@icon_index': 0, '@price': 0, '@scope': 7, '@animation_id': 0, '@note': '', '@speed': 0, '@id': 5, '@features': [], '@effects': [], '@damage': RubyObject({'@type': 0, '@element_id': 0, '@formula': '0', '@variance': 20, '@critical': False}), '@success_rate': 100, '@hit_type': 0, '@itype_id': 1, '@repeats': 1, '@tp_gain': 0})]
设立了5个flag
,严重怀疑应该与不同的结局有关系,因为在修改存档文件的时候也会发现这5个flag
数据。
定义了游戏内地图设定。虽然应该也是Ruby序列化对象,但是似乎和其他的文件有少许差别。暂时只能使用RPG Maker进行阅读。
MapInfos
记录了Map的数量与名称。如果不对应的话,Map数据无法在RPG Maker中正常加载。
Scripts
脚本资源。需要RPGMaker
Skills
回合制格斗中的技能数据。
States
回合制格斗中的人物状态。
System
需要RPGMaker
Tilesets
[None, RubyObject({'@id': 1, '@name': '世界地图', '@mode': 0, '@tileset_names': ['World_A1', 'World_A2', '', '', '', 'World_B', '', '', ''], '@flags': UserDef({}), '@note': ''}), RubyObject({'@id': 2, '@name': '外观地图', '@mode': 1, '@tileset_names': ['Inside_A5', 'Outside_A2', 'Outside_A3', 'Outside_A4', 'Outside_A5', 'Inside_B', 'Outside_C', '', ''], '@flags': UserDef({}), '@note': ''}), RubyObject({'@id': 3, '@name': '内部地图', '@mode': 1, '@tileset_names': ['Inside_A1', 'Inside_A2', '', 'Inside_A4', 'Inside_A5', 'Inside_B', 'Inside_C', '', ''], '@flags': UserDef({}), '@note': ''}), RubyObject({'@id': 4, '@name': '迷宫地图', '@mode': 1, '@tileset_names': ['Dungeon_A1', 'Dungeon_A2', '', 'Dungeon_A4', 'Dungeon_A5', 'Dungeon_B', 'Dungeon_C', '', ''], '@flags': UserDef({}), '@note': ''})]
记录了若干默认地图。
Troops
敌人集群设定。
Weapons
武器设定。
恢复RPG Maker项目
在另一个文件夹下创建新项目
然后复制刚刚的Data
和Graphics
文件夹到项目文件夹中。可能有替换,直接替换即可。
最好也把游戏文件夹里的Audio
音频资源也复制过来。这样就获得了完整的游戏项目了。
Ancurio/rgss_script_editor: Script editor for Scripts.{rxdata, rvdata, rvdata2} (github.com)
Inejka/rvdata2_parser: Tool for reading packed rvdata2 files (github.com)
쯔꾸르 에디터 (Rpg Maker VX Ace 세이브 에디터) : 네이버 블로그 (naver.com)
RPGツクールVX Ace セーブ改造ツール (RPG MAKER VX SAVE EDITOR) (save-editor.com)
Downloads And Free Trials | RPG Maker | Make Your Own Game! (rpgmakerweb.com)
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK