11

Khorina · 8月8日

牛掰!这老哥用显微镜摄取芯片ROM,还原了芯片的二进制固件。

最近在github上看到了一个很让人叹为观止的项目。

作者通过显微镜摄取芯片ROM,将里面的二进制固件给还原了。搞芯片和BSP的朋友都知道这意味着什么。

于是翻译这篇文章与大家分享,受限于英语水平,如有不当之处,还请海涵。

  • 原文:GameBoy ROM Tutorial[1]
  • 译者:TrustZone

嘿,各位:

这是一篇关于掩码ROM恢复的简短教程,我们将从Nintendo GameBoy的掩码ROM照片开始,最终得到一个可以反汇编或模拟的ROM文件。

GameBoy是一个很好的目标,因为它使用的是所谓的Via ROM,这意味着金属Via位于各层之间,用于编码各个位,这些位可以从芯片表面读取。ROM的体积也足够小,我可以将其包含在Github存储库中,这样你就不会因为一些小的位错误而耗费数周的时间去调试了。

来自诺克斯维尔的祝福,

——特拉维斯·古德斯皮德

摄影

我们会从dmg01cpurom.bmp开始,这是我在家中的实验室拍摄的,拍摄前我先用硝酸将芯片去盖,然后用丙酮超声波浴清洗。这颗芯片不需要用氢氟酸去层或用Dash Etch溶液(由硝酸、氢氟酸和乙酸组成)进行位染色。

这张照片是在我的金相显微镜下以50倍放大拍摄的二十二帧图像,然后在Hugin软件中拼接而成。生物显微镜不适用,因为硅基底对可见光是不透明的;在金相显微镜下,光线从样品上反射,而不是穿过样品。

我原始的照片对于Github来说太大了,所以你将要处理的版本分辨率有所降低。这里避免了有损压缩,因为它可能会干扰图像识别。

如果你自己拍摄了DMG-01-CPU芯片的照片,这里的说明也同样适用。

位提取

在本教程中,我们将使用我的CAD程序MaskRomTool来提取位,这是一个用于快速位提取的工具。

首先,编译MaskRomTool并安装它。如果你熟悉Unix命令行,你希望可执行文件maskromtool和gatorom在你的 $PATH中。如果不熟悉,也不用担心,因为所有功能也可以从图形用户界面(GUI)中获得。

在Windows和macOS上,你可以通过使用预构建的发行版来避免编译代码。当代码感觉特别稳定时,这些发行版会每隔几个月编译一次。

安装并运行后,使用MaskRomTool打开dmg01cpurom.bmp。

image.png

注意灰色十字线是如何跟随你的鼠标移动的。它们开始时是直的,但很快就会倾斜以匹配你在ROM上放置的行和列线。这允许你预测相同角度的重复行和列将落在何处,因为大多数图像都是倾斜的,但大多数位都是完美的直线。

同时请注意,ROM中的位以规则的行对和八个规则列的组出现。在MaskRomTool中,你需要放置行和列,但对于匹配原始图像的分组没有严格的限制。如果你发现你可以可靠地放置一条贯穿整个图像宽度的巨大行,或者一条贯穿整个图像高度的巨大列,那就大胆地去做吧。如果图像是歪斜的,你需要用一条非常短的线来绕过错误,那也没问题。

导航

要在图像中移动,你可以使用鼠标或笔记本电脑的触摸板。但更推荐使用鼠标,因为右键点击更方便一些。

按下鼠标中键并拖动背景可以稍微滚动,或者在触摸板上使用两根手指来平移屏幕。如果按住Shift键,平移速度会更快。

在这些项目中,缩放功能非常重要。QAZ键用于缩放,其中Q键可以快速切换到原始分辨率,A键和Z键用于放大和缩小。对于鼠标,按住Ctrl键并滚动滚轮也可以调整缩放。对于触摸板,你可能需要使用捏合动作来缩放,但这只在你的操作系统支持此功能的情况下有效。

先花点时间在ROM照片上移动,猜猜看不同的结构是什么。之后,我们将开始标记图像。

image.png

放置行

