TL; DR

我有一个加密的图像和明文版本,几乎可以肯定它是XOR密码,但是我不知道该如何解密。下面列出了一些线索。




密文摘录(20kB)

明文摘录(20kB)

详细信息

我正在尝试对专业音频设备的固件进行逆向工程,我已经掌握了大部分方法,但是我仍然处于中间。 br />我很确定这是一个XOR密码(因为已经有一个XOR解密可以达到这一点,之后又有一个)。它似乎在0x1000字节的块中应用,因为密钥似乎在此多个字节之后重置。初始密钥似乎是2,并且每​​0x2000字节增加1。在每个块的开头,将当前的“初始密钥”与0x4002进行异或,以产生真实密钥。因此,密钥会在以下偏移量处重置为这些值:将每个单词与键进行异或后,该键将向右移1。有时,显然是随机的,密钥需要与0x4002进行异或。我看不到何时发生这种模式。最初看起来像每四个字节(两个字)发生一次,但这在偏移量0x22处消失了。

我尝试对密文和明文进行XOR运算以生成长的XOR密钥文件,然后尝试找出如何重现该密钥文件。通过对大型密钥文件进行XOR'ing我的猜测,如果我是正确的话,它应该以0x00字节结尾。但是,它通常以0x02 0x40字节结尾,并且通过编写检测到这些错误并相应地调整密钥的代码,我能够看到0x4002对该密钥进行XOR运算的位置和时间,以便正确解密数据。我已经盯着它看了几个小时,但是对我来说,它看起来是随机的,我看不到任何图案!例如,在偏移量为0的块中,键需要在偏移量0、4、8、12(每四个字节)处与0x4002进行异或,但在偏移量20处又降回到每两个字节(20、22、24,不是26-,28、2A, 2A,而不是2E-等)。我看不到何时应该发生密钥上的额外XOR的模式。它似乎与先前的值,偏移量,键值等无关(当然,可能只是我看不到它。)

背景

源数据来自制造商的固件文件,我已从MIDI SysEx事件中解码并使用XOR密码解密。我知道此密码是正确的,因为它会生成正确的页眉和页脚以及每256字节的块号。处理完这些后,我得到的源映像的大小与使用Minipro EEPROM阅读器直接从设备的ROM芯片直接获取的固件转储大小相同。从制造商的固件文件到闪存芯片的最后一步(反之亦然,因为对定制ROM进行编程是我的最终目标)。

请注意,确实写入ROM芯片的内容(在这里我称为明文)本身已进行了进一步的XOR加密,但是我已经成功解密了,因此在这里是没有问题的(并且需要进行闪存内加密,因为bootloader会期望它。)

如果有人可以帮助我弄清楚该算法,那么我将在实施它并将其作为开源发布,这是我正在研究的项目的一部分。 />
反汇编

由于@Igor Skochinsky的问题,我还没有尝试反汇编引导程序,因为我不确定该怎么做。这是引导加载程序的代码,根据Blackfin ADSP-BF531数据表,其中可能包含10个字节的标头。仅适用于Flash ROM编程阶段。数据块通过MIDI端口(功能号0x34“写闪存块”)以7位数据形式进入,被解码为8位数据,应用了与密钥TZ'04无关的XOR解密(密钥从偏移量0x2C84),检查CRC,剥离三字节报头并将剩余的256字节块(大概)存储在RAM中。

手册说设备仅在写完之后确认写入第16个256字节块,即4 kB数据。所讨论的XOR算法每隔4 kB重置密钥,因此该设备似乎会收集256字节的块,直到达到4 kB,然后在该点应用未知的XOR密码,然后将生成的明文写入闪存。芯片(这是一个SST39SF040,标识为芯片ID 0xBFB7)。

与此无关(但有助于引导拆卸),引导加载程序还会在正常引导过程中从闪存芯片加载数据,然后进行XOR。使用“应用程序密钥”对其进行解码。此运行时XOR的解决方法如下:


从偏移量0x3002(长度为0x38)加载的引导加载程序XOR密钥。
从偏移量0x303A读取的引导加载程序密文,长度为0x38。执行。


评论

您是否尝试在转储的固件中找到解密例程?

@IgorSkochinsky我不太确定如何进行反汇编,但是如果有人知道支持Blackfin处理器的任何工具,我已经更新了问题,添加了“反汇编”标题和指向引导加载程序代码的链接。 >

#1 楼

好了,由于@IgorSkochinsky的建议,我在pf0camino / cross-bfin-elf Docker镜像中找到了Blackfin架构的反汇编程序。在Docker中意味着它很容易运行,我不必自己安装交叉编译器。然后,我可以使用以下命令反汇编图像:任何适用于它的自动识别。但是,在阅读了Blackfin汇编程序并搜索了各种已知的常量之后,我能够弄清楚代码在做什么。我的项目。结果如下:

bfin-elf-objdump -D -b binary -mbfin bootloader.bin > bootloader.disasm


baseBlockNum参数是块的ROM地址,以0x1000字节为单位。因此,对于要在地址0x4000处刷新的块,参数为4。

我已经在完整的固件文件上对其进行了测试,并成功解密了!