我正在尝试提取旧Walkman播放器的NAND闪存转储。转储是由一位朋友完成的,很遗憾,由于芯片被破坏,无法重做。
我尝试了多种删除OOB的方法,虽然可以获得一些看起来合理的数据,但是许多事情仍然存在,并且我无法提取适当的文件。

这就是我尝试过的方法。 />
仅通过目视观察十六进制转储,就有一个16字节的行以“ 01 00 00 00”开头
每0x200字节看起来就不合适。

我做了一个简短的脚本,在每个0x200之后删除了16个字节: >
import sys
inf = open(sys.argv[1] ,"rb")
of = open(sys.argv[2],"wb")
clen = 0x200
c = inf.read(clen)
off = 0
while c:
  off = inf.tell()
  oob = inf.read(0x10)
  if oob[:4]!="\x01\x00\x00\x00":
   print " bad OOB at %08X?" % off, oob.encode('hex')
   break
  of.write(c)
  if (off&0x1000) ==0:
   print "%08X" % off
  c = inf.read(clen)


inf.close()
of.close()
print "done."


确实,下一条以01 00 00 00开头的行是1240,而不是1070。我试图考虑并重新启动,但是
类似的问题。所以我想知道我是否缺少什么。
完整文件为4GB,有点重,因此这里切出的块很少:


转储的开始(初始引导加载程序?)。偏移量0

U-boot引导加载程序的启动。偏移量0x104000

内核映像的开始。偏移量0x186000


如果您想查看整个转储,我在聊天中共享了一个链接。

硬件细节:
设备为Sony Walkman NWZ-A829。
闪存芯片很可能是TH58NVG6D1DTG20。
CPU是NEC MP201(ARMv5le)。

此处提供GPL源(U-Boot / Linux内核):http://oss.sony.net/Products/Linux/ Audio / NWZ-S715.html

最终目标是弄清楚固件更新加密并为该设备生成自定义固件。

#1 楼

所以,我最终想通了。我将尝试描述该过程。

首先,介绍一下NAND的背景知识:它以页面的形式组织,这些页面分为若干块。您一次只能读取或写入一页,但是一次只能将一个块完成擦除(将所有位变为1(因此字节变为FF))(写入只能将位从1更改为0,而另一位则不能)因此,要写入新数据,通常必须先擦除该块)。通常,芯片每页还具有一些额外的存储空间,用于存储ECC(纠错码)和/或任意“备用”数据(也称为OOB:带外),这些数据不被认为是USB有用存储的一部分。芯片,但仍可以使用低级功能进行读写。

浏览十六进制转储时,我遇到了一堆FF之后遇到了这个区域: />
0000081FE0: FF FF FF FF FF FF FF FF │ FF FF FF FF FF FF FF FF          
0000081FF0: FF FF FF FF FF FF FF FF │ FF FF FF FF FF FF FF FF          
0000082000: 6C 4F 41 64 00 00 00 00 │ 00 00 00 00 00 00 00 00  lOAd
0000082010: 00 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00
0000082020: 00 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00
0000082030: 00 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00
0000082040: 00 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00
0000082050: 00 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00



在每个0x200字节之后,它具有通常的OOB外观的16字节块,但又有所不同:


83040: 70 41 52 74 18 00 00 00 │ 48 00 00 00 90 00 00 00  pARt↑   H   
83050: A0 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00   
83060: 00 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00
....
84080: 75 42 54 74 20 00 00 00 │ 02 00 00 00 00 00 00 00  uBTt    ☻
84090: 00 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00
840A0: 00 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00
840B0: 00 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00



这是什么?听起来像U-Boot。让我们从Sony网站上检查U-boot来源...和宾果游戏!

 /* for Loader Management */
 #define MNG_SIG_LOADER         0x64414F6C      /* "lOAd" */
 #define TBL_SIG_PART           0x74524170      /* "pARt" */
 #define TBL_SIG_UBOOT          0x74544275      /* "uBTt" */
 #define TBL_SIG_FUKRNL         0x744B5566      /* "fUKt" */
 #define TBL_SIG_FUINRD         0x74525566      /* "fURt" */
 #define TBL_SIG_BAD                0x74444162      /* "bADt" */

 #define    MNG_SIG_KRNL            0x6C4E526B      /* "kRNl" */
 #define TBL_SIG_KRNL           0x744C4E6B      /* "kNLt" */
 #define TBL_SIG_INRD           0x74445269      /* "iRDt" */


(来自icx1087_nand.c
因此,显然这些块与“ Loader”有关管理” ...看一下我们在代码块中遇到的引用:

值是...

/* read management table */
for( rty = 0; rty < NAND_READ_RETRY; rty++ ) {
    if( nand_search_tbl(NAND_BLK_LOADER_START, NAND_BLK_LOADER_LMT,
                        MNG_SIG_LOADER, TBL_SIG_PART, (void *)&ptbl, 0) ) {
            continue;
    }
    /* success to read Kernel information if reach here */
    break;
}


所以看起来82000是NAND块1的开始。如果进一步检查代码,我们可以看到它正在寻找此块页面中的其他签名(例如MNG_SIG_LOADERTBL_SIG_PART)。让我们看看:


MNG_SIG_LOADER:82000(第1页第0页?)
TBL_SIG_PART:83040(第1页第1页?)
TBL_SIG_UBOOT:84080(第1页)第2页?)

83040-82000 = 1040和84080-83040 = 1040也是如此!因此,看起来转储中的页面大小为1040。并且1040 * 128 = 82000,这意味着每个块有128页。实际数据可能是0x1000字节,0x40是“备用”数据。因此,这解释了为什么我在每个四个0x200扇区之后都出现了不同步的原因:每页有8个扇区,但是OOB数据只有0x40字节。 ;我认为这是因为用于转储的软件(IIRC是Matt Oh的DumpFlash)在许多地方都假定使用512字节的页面,因此,OOB数据最终以块的形式散布,而不是在每页的末尾进行分组。可能与数据表中类似(但不相同)的东芝芯片的这一段内容有关:


每个512Byte需要8位ECC br />(但没有说明如何完成操作)

无论如何,一旦我弄清了页面大小和每个块128页的神奇数字0x1040,就不难修复我的脚本:

#define NAND_BLK_LOADER_START   1


这样,我可以将内核和ramdisk的部分闪存转储并提取二进制文件。

#2 楼

我是Rockbox开源项目的开发人员。我们基本上是通过做相同的事情(转储芯片)来解决固件升级的加密问题的。使用cabextract的安装程序并查看文件Data / Device / NW_WM_FW.UPG。它需要一个可以强行使用的加密密钥(如果要求[3],upgtool可以这样做),也可以使用以下命令要求设备提供密钥scsitool。
我们有许多索尼设备的端口,不支持NW-A820,因为它具有非常老的内核,但是我们反向工程的大多数信息可能仍然适用。

[3] upgtool在其数据库中具有A820的密钥,是通过蛮力发现的

评论


是的,发布此问题后,我找到了您的东西。做得好,谢谢!

–伊戈尔·斯科钦斯基♦
17年9月19日在14:29

#3 楼



当快速读取作为NAND问题的未来提示时。

读取NAND闪存时(不必关心bga,tsop ..),并不是所有的程序员都会进行明确的转储,通常它包括虚拟块正如您提到的OOB数据。

由于NAND转储应为8的倍数,例如64、128、256MB ...如果您转储的文件大于典型大小,例如132MB,然后必须分析二进制文件以删除虚拟块并找出模式,然后就可以开始使用二进制文件了。