我们先从几个短行开始,稍后再尝试长的。首先,点击最左边位的左侧一点,然后将鼠标向右移动但不要点击。而是按下R键来放置一行。这两点之间会出现一条细黑线。

你可以重复这个步骤来放置所有的行,但这会很费力,而且对于非常长的行可能会涉及很多滚动。相反,将鼠标保持在右侧但稍微向下移动。当你的十字线对齐行时,按下Shift+R或空格键来放置另一条长度和角度相同的行。

在多个行上重复此操作应该很快就能标记出它们。在以下截图中,我已经标记了前八行的短段。

一旦你掌握了仅从右侧标记重复行的技巧,为了节省时间和精力,你也可以在整个图像上标记它们。如果直线不能穿过整个图像,那么标记较短的长度或更好地对齐你的全景照片。

如果你将行放置在了错误的位置,有几种方法可以移动它。首先,用鼠标左键拖动一个框来选择一条或多条线,然后用鼠标右键拖动它们来移动。箭头键也可以移动所选内容,S键会将单条线的位置设置为新的终点。

image.png

识别位

为了识别位,软件不仅需要您提供的位位置,还需要一个阈值和颜色通道来区分这些位。点击“编辑”,然后选择“选择位阈值”以查看以下图表并选择您自己的阈值。

image.png

前64位的直方图显示了所有三个颜色通道中的间隙。绿色通道中的间隙最大,因此我会在该通道中将阈值设置为172。请注意,当您更改阈值时,位框是如何自动调整的。

尽管蓝色和红色通道也可以用于此图像,但我们想要使用绿色通道,因为它具有最大的间隙。当我们开始累加图像中的所有位时,较大的颜色距离将确保我们获得更少的位错误。

image.png

一旦你设置了前六十四位,点击“查看”和“ASCII预览”来查看它们。不是很棒吗?

11101011
01111111
00110111
01101111
10110001
01101110
01011100
10110101

更多位

既然你已经体验了识别六十四位,那我们现在就来识别所有的位。

首先,通过删除dmg01cpurom.bmp.json并在Mask ROM Tool的新实例中重新打开dmg01cpurom.bmp,或者批量擦除你的线条,来清除你之前的工作。批量擦除是通过拖动选择线条,然后按D键将它们剪除来完成的。

(严格来说,你也可以用很多非常小的行和列来标记图像。我之所以不推荐这样做,是因为它太费时间了。)

在擦除线条后,放置一行从屏幕的最左侧到最右侧。如果你重新开始而不是删除之前的工作,有时先画一条较短的行会有所帮助,这样十字线的角度就会与图像倾斜的角度相同。你可以使用R键尝试画一条行,然后使用D键删除它,而软件不会忘记你的第一个起始位置。

在画完第一条线后,将鼠标移到照片的右侧,每经过一行时按Shift+R或空格键来放置一条线。如果你发现你标记的位稍微有些偏差,你可以使用S键来设置最后一条线的位置,将其移动到新的鼠标位置。箭头键和右键拖动也会重新定位它,同时位的值会随着位置的变化而变化。

如果行特别规则,你可能一次放置几个。要做到这一点,用鼠标左键选择一些线条,然后按Shift+D复制这些线条的集合。然后可以用右键拖动将这些线条移动到新的位置,而原始位置会保留一份副本。

在画完长行之后,画列。只需在第一个位的上方点击一次以设置起点,然后在最后一个位的下方按C键来画一列。Shift+C将在另一个端点处放置相同角度的新列,因此你可以遍历图像并在短时间内绘制所有列。

image.png

当所有位都设置完毕后,使用“编辑/选择位阈值”来稍微调整阈值。注意,随着更多的位被设置,曲线变得更加平滑,而且151可能比172更合适。

image.png

发现和修正错误

将所有位都标记出来是一种很棒的感觉,但这通常并不是结束。在继续解码ROM之前,最好进行一些快速的合理性检查,确保没有犯下任何错误。

