8

RPG Game Reverse 0

 2 years ago
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.
neoserver,ios ssh client

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项目

在另一个文件夹下创建新项目

然后复制刚刚的DataGraphics文件夹到项目文件夹中。可能有替换,直接替换即可。

最好也把游戏文件夹里的Audio音频资源也复制过来。这样就获得了完整的游戏项目了。

1、什么是RGSS - Ruby中文文档 (php.cn)

Ancurio/rgss_script_editor: Script editor for Scripts.{rxdata, rvdata, rvdata2} (github.com)

Inejka/rvdata2_parser: Tool for reading packed rvdata2 files (github.com)

Bioruebe/rmvdec: A decrypter for RPG-Maker-MV ressource files (.rpgmvp, .rpgmvo, rpgmvm) (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)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK