Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
ME2-Writeup — 重建一个已死的USB协议:用热刀解锁手持设备的秘密,一段复兴被遗忘USB接口的多学科之旅 | Kitploit
工具/GitHubGitHub/coremaze/me2-writeup
嵌入式系统安全逆向工程数据恢复硬件黑客硬件安全二进制分析学习与教育固件分析
GitHubcoremaze/me2-writeup

ME2-Writeup

重建一个已死的USB协议:用热刀解锁手持设备的秘密,一段复兴被遗忘USB接口的多学科之旅

查看仓库
4824个月前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

用热风枪和刀逆向工程 ME2 的 USB

背景

2024 年,bjiru 上传了一个关于 ME2 手持设备的视频,这是一个大约 2008 年生产的玩具,其特色是能够通过 USB 在设备与在线世界之间同步积分和宝石。这款游戏极为小众,因此没有软件、驱动程序或资源被存档,至少直到 bjiru 公开了在线游戏客户端之前是这样。

我是 Miuchiz Reborn 的领导者,该计划始于 2015 年,旨在保存、逆向工程、模拟 并维护一款类似游戏的可用性,该游戏同样包含通过 USB 连接的在线部分和手持部分。由于类似的年代和游戏类型,ME2 早在 2018 年就由我的 Miuchiz 社区引起了我的注意,因为他们(错误地)认为两者可能具有架构上的相似性。尽管多年来我一直知道该设备的存在,但 bjiru 的视频最终促使我开始对其进行研究。

我的最初努力完全集中在重建使 bjiru 的计算机游戏副本能再次运行所需的服务器上,但在此过程中,我的注意力不可避免地转向了手持设备。如果无法实现与设备同步积分的机制,在线游戏的重现肯定是不完整的。毕竟,计算机与 ME2 设备之间的这种通信是游戏的主要卖点。我想,我之前处理 Miuchiz 手持设备的经验应该能帮助我快速理清它们预期的通信仪式……只要我能拿到一些代码进行逆向工程。

我的好奇心要求牺牲一些 ME2。eBay 要求牺牲法定货币。没过多久,这些样本就摆在了我面前。

ME2 设备

这些是小型设备,只有几个按键和一个母口 mini-USB 端口。包装盒里包含一根线缆,但没有软件和驱动光盘。那个 USB 端口将是计算机与手持设备之间同步积分的方式,但当我为 Miuchiz 手持设备进行相同的旅程时,我通过逆向工程其附带的 Windows 软件的工作原理,获得了对其闪存的完全访问权限。由于 ME2 没有这类软件,因此没有东西可以逆向工程来弄清楚如何与设备通信。即使在查看了 Wayback Machine 和 bjiru 之后,显然也没有任何用于与这些设备通信的软件副本幸存下来。我记得它叫做 ME2 Desktop Buddy,但那个应用程序与 bjiru 恢复的游戏客户端是分开的。手持设备确实将自己暴露为可移动存储设备,但其内容只是引导你上网下载 ME2 游戏,而该游戏已不再可用。

前进的道路很明确,因为只剩下一个选择:打开硬件。

内部构造

ME2 PCB

ME2 的主要固件存储在 SST39VF3201 上,这是一个 2 兆字(4 兆字节,16 位可寻址单元)的闪存芯片。主微控制器……在坚硬的环氧树脂黑胶之下。这被称为板上芯片(CoB),通常是为了节省成本,但它有一个副作用:隐藏了内部集成电路的任何标识信息。普通封装的芯片通常会有标识标记,就像闪存芯片那样。由于此类设备中使用的微控制器通常包含内部 ROM,因此我想要的 USB 代码部分或全部可能就在那个 ROM 里。将代码放在 ROM 中的好处是,可以恢复变砖的设备,或者如果制造商选择这样做,可以在组装后烧录设备。那个 ROM 存在于一个我无法识别的芯片内部。

从闪存芯片中检索数据是一个直接且文档齐全的过程:拆焊芯片,将其放入现成的闪存编程器(如 XGecu 的产品),然后使用它来转储内容。如果我还需要微控制器 ROM 中的信息,那就没那么直接了,但对于这种不太可能有保护措施的设备来说,仍然是可行的。过去,我在 Tamagotchi Pix 的 SPI 闪存中添加了代码,将其引导 ROM 复制到闪存芯片的空闲空间,然后可以通过与我用于注入代码相同的闪存编程器来读取。然而,在那种情况下,微控制器是正常封装的,并在其表面印有型号信息,因此我可以找到它的数据手册,了解它使用的指令集以及其 ROM 在内存空间中的位置。而此时,我对于 ME2 神秘的板上芯片一无所知。

提取

尽管存在不确定性,但唯一看似可行的前进方向是拆焊闪存芯片。我还购买了一些闪存芯片的插座,希望能够将其中一个焊接到手持设备的 PCB 上。这将使我能够重新编程 ME2,并在需要为它编写代码以转储微控制器内部 ROM 时快速迭代。

不幸的是,我无法用烙铁将闪存芯片拆下而不损坏芯片。在多次尝试失败后,为了解决这个技能问题,我转而购买了一个返修台(实际上是一个声称能达到 500°C 的热风枪),并通过热风熔化焊料来拆除芯片。这样我就能毫无问题地转储闪存内容,但这表明实际使用我购买的那些插座超出了我的能力范围。我不仅需要将所有 48 个微小的引脚焊接到 PCB 上,还必须足够快,以免熔化插座的塑料。我没有处理这个的工具和技能,所以如果我还需要 ROM,就需要另一种策略。

不过,转储结果看起来不错。使用一个我专门为在固件转储中查找未压缩位图而构建的工具,我可以找到通常会在设备上显示的图像:

固件转储中的图像

指令集发现

我已经从闪存芯片中获得了固件转储,但在进行认真的逆向工程之前,我至少需要知道设备运行的指令集。硬件本身没有标记,所以只能猜测。我尝试在 Ghidra(一个开源反汇编器、反编译器以及让我保持就业的乱七八糟的噩梦)中用其自带的几乎所有处理器规格来分析代码。任何 ARM 变体?某种 6502 后代?MIPS?其他任何 Ghidra 支持的架构?答案都是响亮的“不”。

我尝试了所有方法,但都无法反汇编这段代码。我知道它是代码,因为我甚至能找到我正在寻找的代码部分!

十六进制编辑器中的 USB 代码

由于我之前在 Miuchiz 手持设备上的工作,我对 USB 大容量存储设备的工作方式有一定了解。我识别出这个片段几乎肯定是在将 'U', 'S', 'B', 'S' 移动到某个地方,这正是我正在寻找的那种 USB 大容量存储通信的签名。我需要逆向工程的一些或全部 USB 代码(以弄清楚如何与该设备交互)肯定在这个闪存转储中,但由于不知道它是什么指令集编写的,我无法反汇编它。

此时,我有几个损坏的 ME2 设备。这听起来很蠢,但也许环氧树脂黑胶下面会有一些标记?可能没有,但在研究阶段,一个完全毁坏的设备有时比一个只是损坏的设备更有价值。

好吧,我有热风枪,也有刀。俗话说,当你手里有热风枪和刀时,所有东西看起来都像……钉子?我觉得俗话是这么说的。

板上芯片脱离板子

将返修台设置为最高温度,并用刀撬动,整个环氧树脂黑胶就被取下来了。它离开后,在已经不板的板上芯片下面没有显示任何标记。不过你可以看到微控制器硅晶片的下侧,环氧树脂上有几个气泡,透过气泡可以看到键合线。

正如我所说,一个毁坏的设备有时比一个损坏的设备更有价值,而我有热风枪、刀,以及迫切需要复习我的习语。

微控制器从环氧树脂中解放出来

哦。

嗯。

我不知道可以那样去除 CoB 的封装。它就这样干净地弹出来了,考虑到它的温度,我很庆幸它不是朝我弹过来的。它看起来很漂亮,但确实有前进的方向。让我用电子显微镜仔细看看。

用户手册声称数码显微镜是电子显微镜

嗯,它的用户手册是这么声称的。公平地说,我查过,它确实包含至少一个电子。

在 破坏“破解”其他小部件挑战我视线的玩具时,很明显,我很少知道烙铁另一端在发生什么。一位朋友非常客气地推荐我购买了一个便宜的数码显微镜,原本用于硬币和焊接。

低质量晶片照片

尽管它并不是真正适合这项工作的设备,而且与其用户手册的说法相反,我还是用显微镜捕捉到了这张图像。它远不能解读晶片上的任何文字,但整体布局是清晰的,而且我知道在哪里可以找到更多类似的图像。

Siliconpr0n,现在被称为 Siliconprawn,有一个存档,很多人上传了晶片照片,尽管通常质量比我好。不幸的是,根据我所掌握的信息,没有有效的方法来搜索该网站,所以我开始点击、滚动,然后重复……

匹配的晶片照片

它的指纹记录在案!

几个小时后,凌晨 4 点,我终于发现了一些熟悉的东西。它的质量比我拍的好,但布局是 unmistakable。我得到一个 GPL162002A(或 B),与 John McMaster 拍摄的匹配图像相比旋转了 180 度。这是一个 GeneralPlus 微控制器,其数据手册可以在互联网上找到,其指令集是 μ'nSP。

逆向工程固件

事实证明,μ'nSP 对于这种类型和年代的玩具来说相当常见。希望我可以被原谅,因为我没能猜出一个指令集的名字包含甚至不在拉丁字母表中的字符。尽管如此,它仍然足够小众,以至于 Ghidra 默认不支持它。幸运的是,有一些现有的第三方工作支持它,因此我可以开始在 Ghidra 中反汇编它,命名函数,并从数据手册中导入寄存器名称。