使用V键或DRC/评估规则(Evaluate Rules)来对你的设计进行一些快速的合理性检查。例如,如果你放错了一条线,某个位的颜色可疑地接近阈值怎么办?你可能会得到一个像这样的DRC错误,你可以通过更正线条的位置来解决这个问题。每个设计规则检查(DRC)违规都有一个位置,并在图形用户界面(GUI)中以黄色框的形式出现。E键将跳转到列表中的下一个错误位置。

image.png

虽然像线条放错这样的错误是你的责任,但那些不是你的错误的错误也必须被纠正。有时照片上会混入一些灰尘,遮挡了采样位置的位的值。有时化学错误会使位变得难以看清。

在这种情况下,当你比机器更了解情况时,请将鼠标放在该位上并按Shift+F来强制设置其值,并在该位周围放置一个小的绿色框。如果应用了错误的值,再次按Shift+F将会翻转它。

image.png

经过这一切之后,位终于完成了!

11101011111100101100101100110010011000110111110000100001011100101110000000110011110001001001001011000100001011110001101100001000
01111111011100110111111101100011001010110100111100000110101010110011001111110011001010111011000000111000001011101101011011101111
00110111110110110111011111010111011001101001011101111111110110100111000101110010010110000101011101110001111101110111101111011000
01101111111000111110111011110110001011100101011010100010001110000111100000111010011111000111001100101111010000110100111111101001
10110001001100001011100110110111000110011101100111100000111100111111011010110001111111100111011010111010000110100100001100010011
01101110011100110110100100110111011100110101101001001111111100110010111110100011001110011010011101111010000111100111001010110010
01011100011101111111110001110111101100000101101100111000011100010011000011110101001100001011111000110000100110010111011111010010
10110101110101111011101001011111001110101111101000010101111100011101011111000011111010111010101100001110011110011011011111000101
00011111000101000001101110011110101111001111000011111011011100000100011011010000110100111001100100110011110101000101101110110110
11011001000101100111100100011011001110010101010100001101111101110110010110000111010101101101111010101100101100101101111110010111
11111111111110011111101101010101001101111101000010100110101010011011010011111001101101001101010110101010010101011110010110100011
01011110111110100001111011010110001000011101000000111011001011100101001111101110100110110000101000101011100001000001111000100001
11011000100010111011110010010101001011000111000010011000111110001111011011000000100111001101010010001100111101100010100110111001
11111011001010011111101000111101001100101111100110110101011111011011110110000101001011001101000100110111001101011110110110001010
00111111111101100011101111110010001011001111010000011111101111010011011111110111001101110111010101011111111110110101011100111111
10101101111101111000110111110110100001010111100111001101101110100100111111000011011110101010001101011100100011111100111110011111

关于命令行界面(CLI)

到目前为止,我们一直在图形用户界面(GUI)中使用这个工具,但当你处理更大的项目时,你会想要使用命令行界面(CLI)来自动化一些操作。默认情况下,它会启动图形用户界面,因此当你单独运行它时,你会想要添加“-platform offscreen -e”参数,以避免打开窗口并在完成后退出。

Usage: maskromtool [options] image json
Mask ROM Tool

Options:
  -h, --help                 Displays help on commandline options.
  --help-all                 Displays help including Qt specific 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 <Default>        Bit Sampling Algorithm.
  --diff-ascii <file>        Compares against ASCII art, for finding errors.
  -a, --export-ascii <file>  Export ASCII bits.
  -o, --export <file>        Export ROM bytes.
  --export-histogram <file>  Export histogram.
  --export-csv <file>        Export CSV bits for use in Matlab or Excel.
  --export-json <file>       Export JSON bit positions.
  --export-python <file>     Export Python arrays.
  --export-photo <file>      Export a photograph.

Arguments:
  image                      ROM photograph to open.
  json                       JSON lines to open.

假设我们有ROM文件dmg01cpurom.bmp和与之匹配的.json文件,我们可以在macOS或Linux中通过命令行界面(CLI)像这样导出位。在Windows中,我们调用maskromtoolcli.exe而不是maskromtool,以保持控制台连接。

