travisgoodspeed/maskromtool
GitHub: travisgoodspeed/maskromtool
从掩模 ROM 芯片裸片照片中可视化标注、提取和还原固件位数据的 CAD 工具。
Stars: 371 | Forks: 26
大家好,
这是我的 CAD 工具,用于拍摄掩模 ROM 的照片并
提取位数据,从而恢复 ROM 的内容。
该工具中的键盘快捷键*不是*可选的。 在开始探索之前,请阅读
下面的 GUI 文档。
如果你觉得这个工具有用,请为自己或聪明的学生购买一本我的书
[微控制器漏洞利用](https://www.amazon.com/Microcontroller-Exploits-Travis-Goodspeed/dp/1718503881)。
--Travis Goodspeed

## 示例
[gbrom-tutorial](https://github.com/travisgoodspeed/gbrom-tutorial)
教你如何从 GameBoy 掩模 ROM 的照片开始,
逐步制作出准确的 ROM 镜像。
[MYK82 ROM](https://github.com/travisgoodspeed/myk82rom) 包含了
Fortrezza 卡中 MYK82 芯片的完整 ROM 转储。
这是 Clipper 芯片的继任者,该存储库不仅包含
所有的 ROM 位,还包含用于纠错的重拍图像。
[wersi-slm2-51173](https://github.com/travisgoodspeed/wersi-slm2-51173/)
是来自音乐合成器模块的 Zilog Z8 ROM。
[atar862n-rom](https://github.com/travisgoodspeed/atar862n-rom) 是
ATAR862N 芯片中的 MARC4 ROM。
[mk51fx2500](https://github.com/travisgoodspeed/mk51fx2500) 是
来自 Casio FX-2500 计算器及其苏联克隆版
Электроника МК51 的 ASIC。
[EMZ1001ROMs](https://github.com/travisgoodspeed/emz1001roms) 包含
南斯拉夫 EMZ1001 微控制器的照片,它是 S2000 的授权克隆版。
这些解码尚未被破解,这或许使它们成为有趣的挑战目标。
[msp430f149rom](https://github.com/travisgoodspeed/msp430f149rom) 来自
MSP430F149。 该芯片与 MSP430F449 密切相关,
并使用相同的解码器进行解码。
## 发布更新日志
`master` -- GoodASM REPL 现已在 Windows 上支持自动补全。
放弃对 x86_64 macOS 的支持。 可选的 Yara-X 支持。 用于
位阈值的 HSL 色彩空间,配合对眼睛更友好的位颜色直方图。
“打开最近的文件”菜单,QSettings。 宽和高的
采样大小现在显示在视图中。 修复了同时
拖动直线和位时的崩溃问题。 将单个位导出为单独的
图像。 部分支持 CPack 以生成 `.deb` 软件包。 MARC4
和 MSP430 解码由仿射映射定义。
2025-06-01 -- CLI 和 GUI 功能用于处理模糊/损坏的
位,当植入物 ROM 的某些部分曝光不佳时非常有用。 求解器
现在支持使用
[GoodASM](https://github.com/travisgoodspeed/goodasm) 的 grader
类。 `goodasm` 和 `gatorom` 在 macOS 中具有正确的 RPATH。
2025-04-12 -- 通过避免列表中的深拷贝提升性能。
状态栏中正确的位计数,且状态栏现在使用
等宽字体。
[GoodASM](https://github.com/travisgoodspeed/goodasm) 现在通过
git 子模块作为汇编器被包含进来。 剪切、复制和粘贴按键
绑定现在可以像在其他 GUI 中那样正常工作了。
2024-08-18 -- GatoROM 的 solver-set 选项现在使用描述性的
文件名。 GUI 现在可以通过 File/Export/SolverSetBytes 导出一组
求解结果。 更清晰的选择矩形。 当用户混淆时,`R` 和 `C`
现在将绘制正确的线型。 `^H` 现在设置初始位置。 缩放
和移动键现在可在第二个视图中工作。 完全重复的线现在
会在 DRC 期间通过 `V` 键被剔除。 行和列现在存储为排序列表,
而不是集合。 行和列在文件导出中现在具有一致的顺序。
在位标记、后台位标记和对齐方面的性能提升。 macOS 的
通用二进制文件。 RomAlignerTilting 在 bank 之间有间隙的
设计中效果更好。 不在视图内的位在
拖动时不再绘制,从而加快了调整长线组的速度。
2024-07-14 -- 修复了删除双重选择项时的崩溃问题。 Delete
和 Backspace 现在可以像 `D` 一样删除对象。 多个反汇编器。
解码阈值更改时,解码结果现在会实时更新。
2024-06-23 -- Yara 规则求解。 稳定性改进。 十字准线
更新为选定线的角度。 空格键现在重复上一条
线,无论是行还是列。 可以选择多个项,
SHIFT+D 复制它们。 使用 SHIFT 选择以添加更多线,
或使用 CTRL(macOS 上为 CMD)移除线。 右键拖动可移动多条线,
仅预览相关的位。 十字准线和选择颜色现在可以
选择。 缩小时背景不再平铺。
2024-05-19 -- 强制设置位值时,DRC 违规现在会被清除。
用于绘制 GNUPlot 中颜色分布的直方图导出。
支持 Wayland。 在 CLI、GUI、求解器
和基本解码器中支持显式字长。 求解器集合,
将所有潜在的解决方案导出为二进制文件。 不可靠的
对齐器已被弃用。 GUI 求解器。 反汇编器调用
MAME 的 Unidasm。
2024-01-28 -- 撤销和重做。 字符串对话框。 反斜杠键用于
图层可见性。 可靠的对齐算法。 关闭主窗口
关闭应用程序。
2024-01-01 -- 修复了在求解奇数大小时 Z8 解码器中的总线错误。
GatoROM CLI 中的详细模式。 `squeeze-lr` 模式现在位于 GUI
解码器中。 用于清除所有位修复的编辑菜单项。 `E` 将选择
下一个 DRC 违规。 完全垂直的图像不再破坏
对齐算法。
2023-12-07 -- 选择高亮。 状态栏中的行/列计数。
ASCII 求解器。 修复了求解器中因 ROM 尺寸
不当导致的多次[崩溃](https://github.com/travisgoodspeed/maskromtool/issues/59)。
GUI 中的 GatoROM 解码。 移除了冗余的解码器。 十六进制
查看器以及选定字节的高亮显示。
GatoROM CLI 现在对遇到非法访问时退出要求非常严格。
[Zilog Z8](https://github.com/travisgoodspeed/maskromtool/issues/76) ROM 支持。
2023-09-13 -- 用于禁用 OpenGL 的 CLI 选项。 打印支持。
正常工作的 Windows 构建。
2023-08-06 -- OpenGL 现已正常工作并成为默认选项。 包含
GatoROM 用于位解码。
2023-07-20 -- 副屏支持。 高向采样。 修复了
在删除线后按 `V` 时的崩溃问题。
2023-06-17 -- 添加了 X86_64 和 ARM64 上的 macOS 支持。
2023-05-30 -- 首个 Windows 版本发布。
## 构建
该工具可在 Windows、Linux、FreeBSD 和 MacOS 上运行,使用带有
QtCharts 扩展的 QT6。
从 CLI 构建该工具最为简单。 在 Debian Bullseye (11.x) 中,
```
% sudo apt install make gcc g++ cmake git qt6-base-dev libqt6charts6-dev \
qt6-translations-l10n linguist-qt6 qt6-l10n-tools qt6-tools-\* qt6-image-formats-plugins \
libreadline-dev qt6-declarative-dev pkg-config
% git clone https://github.com/travisgoodspeed/maskromtool/
...
% cd maskromtool
% git submodule init
% git submodule update --remote
...
% mkdir build; cd build
% cmake ..
% make -j 8 && sudo make install
```
在 Windows 和 macOS 中,请使用 [Qt 开源版](https://www.qt.io/download-qt-installer-oss)安装程序,
务必包含 Charts 和 Image Formats 扩展。 然后作为项目打开
`CMakeLists.txt`。 `Ctrl+B` 将随后编译 `maskromtool`。
如果您的导入出现问题,例如选择了错误的 Qt 安装,请删除
`CMakeLists.txt.user` 并重新打开项目以重试。
为了 Windows 和 macOS 用户的方便,我们还提供了一些
[预构建版本](https://github.com/travisgoodspeed/maskromtool/releases)。
在 macOS 上,如果您收到签名无法识别的警告,
可能需要运行 `xattr -dr com.apple.quarantine *`。
要在 macOS 上构建,首先安装 XCode,[Homebrew](https://brew.sh)
和 [Qt 开源版](https://www.qt.io/download-qt-installer-oss),
遗憾的是这需要一个账户。 之后,您可以在 QT Creator 中打开
`CMakeLists.txt` 或使用发布脚本进行构建。
(如果脚本的 Qt 版本低于您的版本,请编辑该脚本。)
```
% ./buildrelease-macos.sh
... (ignore errors about signing
% open release/maskromtool.app
```
您也可以在没有官方 Qt 安装程序或 App 的情况下构建它,
仅通过 Homebrew 即可。 这大致类似于我们在 Linux 中的操作。
```
% brew install cmake emacs qt pkgconfig
% git submodule init
% git submodule update --remote
...
% mkdir build; cd build
% cmake ..
% make -j 8 && sudo make install
```
## 可选库
### YaraX
[Yara-X](https://github.com/VirusTotal/yara-x) 是一个
在恶意软件研究领域流行的模式匹配库。 MaskRomTool
和 GatoROM 将其作为可选库支持,用于求解未知的布局。
当 PkgConfig 可用并且其 C API
[已安装](https://virustotal.github.io/yara-x/docs/api/c/c-/)时,Yara-X 会自动被包含。
```
% git clone https://github.com/VirusTotal/yara-x
...
% cd yara-x
% cargo install cargo-c
...
% cargo cinstall -p yara-x-capi --release
... (If error here, make your user own /usr/local/lib and include.)
```
## GUI 使用
首先使用 File/Open ROM 打开一张 ROM 芯片的照片。 尽量
使用未压缩的格式,但请注意 macOS 不喜欢 TIFF 文件。
按住 control 键(macOS 上为 command 键)同时滚动鼠标
滚轮将进行放大和缩小。 您也可以在触控板上双指缩放。
使用鼠标中键拖动可平移,或根据您操作系统的喜好
用双指滚动。
根据任意约定,位应排列在长列中,行较短。 如果
解码线可见,它们应位于图像的顶部。 您可以随意
从某个方向拍摄照片,然后旋转它进行标记。
保存项目时,图像的文件名将附带 `.json` 扩展名。
这个经过排序和缩进的 JSON 文件适合在 Git 存储库等
版本控制系统中使用。
这些键盘按键提供了您的大部分输入。 要绘制
线,首先单击一次选择起始位置,然后当鼠标位于
结束位置上方时按下该键。 删除项或
设置其位置将应用于最近放置的线,
除非您拖动一个框来选择线。
通过按住鼠标左键拖动来选择一个项目,
并观察它是否变绿。 最近放置的项目会被
自动选择。 某些命令作用于多个选定的
项目;而另一些仅作用于一个。
您可以使用 `D` 删除错误,或使用 `S`、箭头键或
右键拖动稍微调整其位置。 移动期间,为了性能,
不相关线的位可能会被隐藏,按下 `M` 键或
释放鼠标右键将重绘它们。
在 macOS 上,`^` 表示 Command 而不是 Ctrl。
```
Tab -- Show/Hide bits.
\ -- Show/Hide rows and columns.
^\ -- Show/Hide background.
ALT \ -- Show/Hide crosshair.
R -- Draw a row from the last left-click position.
SHIFT R -- Repeat the last row.
C -- Draw a column from the last left-click position.
SHIFT C -- Repeat the last column.
SPACE -- Repeat the last row or column.
^X ^C ^V -- Cut, Copy and Paste.
D -- Delete the selected objects.
SHIFT D -- Duplicate the selected lines.
S -- Set the selected object to the mouse position.
F -- Jump to the selected item.
ARROWS -- Move the selected items.
right-drag -- Move the selected items. (SHIFT or ^)
middle-drag -- Pan the view.
^ wheel -- Zoom.
Q -- Zoom to zero.
A -- Zoom in.
Z -- Zoom out.
H -- Jump to home position.
^H -- Set the home position.
SHIFT F -- Force a bit's value. (Again to flip.)
SHIFT A -- Force a bit's ambiguity. (Again to flip.)
M -- Remark all of the bits.
SHIFT M -- Update hex decoding and disassembly.
V -- Run the Design Rule Checks.
SHIFT V -- Clear the DRC violations.
E -- Jump to next violation.
^Z -- Undo
SHIFT ^Z -- Redo
^S -- Save changes.
```
当您首次开始标记位时,软件尚未知道
1 和 0 之间的阈值。 您可以通过
`View` / `Choose Bit Threshold` 进行配置。
即使是最好的位也不会全部被完美标记,因此如果您发现
软件出错,请使用 `SHIFT+F` 强制设置位值。 `SHIFT+A`
功能类似,将位标记为模糊或已损坏。 `DRC`
菜单包含设计规则检查,将突出显示项目中的问题,
例如弱的位或对齐错误。
如果放置许多线变得乏味,请使用鼠标左键选择一组,
然后使用 `SHIFT+D` 复制整个集合。 您
可以接着用鼠标右键将其拖动到新位置,在
原始位置留下另一个副本。 如果为此
掉帧,请使用 `TAB` 键临时隐藏所有位,这将
极大地加快在密集区域移动多条线的速度。
十字准线将自行调整为您最近放置的行
和列。 这将使它们稍微倾斜以匹配您
照片的实际情况。
在标记位并使用 DRC 抽查其准确性后,
运行 File/Export 将其导出为 ASCII,以便使用
其他工具进行解析,例如 [GatoROM](GATOREADME.md)、
[Bitviewer](https://github.com/SiliconAnalysis/bitviewer) 或
[ZorRom](https://github.com/SiliconAnalysis/zorrom)。
## CLI 使用
除 GUI 外,该工具还具有命令行界面,
在脚本编写中非常有用。 使用 `--help` 开关查看最新
参数,如果您不希望 GUI 保持打开以供
交互使用,请使用 `--exit` 开关。
```
forum% maskromtool --help
Usage: maskromtool [options] image json
Mask ROM Tool
Options:
-h, --help Displays help on commandline options.
--help-all Displays help, including generic Qt options.
-v, --version Displays version information.
-V, --verbose Print verbose debugging messages.
--stress Stress test bit marking.
-e, --exit Exit after processing arguments.
--disable-opengl Disable OpenGL.
--enable-opengl Enable OpenGL.
-d, --drc Run default Design Rule Checks.
-D, --DRC Run all Design Rule Checks.
--sampler Bit Sampling Algorithm.
--diff-ascii Compares against ASCII art, for finding errors.
-a, --export-ascii Export ASCII bits.
-o, --export Export ROM bytes.
--export-histogram Export histogram.
--export-csv Export CSV bits for use in Matlab or Excel.
--export-json Export JSON bit positions.
--export-python Export Python arrays.
--export-photo Export a photograph.
Arguments:
image ROM photograph to open.
json JSON lines to open.
```
要在没有 GUI 的情况下运行,请传递 `-platform offscreen`。 如果程序
在 Wayland 下崩溃,请通过传递 `-platform xcb` 强制使用 Xorg。
在 Windows 上,可执行文件要同时拥有 GUI 并
保留 CLI 日志很困难。 我们通过生成两个
可执行文件来解决这个问题;请使用 `maskromtool.exe` 以运行 GUI,并使用
`maskromtoolcli.exe` 以运行 CLI。
一个单独的可执行文件 `gatorom` 封装了不带
图形界面的 ROM 位解码器。 详见 [GatoROM](GATOREADME.md)。
## 高层设计
我基于 `QGraphicsScene` 设计了 GUI。 底层数据
对象使用 QT 坐标系,使用浮点数以获得
优于像素的精度。
加载 ROM 照片后,用户在照片上放置列和行。
列和行的每个交叉点被视为一个位,可配置的
颜色阈值决定了该位的值。 如果照片被误读,
您还可以将该位强制设置为已知值。
一旦所有的位都被标记选择了阈值,
软件会将每个浅色位标记为蓝色 (0),每个深色位
标记为红色 (1)。 然后将这些位对齐到导出为 ASCII 的
行链表中,以供其他工具使用。
为了识别错误,一组设计规则检查 (DRC) 将评估
打开的项目。 虽然主要界面是 GUI,但也提供了
CLI 用于脚本编写和测试。
## 纠正位错误
虽然几千个位可能会被无误地标记,但更大的
项目将不可避免地需要管理它们的错误。
一个良好的开端是使用 DRC 检查并仔细配置
位阈值,直到没有明显的错误。 然后导航项目
并按 `tab` 键以显示和隐藏注释,确保
每个位都被正确识别。
当这不够时,例如对于几十或几百千位的 ROM,
对同一个 ROM 进行多次注释会有所帮助,
最好使用不同的照片。 在为每张照片
添加注释时当然会发生位错误,但它们会发生在
不同的地方。 然后,您可以对
`--export-ascii` 的输出使用 `--diff-ascii` 功能来比较图像,
协调它们的差异,直到您的所有项目文件一致。
## 采样算法
大多数 ROM 只需读取位中心单个像素的颜色即可
读取。 对于这些,`Default` 采样算法就可以
正常工作。

对于位去层处理有些过度的扩散 ROM,
位的中心没有独特的颜色,但它被
稍暗的线包围。 `Wide` 算法将在
采样其宽度大小的位后取每个通道中最暗的
颜色,`Tall` 执行相同的操作,但是是垂直方向的。

## 开发
非常欢迎对 Mask ROM Tool 提供补丁和改进,但请
不要在问题追踪器中滥发功能请求。 Pull request 应
通过 Github 页面提交,并且不应将项目与第三方库的依赖
纠缠在一起。
代码使用保守的 C++ 方言编写,极少使用
高级特性。 我已尝试彻底注释代码和类定义。
## ROM 解码器
[GatoROM](GATOREADME.md) 作为一个命令行解码器被包含,
用于求解位排列。 请参阅其自带的 README 文件获取 CLI
文档,特别是针对 GUI 尚不支持的求解器方法。
另外,GatoROM 在 MaskRomTool GUI 中被用作
解码库。 使用 Edit/Decoding 定义解码风格,
并使用 View/HexPreview 查看位到十六进制的实时解码。

从解码器中,您可以高亮显示十六进制字节并使用 View/Highlight
Hex Selection 可视化选定的字节。 这里我们看到的是
[MYK82 ROM](https://github.com/travisgoodspeed/myk82rom) 的前三个字,
它们将 32 位打包在每个位置中。 大多数反汇编器通过 CLI 路径
操作,但 [GoodASM](https://github.com/travisgoodspeed/goodasm) 是
静态链接的。

还支持脚本化求解器,其中通过简单的掩码或 Yara
规则描述预期的固件。 所有匹配项都会被枚举,
通过在它们之间跳转,您可以快速破译未使用
交织、行反转或其他复杂操作的图像。

## 相关工具
John McMaster 的 [ZorRom](https://github.com/SiliconAnalysis/zorrom) 是
一款优秀的解码器,也是该工具中解码库的灵感来源。
Adam Laurie 的 [RomPar](https://github.com/AdamLaurie/rompar) 可能是
首款实现开源的位标记工具。
Chris Gerlinsky 的 [Bitract](https://github.com/SiliconAnalysis/bitract/) 是
另一款用于位标记的开源工具,而
[Bitviewer](https://github.com/SiliconAnalysis/bitviewer) 是他配套的
用于将位解码为字节的工具。
Peter Bosch 的 [PLA Decode](https://github.com/peterbjornx/pladecode)
是一款用于提取旧 Intel 微代码的位标记工具。 请参阅
他 2020 年在 [Hardwear.io](https://www.youtube.com/watch?v=4oFOpDflJMA) 上的
演讲以获取更多详细信息。
标签:Bash脚本, CAD工具, GameBoy ROM, GoodASM, MSP430, ROM转储, Yara, Zilog Z8, 云资产清单, 半导体逆向, 图像位提取, 图像处理, 域名收集, 微控制器漏洞, 掩膜ROM提取, 数字取证, 硬件安全, 硬件黑客, 自动化脚本, 芯片解密, 逆向工程, 集成电路分析