下面是我仅凭十六进制转储就确信是 USB 代码的函数,它与微控制器数据手册中指定的 USB 寄存器进行交互:

USB 函数反编译

正如我之前提到的,我对于这类 USB 大容量存储设备的通信方式已经有一定了解,特别是因为将我的 Miuchiz USB 库移植到 macOS 并使用 libusb 的一些实验性工作。USB 大容量存储设备基本上是在传输 SCSI 命令,而这些命令在网上有详细的文档。例如,有请求从设备读取或写入的命令。

SCSI 调度函数反编译

然而,我知道一般来说,标准的命令,比如读取或写入,对我没有用。这些是计算机内置的大容量存储驱动程序已经知道如何执行的命令。计算机会发出这些命令来与它交互,就像对待任何普通的可移动介质设备一样。在这种情况下,读取命令只会检索包含帮助文件的文件系统,而写入命令什么也不做,因为它本就不应该是可写的。这些并不是用来与整个闪存芯片交互的;相反,它们实际上是一个模拟的小型 CD-ROM,用于帮助首次使用的用户。

然而,一些命令 ID 是保留给供应商想要实现的。在普通 ID 查找运行之前,一些保留 ID 的处理程序被粗略地注入。

特殊命令反编译

通过静态分析,我能够识别并命名我正在寻找的函数:读取、编程和擦除闪存。这些都是为 ME2 以及可能的其他 GeneralPlus 设备实现的非标准命令,并且几乎肯定被最初随设备附带的任何软件和驱动程序使用。你可以构造一个 USB 消息来触发这些路径中的任何一个。读取允许你从闪存中检索数据。编程允许你“编程”闪存。擦除允许你将闪存区域中的所有位重置为 1,当与编程命令结合使用时,可以实现对闪存的完整写入,因为“编程”只能将位从 1 变为 0。我感兴趣的每个自定义命令都使用保留 ID 0xFF,后面跟着子命令的 ID 和操作所需的任何参数。

命令的确切结构对读者来说并不特别重要,但方法论可能是有意义的。我使用 libusb(实际上,是 rusb)来促进我所有通过 USB 的交互。这种方法允许你编写用户态代码来与 USB 设备交互,而不是编写新的驱动程序。

当 Windows ME2 软件从互联网上消失时,就好像其语言的倒数第二个使用者去世了。从某种意义上说,ME2 手持设备变成了一个终端使用者。通过一点点实验和一点点阅读有时正确的反编译结果,我正在读取它的思想,学习它几乎灭绝的语言的词汇。当它回应时,我知道我走对了路。

Č̶̯a̴̩͗n̵͉͆ ̴͍͠Ǐ̶̜ ̴͈͌h̷̙̔á̶͉v̸͈̽é̴̢ ̵͍͛a̵̞͝ ̴̤̉s̵̡͊ē̴̮c̸̭̅t̶̛͖o̸̡͠r̶̺̊ ̶̥̀ǫ̸̀f̸̦́ ̷̈́ͅỳ̷͎o̶̦̐u̵͙̚r̶͙͒ ̵̥̕f̸̡͝l̷͈̄a̶͍͋s̸̢̓h̸̗͝?̴̪̕

……不行?一定是我的口音。让我调整一下再问:你能给我一个闪存扇区吗?下一个扇区呢?你愿意编程那个扇区中的任何位吗?我能再次读取你的闪存,看看它现在是否不同了吗?我敢要求你擦除一个扇区……并且希望明白 哪个 扇区我要求你销毁?

一个接一个地,我编写代码来构造、填充和传输我需要 ME2 听到的消息。一旦我们达成了共识,我让它在拥有不同数量的积分时向我发送几个闪存转储。在比较它们之后,我能够确定积分存储在闪存中的位置,并最终用我的计算机修改它们!

设备上显示 654321 的分数

确实,只要不涉及擦除正在使用的代码,我就可以使用这些命令对设备做任何我想做的事情。ME2 加入了我在不应该出现的地方显示 Miuchiz Reborn 标志的设备收藏,包括拍摄晶片照片的数码显微镜。

多个被黑客植入 Miuchiz Reborn 标志的设备

“Embadded” ROM 和“Embadded” 错误

诚然,当我第一次尝试读取/写入闪存时,我有些鲁莽,因为我无法看到所有正在执行的代码。例如,有些代码调用了微控制器的内部 ROM,或者调用了由 ROM 复制到 RAM 的 RAM 例程。我对其他函数的一些猜测是根据直接内存访问(DMA)寄存器的设置方式得出的。例如,如果 DMA 被设置为从 USB 缓冲区复制,那么它很可能是在使用那些数据来编程闪存,而不是读取闪存。

