品牌:ほろよい 広場
发售日期:2002-10-01
原画:
声优:
剧本:
0.0( 0人评价)
为该游戏添加介绍
很遗憾,在经过繁复工作后,我判断本游戏的破解补丁**不可达成**。个人建议后来者不要去试,只会浪费时间——除非你有什么崭新思路,或者手握一台量子计算机,或者**已经朝作者买了正版**——这可以导出CG达成最后一块拼图(但作者官网没了根本联系不上,否则我自己就买了)。 姑且用体验版提出来的CG合了个残缺版,但感觉真没必要放出来……
先说作者埋下的暗桩:
1. 一个假注册函数:读注册表 ProductID、读 YB002.DAT 尾部、用 `Randomize(7491)` 异或后**写回 YB002.DAT**→弄脏YB002(实质是认证拼图之一,见下),导致此后无论如何做攻击都绝对不可能成功破解(原因同样见下)。 2. 一个清除system.dat/user.dat的恐吓炸弹,目前看来没任何分支走到它上面执行。 3. 状态门和实际内容解密分离。导致看上去已经认证通过,但是进实际游戏马上报错。 4. 不计其数的死分支 5. 反调试器,挂上开游戏必定秒退。 6. 认证Key包含解密key,目前图像提取这块是死局。 安装流程: SFX Overlay 位于偏移 0x6C00,魔数为 LHA 的 -lh5- 压缩流头部。 然后自动执行UNINSTYB.EXE——该exe既能安装又能卸载。 它解压YUREIB.GLB。 GLB包格式: 0x00 - 0x03:"JGLB"(0x4A 0x47 0x4C 0x42) 0x04 - 0x05:0x0001(版本号) 0x06 - 0x07:条目总数(0x000C) 0x08 - 0x0F:"Yu-Byoin\0" 0x10 - 0x6F:每个条目8字节的索引表。Offset占4字节、Size占4字节。 UNINSTYB.EXE读取YUREIB.GLB并对前8个字节做变换: XOR 0xE6、XOR 0xE7、XOR 0xE8……XOR 0xED(8个字节每个字节XOR值都不同) 第9个字节后是原样输出。 然后安装包对YB002.DAT尾部做修改: 先生成几个常数: 乘数a(0x408050)=Int(Rnd*30000)+1983 增量c(0x408054)Int(Rnd*30000)+2171 模数m(0x408058)Int(Rnd*20000)+12767 尺寸混淆密钥K_size(0x40805C)=±(Int(Rnd*15000)+16111) 初始种子X_0(0x408060)=Int(Rnd*32000)+511 校验常数K_5=Int(Rnd*18000)+719 然后将参数做Randomize(0xA0D5)异或→写入注册表+产品序列号(Base-N编码,长度18)+YB002尾部。 →加密YB002.DAT: Size部分动态异或K_size。 内容区按DWORD逐块异或LCG生成器(0x00403F3C)生成的DWORD。 验签流程:
认证文件YBPLAY.DAT使用433-bit RSA不对称加密。在发布当年大概无懈可击,今天已经能穷举了。这里直接写答案——如果有后来者,请直接用以下值即可:
公钥模数N=13176862830940117142776899025684081751351350033204258942658688359946915625609458413096943199864314319134722256776072743912358607923 e=7 p=1067325897951489270617331695133200226491170791899739827953441217293 q=12345678912345678912345678912345678912345678912345678912345678911 私钥d=9412044879242940816269213589774344108108107166574470673327634542048031463389731045405189875584834581236575561402848026461836936943 用上述私钥签任意 256B 载荷,可生成合法YBPLAY.DAT(认证文件)。
载荷布局: [1..16]:与 ProductID XOR 出主密钥。 [17..50]:是图像 LCG 常数区(Mul1/Inc1/Mod1/K_offset/Seed1、Mul2/Inc2/Mod2/K_size/Seed2,前 4 个是 4B Long、后 5 个是 2B Integer 符号扩展) [0x25]起是 K_script(剧本偏移)。 [64..103] 是授权文本 "Official Full Registered License\0" ^ 0x83 防篡改填充。 可确定常数: K_offset=0xB63C15A2,K_size=0x9B07,K_script=89。 剧本解密(DataMAIN.DAT): ① Knuth 洗牌(`Rnd(-1); Randomize(16177)`,生成 L/2 个位置对后倒序交换) ② 前 6336B 为章节偏移表 ③ 逐字节 `^ 0xE6`,且**仅正式版**(Diff==0)再 `^ ((pos×K_script + 11511) mod 240 + 15)`(pad 函数 `0x566EA0`,字节读取循环 `0x573ABB`)。 解密结果为 UTF-16LE 剧本流。 然后就到这里卡死了。 YB002有二次加密,导致游戏能进但画面全黑。
------------------------
(注:我到这里力竭了——实在无心继续逆向,所以接下来请看AI表演。省流:认证Key同时也是解密key,穷举量级过大,且FP舍入噪声导致没有快速验证手段)
## 已判明事实(逐条钉死,含证据位置)
### 包格式 - `JGLB`/`JADV-03N` 头 16B;索引在 16 起、8B/条、181 槽;**索引 XOR(K_off/K_size)与双 LCG 只用于正式版 YB002**;YB001/YB006 为明文索引 + 前 8 字节 `^E6..ED`;YB006 索引偏移为 1-based。 - **条目 ID → 槽位是 1-based**:剧本 ID N 读索引槽 N-1(`sub ax,1; imul ax,8; add 10h; add 1`,`0x564DDA-0x564E02`)。 - 空条目惯例:stored `(0,0)` → 解码出巨偏移 → Get 越界被吞 = 静默黑;stored `(K_off,K_size)` → 解码 `(0,0)` → 弹「ファイル参照エラー7(IDxxxのデータは存在しません)」并终止。
### 图像容器格式(两包通用) `[19B 头: D9F0E103 114D47A4 + 参数] [~378B Photoshop IRB] [128×96 缩略图 JPEG(带 FFD8)] [8BIM 块] [640×480 主 JPEG(无 FFD8,从 COM/APP14 起)]`。主图抽取法:缩略图 EOI 后第一个 FF 段起、补 FFD8。 立绘/差分(槽 140+):BMP 变体(自定义 2 字节魔数 `4C B9`,BITMAPINFOHEADER 在偏移 13,8-bit 调色板)——重建为标准 BMP 只需重写 14B 文件头。
### 显示链路 - `Proc_6_46`(`0x567740`)按 `[58323Ah]/[5831EEh] > 0` 触发加载,`Diff`(`0x583038`)只作包选择器(-1→YB001,0→YB002),无互斥门禁(早年笔记的怀疑是 VB Decompiler 伪码误读)。 - 解密→写 `C:\WINDOWS\Tempgrp.000`→`LoadPicture`(VB6 Global vtable+0x44)→赋 PictureBox→`Kill`。**无任何自定义解码器**(全代码节魔数扫描为零);也无涂红/压图惩罚暗桩——标题左上角红块只是 PictureBox 默认底色。 - 标题:正式版读 YB002 的 id 130(槽 129),体验版读磁盘 `Title.bmp`。
### 剧本/热点 - `YB004.DAT` = 140 张背景热点掩码(每张 3,072B = 64×48 格,包大小逐字节吻合);`YB003.DAT` = 19 张立绘叠加掩码(30×48=1,440B)。点击 `(X/10, Y/10)` 寻址得热点号 → CLJUMP 跳剧本块。**掩码与 YB002 无关、公开包完好**。 - 全部掩码已导出 `extracted\masks\`(含放大预览 BMP)。
### 内容恢复终局 - 共享条目 72 个:YB001 孪生提供完整主图/立绘(已验证可解码、可显示)。 - 3 张大 CG(槽 18/24/70):AI 虚构版(非原图)。 - 标题(槽 129):用 Title.BMP 直填。 - **56 张正式版独有图:不可恢复**(穷举证据见暗桩 5)。 - 原包 46 个空槽(含 8/36/44/49-50/66/79-98/124-128/130-134/137-139/159/173/175-177/179-180)原本就空。
---
## 尝试过的手段(含失败)
| 手段 | 结果 | |---|---| | 433-bit RSA 分解(yafu GNFS) | ✅ 成 | | 伪造 YBPLAY(双层 ProductID XOR + 自签) | ✅ 过全部校验,剧本/标题/共享图实机正常 | | factory_stream 攻击(gcd / z3 FP64 / HNP / 12 亿字典 / VB6-Rnd 13 映射 × 2^24 / Rnd 公式 6 族 × 2^24) | ❌ 全灭(该层后已被证明无需再碰) | | 重放攻击 keystream.bin(257,904B) | ⚠️ 仅前 ~21B 真;曾误判"~1KB 有效"(编码器表巧合) | | 同尺寸对穷举 C(72,2) 建共识流 | ❌ 最长 1,139B(立绘对,结构性巧合),典型 21B | | 原流 LCG 种子反推(S2 全空间 + 代数解 A/C × 3 种模数) | ❌ 无锚点,无解 | | UAC/管理员权限假说 | ❌ 被 VirtualStore 实证推翻(BGM MIDI 测试期间正常落盘) | | v3/v4 重打包(容器剥离/转码) | ❌ 当时未知 off-by-one,全部死于首字节脏 | | **v5 重打包(索引偏移 +1 补偿 + YB001 真内容 + AI CG + Title.BMP)** | ✅ **实机图像显示正常** |
## 汇编段结论速查
| 地址 | 内容 | |---|---| | `0x564B70` | Proc_6_40:图像解密加载核心(索引→Get→双 LCG→写 Tempgrp.000→LoadPicture→Kill) | | `0x564DDA-0x564E02` | 条目 ID→槽位:`(id-1)*8+16+1`(1-based 证据) | | `0x564E40/0x564EC2` | 索引 XOR 仅正式版分支执行(`test Diff` 后跳过体验版) | | `0x564F3F-0x564F4C` | 内容 Get:位置=解码偏移(1-based → 实际读 offset-1,off-by-one 现场) | | `0x565799-0x5659DA` | 双 LCG 循环:每条目 reseed 到固定种子(流逐条目 100% 相同) | | `0x5659E3` | On Error Resume Next(静默吞错起点) | | `0x565A04-0x565B01` | `GetWindowsDirectoryA` + `\Tempgrp.000` 拼接与打开 | | `0x565B15` | Diff 分支:正式版 Put Long 数组 / 体验版 Put Byte 数组 | | `0x565DE4` | 空条目分支(写 `windir+TMP\Tempgrp.000`,报错码 7) | | `0x567740` | Proc_6_46:BACK/CHAR 门控与 BitBlt 合成 | | `0x566EA0` | 剧本 pad 函数(K_script 来自 `[583354]`) | | `0x573ABB` | 剧本字节读取循环(^E6,正式版再 ^pad) | | `0x55C5A0/0x55C6C0` | LCG1/LCG2 本体(Variant floor 模) | | `0x55C7E0` | 许可证综合校验(ProductID + YBPLAY + 包哈希)→ `[5832C2]=0x34E8`、`Diff=0` | | `0x558F10-0x55916E` | exe 自哈希反篡改 | | `0x55BD62` / `0x5678A8` | ExitWindowsEx(4,0) 强制关机陷阱(启动 / 循环 1/16 随机) | | `0x563550` | 标题初始化(正式版读槽 129 / 体验版读 title.bmp) |
暂无相关记录
很遗憾,在经过繁复工作后,我判断本游戏的破解补丁**不可达成**。个人建议后来者不要去试,只会浪费时间——除非你有什么崭新思路,或者手握一台量子计算机,或者**已经朝作者买了正版**——这可以导出CG达成最后一块拼图(但作者官网没了根本联系不上,否则我自己就买了)。
姑且用体验版提出来的CG合了个残缺版,但感觉真没必要放出来……
先说作者埋下的暗桩:
1. 一个假注册函数:读注册表 ProductID、读 YB002.DAT 尾部、用 `Randomize(7491)` 异或后**写回 YB002.DAT**→弄脏YB002(实质是认证拼图之一,见下),导致此后无论如何做攻击都绝对不可能成功破解(原因同样见下)。
2. 一个清除system.dat/user.dat的恐吓炸弹,目前看来没任何分支走到它上面执行。
3. 状态门和实际内容解密分离。导致看上去已经认证通过,但是进实际游戏马上报错。
4. 不计其数的死分支
5. 反调试器,挂上开游戏必定秒退。
6. 认证Key包含解密key,目前图像提取这块是死局。
安装流程:
SFX Overlay 位于偏移 0x6C00,魔数为 LHA 的 -lh5- 压缩流头部。
然后自动执行UNINSTYB.EXE——该exe既能安装又能卸载。
它解压YUREIB.GLB。
GLB包格式:
0x00 - 0x03:"JGLB"(0x4A 0x47 0x4C 0x42)
0x04 - 0x05:0x0001(版本号)
0x06 - 0x07:条目总数(0x000C)
0x08 - 0x0F:"Yu-Byoin\0"
0x10 - 0x6F:每个条目8字节的索引表。Offset占4字节、Size占4字节。
UNINSTYB.EXE读取YUREIB.GLB并对前8个字节做变换:
XOR 0xE6、XOR 0xE7、XOR 0xE8……XOR 0xED(8个字节每个字节XOR值都不同)
第9个字节后是原样输出。
然后安装包对YB002.DAT尾部做修改:
先生成几个常数:
乘数a(0x408050)=Int(Rnd*30000)+1983
增量c(0x408054)Int(Rnd*30000)+2171
模数m(0x408058)Int(Rnd*20000)+12767
尺寸混淆密钥K_size(0x40805C)=±(Int(Rnd*15000)+16111)
初始种子X_0(0x408060)=Int(Rnd*32000)+511
校验常数K_5=Int(Rnd*18000)+719
然后将参数做Randomize(0xA0D5)异或→写入注册表+产品序列号(Base-N编码,长度18)+YB002尾部。
→加密YB002.DAT:
Size部分动态异或K_size。
内容区按DWORD逐块异或LCG生成器(0x00403F3C)生成的DWORD。
验签流程:
认证文件YBPLAY.DAT使用433-bit RSA不对称加密。在发布当年大概无懈可击,今天已经能穷举了。这里直接写答案——如果有后来者,请直接用以下值即可:
公钥模数N=13176862830940117142776899025684081751351350033204258942658688359946915625609458413096943199864314319134722256776072743912358607923
e=7
p=1067325897951489270617331695133200226491170791899739827953441217293
q=12345678912345678912345678912345678912345678912345678912345678911
私钥d=9412044879242940816269213589774344108108107166574470673327634542048031463389731045405189875584834581236575561402848026461836936943
用上述私钥签任意 256B 载荷,可生成合法YBPLAY.DAT(认证文件)。
载荷布局:
[1..16]:与 ProductID XOR 出主密钥。
[17..50]:是图像 LCG 常数区(Mul1/Inc1/Mod1/K_offset/Seed1、Mul2/Inc2/Mod2/K_size/Seed2,前 4 个是 4B Long、后 5 个是 2B Integer 符号扩展)
[0x25]起是 K_script(剧本偏移)。
[64..103] 是授权文本 "Official Full Registered License\0" ^ 0x83 防篡改填充。
可确定常数:
K_offset=0xB63C15A2,K_size=0x9B07,K_script=89。
剧本解密(DataMAIN.DAT):
① Knuth 洗牌(`Rnd(-1); Randomize(16177)`,生成 L/2 个位置对后倒序交换)
② 前 6336B 为章节偏移表
③ 逐字节 `^ 0xE6`,且**仅正式版**(Diff==0)再 `^ ((pos×K_script + 11511) mod 240 + 15)`(pad 函数 `0x566EA0`,字节读取循环 `0x573ABB`)。
解密结果为 UTF-16LE 剧本流。
然后就到这里卡死了。
YB002有二次加密,导致游戏能进但画面全黑。
------------------------
(注:我到这里力竭了——实在无心继续逆向,所以接下来请看AI表演。省流:认证Key同时也是解密key,穷举量级过大,且FP舍入噪声导致没有快速验证手段)
## 已判明事实(逐条钉死,含证据位置)
### 包格式
- `JGLB`/`JADV-03N` 头 16B;索引在 16 起、8B/条、181 槽;**索引 XOR(K_off/K_size)与双 LCG 只用于正式版 YB002**;YB001/YB006 为明文索引 + 前 8 字节 `^E6..ED`;YB006 索引偏移为 1-based。
- **条目 ID → 槽位是 1-based**:剧本 ID N 读索引槽 N-1(`sub ax,1; imul ax,8; add 10h; add 1`,`0x564DDA-0x564E02`)。
- 空条目惯例:stored `(0,0)` → 解码出巨偏移 → Get 越界被吞 = 静默黑;stored `(K_off,K_size)` → 解码 `(0,0)` → 弹「ファイル参照エラー7(IDxxxのデータは存在しません)」并终止。
### 图像容器格式(两包通用)
`[19B 头: D9F0E103 114D47A4 + 参数] [~378B Photoshop IRB] [128×96 缩略图 JPEG(带 FFD8)] [8BIM 块] [640×480 主 JPEG(无 FFD8,从 COM/APP14 起)]`。主图抽取法:缩略图 EOI 后第一个 FF 段起、补 FFD8。
立绘/差分(槽 140+):BMP 变体(自定义 2 字节魔数 `4C B9`,BITMAPINFOHEADER 在偏移 13,8-bit 调色板)——重建为标准 BMP 只需重写 14B 文件头。
### 显示链路
- `Proc_6_46`(`0x567740`)按 `[58323Ah]/[5831EEh] > 0` 触发加载,`Diff`(`0x583038`)只作包选择器(-1→YB001,0→YB002),无互斥门禁(早年笔记的怀疑是 VB Decompiler 伪码误读)。
- 解密→写 `C:\WINDOWS\Tempgrp.000`→`LoadPicture`(VB6 Global vtable+0x44)→赋 PictureBox→`Kill`。**无任何自定义解码器**(全代码节魔数扫描为零);也无涂红/压图惩罚暗桩——标题左上角红块只是 PictureBox 默认底色。
- 标题:正式版读 YB002 的 id 130(槽 129),体验版读磁盘 `Title.bmp`。
### 剧本/热点
- `YB004.DAT` = 140 张背景热点掩码(每张 3,072B = 64×48 格,包大小逐字节吻合);`YB003.DAT` = 19 张立绘叠加掩码(30×48=1,440B)。点击 `(X/10, Y/10)` 寻址得热点号 → CLJUMP 跳剧本块。**掩码与 YB002 无关、公开包完好**。
- 全部掩码已导出 `extracted\masks\`(含放大预览 BMP)。
### 内容恢复终局
- 共享条目 72 个:YB001 孪生提供完整主图/立绘(已验证可解码、可显示)。
- 3 张大 CG(槽 18/24/70):AI 虚构版(非原图)。
- 标题(槽 129):用 Title.BMP 直填。
- **56 张正式版独有图:不可恢复**(穷举证据见暗桩 5)。
- 原包 46 个空槽(含 8/36/44/49-50/66/79-98/124-128/130-134/137-139/159/173/175-177/179-180)原本就空。
---
## 尝试过的手段(含失败)
| 手段 | 结果 |
|---|---|
| 433-bit RSA 分解(yafu GNFS) | ✅ 成 |
| 伪造 YBPLAY(双层 ProductID XOR + 自签) | ✅ 过全部校验,剧本/标题/共享图实机正常 |
| factory_stream 攻击(gcd / z3 FP64 / HNP / 12 亿字典 / VB6-Rnd 13 映射 × 2^24 / Rnd 公式 6 族 × 2^24) | ❌ 全灭(该层后已被证明无需再碰) |
| 重放攻击 keystream.bin(257,904B) | ⚠️ 仅前 ~21B 真;曾误判"~1KB 有效"(编码器表巧合) |
| 同尺寸对穷举 C(72,2) 建共识流 | ❌ 最长 1,139B(立绘对,结构性巧合),典型 21B |
| 原流 LCG 种子反推(S2 全空间 + 代数解 A/C × 3 种模数) | ❌ 无锚点,无解 |
| UAC/管理员权限假说 | ❌ 被 VirtualStore 实证推翻(BGM MIDI 测试期间正常落盘) |
| v3/v4 重打包(容器剥离/转码) | ❌ 当时未知 off-by-one,全部死于首字节脏 |
| **v5 重打包(索引偏移 +1 补偿 + YB001 真内容 + AI CG + Title.BMP)** | ✅ **实机图像显示正常** |
---
## 汇编段结论速查
| 地址 | 内容 |
|---|---|
| `0x564B70` | Proc_6_40:图像解密加载核心(索引→Get→双 LCG→写 Tempgrp.000→LoadPicture→Kill) |
| `0x564DDA-0x564E02` | 条目 ID→槽位:`(id-1)*8+16+1`(1-based 证据) |
| `0x564E40/0x564EC2` | 索引 XOR 仅正式版分支执行(`test Diff` 后跳过体验版) |
| `0x564F3F-0x564F4C` | 内容 Get:位置=解码偏移(1-based → 实际读 offset-1,off-by-one 现场) |
| `0x565799-0x5659DA` | 双 LCG 循环:每条目 reseed 到固定种子(流逐条目 100% 相同) |
| `0x5659E3` | On Error Resume Next(静默吞错起点) |
| `0x565A04-0x565B01` | `GetWindowsDirectoryA` + `\Tempgrp.000` 拼接与打开 |
| `0x565B15` | Diff 分支:正式版 Put Long 数组 / 体验版 Put Byte 数组 |
| `0x565DE4` | 空条目分支(写 `windir+TMP\Tempgrp.000`,报错码 7) |
| `0x567740` | Proc_6_46:BACK/CHAR 门控与 BitBlt 合成 |
| `0x566EA0` | 剧本 pad 函数(K_script 来自 `[583354]`) |
| `0x573ABB` | 剧本字节读取循环(^E6,正式版再 ^pad) |
| `0x55C5A0/0x55C6C0` | LCG1/LCG2 本体(Variant floor 模) |
| `0x55C7E0` | 许可证综合校验(ProductID + YBPLAY + 包哈希)→ `[5832C2]=0x34E8`、`Diff=0` |
| `0x558F10-0x55916E` | exe 自哈希反篡改 |
| `0x55BD62` / `0x5678A8` | ExitWindowsEx(4,0) 强制关机陷阱(启动 / 循环 1/16 随机) |
| `0x563550` | 标题初始化(正式版读槽 129 / 体验版读 title.bmp) |
---