dell% maskromtool -platform offscreen -e dmg01cpurom.bmp -a DMG_ROM.txt
Allocation limit was  128 MB
Disabling allocation limit.
Loaded background image of  9000 , 2249
Done loading, now marking bits.
Exporting to ASCII.
dell%

解码ROM文件

现在你已经有了你的项目按物理顺序排列的位,但这与反汇编器或模拟器更喜欢的逻辑顺序的字节截然不同。我们将首先以图形方式完成这个操作,然后也会看到如何在Unix命令行中执行它。

在开始之前,请安装MAME并确保其反汇编器unidasm在PATH中。如果你没有这样做,求解器仍然可以工作,但你将无法看到反汇编的代码。

图形化解码

你可以通过“编辑/解码”手动调整解码设置。首先,将反汇编架构设置为LR35902,并将字大小设置为8。翻转、旋转和存储体(banking)将在稍后为你解决,底部的标志列表显示了将传递给GatoROM用于在命令行中解码的选项。

image.png

你可以使用“查看/求解器”来求解特定的字节序列或Yara规则。双击某个解决方案将重新配置解码器并更新十六进制和反汇编视图,以便可以快速搜索它们。

首先,使用求解器的“字节”选项卡来求解0:31,1:fe,2:ff,这意味着前三个字节将是31 fe ff。这是LR35902机器代码,用于将堆栈指针设置为0xfffe。双击解决方案-z--decode-cols-downr-i-r180--flipx将把这些设置应用到解码器上。

image.png

“View/HexPreview”将以十六进制实时显示解码结果。选择某些字节后,你还可以使用“View/HighlightHexSelection”来高亮显示这些位在你的项目文件中的位置。

image.png

使用GatoROM进行解码

GatoROM是随MaskRomTool一起提供的一个位解码器。它运行在命令行下,但实际上它使用的是与GUI求解器中相同的库。

首先,我们需要一个ROM位的ASCII文件。你可以使用MaskRomTool的GUI中的“文件/导出/ASCII”来生成这个文件,或者在命令行中使用maskromtool -platform offscreen dmg01cpurom.bmp -a DMG_ROM.txt -e来生成。

这是如何根据ROM进行求解,已知前两个字节是31和fe。-z标志表示我们希望使用Zorrom兼容模式,它在写入正确的解码到DMG_ROM.bin之前,准确地识别了三个潜在的解码。

dell% gatorom DMG_ROM.txt --solve --solve-bytes "0:31,1:fe" -z -o DMG_ROM.bin
Grade 50        31 11 47 fe 3e f9 1e 0e         -z --decode-cols-left -i -r 180 --flipx 
Grade 50        8a fe a8 01 d4 52 b0 a4         -z --decode-squeeze-lr -r 180 --flipx 
Grade 100       31 fe ff af 21 ff 9f 32         -z --decode-cols-downr -i -r 180 --flipx 
Exporting       -z --decode-cols-downr -i -r 180 --flipx 
dell%

我们也可以用其他方式进行搜索。如果我们知道31 fe ff存在于图像的某个地方,但不知道确切的位置,怎么办?这会产生三个潜在的解决方案,如果需要,我们可以将它们转储到文件中以进行探索。

dell% gatorom DMG_ROM.txt --solve --solve-string "31,fe,ff" 
Grade 100       f5 06 19 78 86 23 05 20         --decode-cols-downl -i -r 0 --flipx 
Grade 100       31 fe ff af 21 ff 9f 32         --decode-cols-downr -i -r 0 --flipx 
Grade 100       f5 06 19 78 86 23 05 20         --decode-cols-downl-swap -i -r 0 --flipx 
dell%

参考资料

[1]

GameBoy ROM Tutorial: https://github.com/travisgoodspeed/gbrom-tutorial/blob/master/README.md

作者:Hcoco
文章来源:TrustZone

推荐阅读

更多物联网安全,PSA等技术干货请关注平台安全架构(PSA)专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入PSA技术交流群,请备注研究方向。
推荐阅读
关注数
4569
内容数
186
Arm发布的PSA旨在为物联网安全提供一套全面的安全指导方针,使从芯片制造商到设备开发商等价值链中的每位成员都能成功实现安全运行。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息