SCSI 擦除函数反编译

例如,这段代码调用了一个位于闪存外部的函数,这样它就不会从自身下面拉出代码,然后返回到它刚刚从自身下面拉出的代码。你确实需要非常小心,以免把设备变砖。

相关的内存区域在数据手册中有清晰的布局:

数据手册中的内存布局,其中“Embedded ROM”拼写为“Embadded ROM”

有 128 千字的特别“embadded” ROM,我还没有访问权限,这阻碍了我完全理解整个系统。

幸运的是,自定义闪存读取函数没有执行边界检查。这意味着,通过一个精心构造的消息,试图从一个非常高的闪存地址读取,你可以环绕微控制器的整个地址空间,最终回到起点。由于这相当于任意读取能力,这次我不需要编写任何设备上的转储代码!所有内存都可以通过这个漏洞读取,所以我用它来读取了 Embadded ROM,保存起来供以后逆向工程使用。

有了所有内存,我能够发现设备 RAM 中的帧缓冲区,显示了当时设备屏幕上显示的图像:

RAM 转储中的帧缓冲区

我也能够通过参考数据手册中说明的位置,从设备的地址空间读取通用输入/输出(GPIO)寄存器。通过每秒触发该漏洞数十次,我可以有效地轮询按键,如果我想的话,甚至可以将它变成一个 USB 控制器:(视频)

GPIO 转储

在我的测试过程中,我注意到闪存中一个值发生了奇怪的修改,而这个值甚至看起来不应该是保存数据。

显示 0xAA 被写入闪存的差异对比

0x00AA(记住,这个系统的字大小是 16 位)被写入了一个我并未要求的地方。有了 Embadded ROM,我们终于可以看到解释这一点的代码。

显示导致越界写入的代码的反汇编

这些闪存芯片通过向特定偏移写入命令来接收命令。与立即提交写入数据的 RAM 不同,闪存芯片只会尝试将写入解释为命令的一部分,因此对闪存地址空间的单次写入不足以实际更改任何数据。当一段代码想要编程闪存时,它会发出一个多步命令序列,从向 0x5555 写入 0xAA 开始,以在所需地址写入所需数据结束。如果一个用户有太多的空闲时间(可能还有热风枪和刀子),想要尝试探究设备的工作原理,他们可能会最终请求设备编程到超出其闪存芯片容量的扇区。处理器知道每一步,但闪存芯片不知道。相反,最后的命令周期完全错过了闪存芯片的地址空间,因此闪存热切地等待着应该在哪里编程什么值。

处理器:嘿,闪存!我想开始编程另一个字!

闪存:收到!正在编程 0xAA 到 0x5555!

处理器:……嗯?

由于命令周期不同步,闪存将下一个命令的第一个周期误认为是上一个命令的最后一个周期,于是 0xAA 被编程到了 0x5555。对于典型的 8 位字节,等效地址是 0xAAAA,这与我的闪存转储中写入 0x00AA 的位置匹配。

这理论上可以用于任意写入,只要你不介意破坏闪存中那个特定的字,但该设备已经被充分攻破,我不再热衷于弄坏更多设备。或许可以挽救这些设备,因为逆向嵌入式 ROM 显示它包含自己的 USB 处理程序和闪存读/编程/擦除实现。然而,我只让 ROM 进入过这种状态(而不是从闪存代码启动)一次,之后就再也没成功过。根据 ROM 的反编译结果,我怀疑它可能依赖于一个浮空的 GPIO 端口,但不确定。无论如何,我在这里的任务已经完成了。

最终成果与收获

这番捣乱的最终成果是一个命令行工具,它可以:

  • 读取闪存
  • 写入闪存
  • 读取点
  • 设置点
  • 读取宝石
  • 设置宝石
  • 转储内存(通过漏洞)
  • 监视按钮输入(通过漏洞)

这个工具,以及游戏服务器代码和其他研究成果,可在 ME2-Restoration 仓库中找到。由于实现细节在那里可以获取,而且对普通读者来说可能不太有趣,因此本文省略了具体技术细节,转而描述过程和技巧。

更重要的是,这证明了理解或保存其功能并不严格需要原始的 PC 端软件。即使官方软件已随时间流逝,仍然可以打开 ME2 这个黑匣子,从其硬件和固件中重建其协议,将原本已死的接口恢复成可用的东西。这也不仅限于 USB 这样的接口。阅读我是如何重新创建一个早已失效的许可证服务器,让一个十年前的矢量编辑器重获新生。

这也是我第一次对集成电路进行开盖封装,为了给予它应有的尊重,我购买了一台更好的显微镜,并随后向 siliconprawn 贡献了 GPL162002A/B 的最高质量照片,这里以降低的分辨率预览,以便于网络浏览:

High quality die shot

下载工具