1.frida逆向抓包获取key(为后续garbro编译做准备)
javascript
https://github.com/YuriSizuku/GalgameReverse/blob/master/project/krkr/src/krkr_hxv4_dumpkey.js
下载后放游戏目录
python安装步骤略自行查看b站教程
Python
pip install frida-tools
注意有些Steam的游戏存在DRM等,去除后使用,具体技术细节不在本文中赘述,请查看其他文章
游戏目录中运行以下命令
javascript
frida -l krkr_hxv4_dumpkey.js -f 游戏.exe > key_output.txt 2>&1
运行后等待一会命令窗口,然后游戏打开,关闭游戏
control_block.bin与key_output.txt将会在游戏目录中生成
Textile
hxpoint at 0x6c4cf0c3
cxpoint at 0x6c4c3c6d
* key : 724dc481e71024c53ed9ee2a1674f39caec40e0d55ffb11e60fe6e1f7dcc4128
* nonce : 522f20d0a8e442e85a1e8b4dead28da3
* verify : 481c32f156b99b6014ccbd2c479fce70422f58163d6c7ad344b05ca2955897c8
* filterkey : b9ac287fb5e05f0d
* mask : 0x1dc
* offset : 0x295
* randtype : 1
* order : 05 03 00 02 07 04 06 01 05 04 03 00 01 02 00 02 01
* PrologOrder (garbro) : 0, 2, 1
* OddBranchOrder (garbro) : 4, 1, 0, 3, 5, 2
* EvenBranchOrder (garbro) : 3, 4, 1, 2, 6, 0, 7, 5
删除了一些冗余信息,那么这些带"*"是我我们要重点关注的内容
2本地编译
尽可能用最新的.NET,最低要求是4.7.2的
下一个这个
https://strawberryperl.com/https://strawberryperl.com/
VSCodeStudio的一些开发包尽量下一下,或许未来用到


如果进去了一堆报错正常缺少啥using的,点击生成,生成解决方案,清除生成的解决方案即可去除

没有就不用管
修改SchemeTool文件夹中的Program.cs
C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
namespace SchemeTool
{
class Program
{
static void Main(string[] args)
{
// ================================
// 基本信息(根据游戏修改这里)
// ================================
string gameTitle = "TenShiSouZou"; // Scheme 名称(自定义)
string exeName = "tenshi_sz.exe"; // 游戏主程序名
string formatPath = @".\GameData\Formats.dat"; // GARbro 数据库
string controlBlockFile = "Tenshi.bin"; // 控制块文件
string namesFile = "HxNames-Tenshi.lst"; // 名称表文件
// ================================
// 1. 读取原有 Formats.dat
// ================================
using (Stream stream = File.OpenRead(formatPath))
{
GameRes.FormatCatalog.Instance.DeserializeScheme(stream);
}
// ================================
// 2. 获取 XP3 解包器
// ================================
var format = GameRes.FormatCatalog.Instance.ArcFormats
.FirstOrDefault(a => a is GameRes.Formats.KiriKiri.Xp3Opener)
as GameRes.Formats.KiriKiri.Xp3Opener;
if (format == null)
{
Console.WriteLine("未找到 Xp3Opener");
return;
}
var scheme = format.Scheme as GameRes.Formats.KiriKiri.Xp3Scheme;
if (scheme == null)
{
Console.WriteLine("未找到 Xp3Scheme");
return;
}
// ================================
// 3. 读取 ControlBlock(二进制控制块)
// ================================
if (!File.Exists(controlBlockFile))
{
Console.WriteLine("未找到 Tenshi.bin");
return;
}
byte[] cb = File.ReadAllBytes(controlBlockFile);
// ControlBlock 必须是 4 字节对齐
if (cb.Length % 4 != 0)
{
Console.WriteLine("ControlBlock 大小错误");
return;
}
// 转换为 uint 数组
uint[] controlBlock = new uint[cb.Length / 4];
Buffer.BlockCopy(cb, 0, controlBlock, 0, cb.Length);
// ⚠ 不需要 ~ 取反(本游戏已验证)
// ================================
// 4. 构造 CxScheme(来自 Frida 抓到的参数)
// ================================
var cs = new GameRes.Formats.KiriKiri.CxScheme
{
Mask = 0x1dc, // Frida 抓到
Offset = 0x295, // Frida 抓到
// 分支顺序(非常重要)
PrologOrder = new byte[] { 0, 2, 1 },
OddBranchOrder = new byte[] { 4, 1, 0, 3, 5, 2 },
EvenBranchOrder = new byte[] { 3, 4, 1, 2, 6, 0, 7, 5 },
ControlBlock = controlBlock
};
// ================================
// 5. 构造 HxCrypt
// ================================
var crypt = new GameRes.Formats.KiriKiri.HxCrypt(cs)
{
RandomType = 1, // Frida 抓到
FilterKey = 0xb9ac287fb5e05f0d, // Frida 抓到
NamesFile = namesFile // 文件名表
};
// ================================
// 6. 设置 IndexKey(key + nonce)
// ================================
// 这是 32 字节 key
byte[] key = SoapHexBinary.Parse(
"724dc481e71024c53ed9ee2a1674f39caec40e0d55ffb11e60fe6e1f7dcc4128"
).Value;
// 这是 16 字节 nonce
byte[] nonce = SoapHexBinary.Parse(
"522f20d0a8e442e85a1e8b4dead28da3"
).Value;
// 绑定到 data.xp3
crypt.IndexKeyDict = new Dictionary<string, GameRes.Formats.KiriKiri.HxIndexKey>()
{
{
"data.xp3",
new GameRes.Formats.KiriKiri.HxIndexKey
{
Key1 = key,
Key2 = nonce
}
}
};
// ================================
// 7. 注册到 KnownSchemes
// ================================
scheme.KnownSchemes[gameTitle] = crypt;
// ================================
// 8. 绑定 exe → Scheme
// ================================
var gameMapField = typeof(GameRes.FormatCatalog)
.GetField("m_game_map", BindingFlags.Instance | BindingFlags.NonPublic);
var gameMap = gameMapField.GetValue(GameRes.FormatCatalog.Instance)
as Dictionary<string, string>;
if (gameMap != null)
gameMap[exeName] = gameTitle;
// ================================
// 9. 保存回 Formats.dat
// ================================
using (Stream stream = File.Create(formatPath))
{
GameRes.FormatCatalog.Instance.SerializeScheme(stream);
}
Console.WriteLine("TenShiSouZou 加密方案添加成功!");
}
}
}
ctrl+shift+B,再生成一次
右键ScchemeTool,点击生成

.bin放入
在GARbro-Mod-master\GARbro-Mod-master\bin\Debug存在SchemeTool.exe
cmd运行SchemeTool.exe,直接把exe拖到cmd窗口上回车就是了
成功了会有提示

虽然吧无法直接解析查看文件,但可以提取出来当参考目录,配合CXDECExtractorV2这个项目可以快速写个快速恢复脚本
3.Garbro2可视化SchemeTool也可以可视化编辑,同样的只可以看到结构无法查看问渐文件详细