DC_danelchen DC_danelchen
关注数: 4 粉丝数: 4 发帖数: 224 关注贴吧数: 4
MARK.R3 逆向实战 如果你也做过老游戏资源逆向,应该对这种场景不陌生: - 文件名看起来像图像包(`MARK.R3`) - 解压后确实“像图”,但一开始全是噪点- 参数改来改去,偶尔能看到箭头轮廓,又很快“跑飞” 这篇就记录我把 `MARK.R3` 从不可读推进到“可复用解析流程”的全过程,重点讲**最终可落地的技术链路**。 ---## 1. 先给结论:`MARK.R3` 不是“一张完整成品图”最终确认: 1. `MARK.R3` 外层是 `LS11` 压缩容器 2. 解压后存在稳定可识别图元(鼠标、箭头、边框/纹理片段) 3. 但它不是“按最终 UI 坐标排好的一张大图”,更像**运行时拼装素材仓库**所以“解压后直接当 BMP 展示”这条路,只能看到局部规律,不能直接得到最终界面。 ---## 2. 第一步:把 LS11 这层彻底打通 `MARK.R3` 的结构很规整: - `0x00..0x0F`:LS11 头 - `0x10..0x10F`:256 字节字典 - `0x110..0x113`:压缩长度(BE) - `0x114..0x117`:解压长度(BE) - `0x118..0x11B`:正文起始(通常 `0x120`) - `0x120..`:压缩正文 关键是索引流解码规则(`seg1 + seg2`)和回溯复制(`index>=256`)要严格一致。 这一步一旦实现正确,后面所有图像实验才有意义。 ---## 3. 第二步:找到“稳定出轮廓”的主窗口 在解压数据中,最有价值的一段是:`dec[0x3D0 .. 0x3D0 + 63*216)`这个窗口非常关键。基于它我们得到了第一条稳定链路: - 63 个 block- 每 block 216 bytes- 每 block 拆 4 个 plane - 每 plane 54 bytes- `54*8 = 432 bits = 24*18`,对应 `24x18` 的 1bpp 图像也就是说,`216 -> 4x54 -> 24x18(1bpp)` 在几何上是闭合的,不是拍脑袋参数。 ---## 4. 第三步:为什么“看起来对,又总有点不对” 你会遇到这些典型现象: - 能看见箭头/鼠标,但有时像少一列、少几行 - 某些块上下能接上,整体又不是标准网格 - 改 `grid`、`skip`、`fill order` 会导致“像对了又错了”这不是 LS11 错了,而是**组织层未完全还原**: - 有些数据更像帧流,不是纯 tile 表 - 可能存在锚点偏移/裁剪区 - `bbox` 是前景包围盒,不等于原始 tile 尺寸 ---## 5. 第四步:引入“流式切片” 作为第二主链路除了 63x216 结构链路,还需要一条**更中性**的读取方式: - 把 payload 当连续 1bpp bitstream - 可选 `byteSkip`- 指定 tile 尺寸(如 `24x24`/`20x20`) - 再按 row-major 或 column-major 排 atlas这条链路非常适合做形状探测和参数扫描,不依赖过早假设“每块一定是什么语义”。 ---## 6. 流式切片拿到了什么结果 流式切片这条线,拿到的结果可以概括为 4 点: 1. 能稳定切出可识别图元 在 `1bpp` 流式读取下,已经能反复得到鼠标/箭头等高辨识度形状,不再是纯噪点。 2. 能验证“参数影响的是排布,不是解压正确性” `byteSkip`、tile 尺寸(如 `24x24`/`20x20`)、row/column 填充顺序会明显改变图像排布与对齐,但底层可识别结构是连续存在的。 3. 能定位高价值候选区 通过 sweep 与对照,锁定了多组可用候选(例如围绕 block 37/38/40/42 的图元连续性),支持后续继续做装配关系推断。 4. 证明 MARK 不是“单一整图直出” 流式切片下图元是“可读但重组态”,这和运行时拼装素材库的判断一致:数据是有组织规律的,但不是最终 UI 成品坐标图。 ---## 7. 给后来者的建议:别急着“锁死唯一算法” 逆向这类老资源时,最容易犯的错是: - 太早把一种显示结果当唯一真相 - 为了贴图效果不断硬编码补偿更稳的做法是: 1. 先锁定**可验证不变量**(容器、长度、几何闭合) 2. 再并行保留两套读取路径(结构链路 + 流式链路) 3. 最后才讨论运行时拼装规则这样你不会在“看起来差一点”的参数坑里无限循环。
三国志英杰传 FACEDAT.R3 解析的故事 凌晨的工位上,FACEDAT.R3像一块不开口的铁。任务看似简单:把240张头像提取出来、颜色修正、做成可复用资产。真正的难点是,它不是常规资源包,通用解码法一上去就是噪声、彩条、假轮廓。团队第一轮就起冲突:先“快出图”还是先“建证据链”?主角顶着进度压力,先做资料归档、时间线、外链原文落盘。很多人觉得慢,但这一步等于先画战场地图,防止后面每次“看起来像成功”都无法复盘。 接着三套常规算法连试:raw4bpp、planar、rle4bpp。图里偶尔冒出“像人脸”的结果,最容易让人上头。主角却把失败样本全留档,做参数扰动测试:同一数据换几种位序也能“像脸”,说明是假阳性。矛盾升级到方法论层面:相信肉眼,还是相信可复现性。答案很硬:单图惊艳不算赢,全量稳定才算赢。 转机来自外部线索:前240组索引,每组6字节(4+2),基址0x5A0。这条信息像钥匙。团队先做结构体检:偏移、长度、边界都能自洽,证明“怎么切块”基本正确。随后确认真正解码链在TFDED.COM,于是路线从“盲猜编码”转为“运行时取证”。通俗类比:之前像闭眼拆锁;现在是先借原钥匙开门,再研究锁芯结构。 黑盒链路搭起来后,PROBE0.COM负责三件事:喂入CHUNK0.BIN触发INT62h、从显存导出DUMP0.BIN、采样PAL0.BIN。第一批240张终于可见,gallery.htm也出来了。现场一度想庆祝,但主角压住:这只是“看得见”,还不是“解释得通”。 随后进入颜色战。先验PAL0.BIN,确认是标准VGA6bitDAC,不是“少一位”问题。再做网页对齐时发现,单靠边缘匹配会错绑相似头像,于是引入“8色最优置换分数”(8x8计数矩阵+8!置换),把“轮廓像”与“色层同源”分开。并强制全局一套LUT,禁止逐图漂移。通俗类比:不是给每个人单独开滤镜,而是先定全片统一调色规则。 用户又提出关键观察:背景色会变,不能让大背景压倒人物前景。团队加了“前景加权、边框剔除、透明前景对照”,效果确实改善,但仍有残差。这里出现阶段性迷雾:明明调色策略更科学了,为什么还有异常? 真正的大反转发生在输入链。对照索引长度后发现:大量块长度超过1302,而旧PROBE0只读1302字节,等于把数据截断再去解码。统计一出:240里有179张超过上限。修复很朴素却致命:inbuf和读入长度改到4096。全量重跑后same61/diff179,与统计严丝合缝。通俗类比:不是画师上色差,而是稿子被撕掉半页。 修复后,花屏类问题大幅下降。团队完成rfix重导出、全局重拟合、问题页重建,并把低分样本分流成两类:decode_suspects(解码可疑)与web_mapping_suspects(参考错绑可疑),避免把参考噪声误判为解码失败。至此,阶段一闭环成立:结构可解析、240可稳定导出、调色有统一算法、问题可分流追踪。 这场仗最“爽”的地方,不是一招破局,而是把混乱变成秩序:从“凭感觉像”变成“有证据对”,从“个人能跑”变成“团队可复跑”。下一阶段目标也清晰:把TFDED黑盒块解码翻译成纯TS状态机,用240张逐像素对拍,最终摆脱DOSBox依赖。一句话收束:阶段一解决了“门怎么开”;阶段二要解决“钥匙怎么造”。
1 下一页