一、存档位置与文件分工
Windows Steam 版默认路径:
C:\Users\用户名\Documents\My Games\Terraria\Players\ → 角色档 .plr / .plr.bak / 配套 *.plr.map 缩略图
C:\Users\用户名\Documents\My Games\Terraria\Worlds\ → 世界档 .wld / .wld.bak / *.wld.map
.plr 存角色名、外观、HP/MP、背包、装备、饰品、猪猪存钱罐、保险箱、buff、任务进度;.wld 存地图尺寸、图格 Tile、墙体、液体、NPC、宝箱、事件标记、Boss 击杀状态。两者都是自定义二进制序列化 + 部分加密,不是 JSON/XML。
二、加密机制演变(手动解密前必须先判版本)
1. 早期 1.0~1.1:弱混淆,XNA 下 Rijndael/AES 固定密钥 "h3y_gUyZ"(Unicode 编码成密钥字节),AES-128-CBC 思路雏形。
2. 1.2~1.3:正式 AES + RijndaelManaged,密钥依旧硬编码在 Terraria.exe 内,用 dnSpy / ILSpy 反编译 Assembly 搜 Decrypt / Rijndael / LoadPlayer 可定位。
3. 1.4.x 至今:玩家档 .plr 主体 AES 加密块,头部明文存版本号、名字长度、标志位;世界档 .wld 图格区走压缩(紧凑 Tile 序列化)+ 局部加密,宝箱/容器数据嵌在世界流里。
结论:手动改物品不能拿 HxD 直接硬改密文体,必须先把加密主体解出来成明文二进制流,改完再按同算法封回,否则游戏读档直接报 Corrupt Save。
三、工具链
• HxD / 010 Editor:看头、搜明文字符串、按偏移改明文流
- dnSpy / ILSpy:反编译 Terraria.exe 提取密钥、AES 参数、Tile 读写顺序
• Python / C#:写解密→改字节→重加密脚本
• Terraria Wiki Item ID 表 + Prefix(修饰语) 表:定位物品用
- 备用校验:老主机/Xbox 版改完要修 checksum,PC 1.4 走 AES 完整性校验,不重加密必坏
四、.plr 手动解密流程(以 1.4 PC 为例)
1. 备份:复制 Knight.plr → Knight.plr.bak,关游戏再操作。
2. 读文件头:前若干字节非密,含 magic(0x54524d79 之类标识)、version、playerName 长度 + UTF8 名、difficulty(0经典/1中核/2硬核/3旅程)。
3. 定位加密块:头部结束后到文件尾为 AES 密文,长度 = 文件总长 - 头部长,必须是 16 字节整数倍(AES-CBC block size)。
4. 提取密钥参数(dnSpy 搜 PlayerFile.StartDecryption):
key = Encoding.Unicode.GetBytes("h3y_gUyZ") 截断/补位到 16/32 字节,IV 取自文件头固定字段或全零,模式 CBC,填充 PKCS7。
5. 解密:AES.Decrypt(密文, key, IV) → 得到明文 PlayerBuffer 流。此时用 HxD 打开明文流能看到名字、HP/MP 数值、物品段。
6. 字节序:PC 小端(Little-Endian),Xbox/3DS 大端,改多字节数值时注意翻转。
五、物品段结构与手动改物品
解密后的明文流里,物品区布局(1.4 主线):
• 主背包 50 格 + 硬币/弹药 8 格 + 装备/饰品/染料/时装/宠物/矿车/钩爪等专用槽
每格 Item 结构序列化顺序(反向用 Wiki ID 对照):
[2字节 ItemID][2字节 stack(数量)][1字节 prefix(修饰语)][1字节 favorited/flags] ≈ 6 字节起,老版 5 字节(ID+stack+prefix)
例:把第 0 格改成“泰拉之刃 Zenith(ID 757 / 0x02F5)”,数量 999(0x03E7),前缀 Legendary(ID 82 左右,查表):
原:03 00 01 00 00
改 ID 小端:F5 02
改数量小端:E7 03
改 prefix:52(十进制82十六进制)
写回:F5 02 E7 03 52
HP/MP 上限字段在名字段后不远处,2 字节或 4 字节小端,直接搜当前数值定位(如满血 500 → 0xF4 0x01)。
猪猪存钱罐 / 保险箱 / 虚空袋:不在主背包连续区,跟随在专属标记段后,结构同 Item 数组,需按版本偏移表跳。
六、.wld 世界档处理差异
.wld 不推荐手改图格,体量巨大(小世界几 MB、大世界几十 MB),结构:
Header(世界名、种子、尺寸、难度、时间、Boss flags)→ Tile 区(按列压缩序列化,每 Tile 存类型/墙/液体/线/执行器位标)→ Chest 数组(宝箱物品用同 Item 结构)→ Sign/NPC/Event 区。
手动改宝箱物品:定位 Chest 区 → 每箱 40 槽 Item 结构 → 同 .plr 改法。图格直接改需复刻 CompactTileData 位域(type 占多少位、wall 占多少位、液体 4 位等),不推荐手写,用 TEdit 类工具更安全。
七、重加密与回填(关键,漏了必 Corrupt)
1. 改完明文流 → AES-Encrypt(明文, key, IV) 得到新密文。
2. 新密文长度若因改大物品名/扩字段变化,需同步修正文件头里的 Length 字段(若有)。
3. 头部原样拼回 + 新密文 → 写回 Knight.plr。
4. 1.4 起若引擎带 HMAC/校验和,需用同套逻辑重算(多数 PC 版仅 AES-CBC + 内部字段自检,无外置 checksum;主机版必须修 checksum)。
5. 进游戏读档验证:角色名正常、物品到位、不报损坏即成功。
八、常见坏档与定位
• 打开报 Corrupt Save:密文没重加密、IV 取错、PKCS7 填充被破坏、头部长度字段未同步。
- 物品变问号/消失:ItemID 超出当前版本最大 ID、prefix 值非法、字节序没翻。
• HP 改完回弹:改到缓存副本不是真实字段、或难度模式限制(硬核死亡删档逻辑干扰)。
• 世界图格花屏:手改 Tile 位域错位,必须用 TEdit 而非 HxD 动地形。
- Steam 云覆盖:改完进游戏前关 Steam Cloud,否则云快照回写覆盖本地。
九、最小化可行手动改物品脚本思路(C# 片段逻辑)
LoadBytes(plr) → 切头部/密体 → AES128-CBC Decrypt(key="h3y_gUyZ" Unicode, iv) → 明文流找 inventory offset(按名字长度+固定头推算或搜已知物品特征) → 写 ItemID/stack/prefix → Encrypt 回密体 → 拼头写盘 → .bak 留存。
Python 侧用 Cryptodome.AES 同参数复刻即可,IV 与 key 长度按 dnSpy 实际反编译结果校正,不同 1.4 小版本可能轮换盐值。
整条逆向链路就是:定位路径 → 备份 → 反编译取密钥 → 切头/解密主体 → 明文流按 Item 结构改 ID/数量/prefix → 同算法重加密 → 拼头回写 → 关云同步进游戏校验;.wld 只动 Chest 物品,Tile 交给专用编辑器,硬碰密文主体必坏档。
Terraria泰拉瑞亚存档逆向全流程:plr与wld手动解密及物品修改实操
来源:
作者:
点击:

