Flash: Difference between revisions

From PS3 Developer wiki
Jump to navigation Jump to search
(minor cleanup and more information starting)
m (Tidy up)
Line 1: Line 1:
[[File:Flash_TSOP.png|thumbnail|Typical Flash TSOP package found on PS3's can either be 2x128mb NAND or 1x16mb NOR]]
This is my attempt at documenting the files located and stored on flash. Please do note that this is from reverse engineering several flash dumps, not from reverse engineering the PS3 firmware itself. This involves alot of guesswork and may not be accurate and there may be information missing.
= Structure =
= Structure =



Revision as of 09:02, 11 May 2011

Typical Flash TSOP package found on PS3's can either be 2x128mb NAND or 1x16mb NOR

This is my attempt at documenting the files located and stored on flash. Please do note that this is from reverse engineering several flash dumps, not from reverse engineering the PS3 firmware itself. This involves alot of guesswork and may not be accurate and there may be information missing.

Structure

  • 0x0 > 0x400 = Headers
  • 0x400 > 0x800 = File table
  • 0x800 > 0xF00000 = Region 1
    • 0x800 > 0x2F000 = asecure_loader region
      • 0x840 > 0xF110 = metldr
  • 0xF00000 > 0xFFFFFF = region 2
    • unknown format

Flash Format

Header

First 512 Bytes of flash

00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00000010  00 00 00 00 0F AC E0 FF 00 00 00 00 DE AD BE EF  .....¬àÿ....Þ.¾ï
00000020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 78 00  ..............x.
00000030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
....
000001F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Address Length Value Description
0x00 0x10 0x0 Blank/Unknown
0x10 0x10 0x0FACE0FF 0xDEADBEEF Magic number
0x20 0x10 0x7800 Length of region * 0x200
0x30 0x1D0 0x0 Blank/Unknown

Unknown Header

The next block of 512 bytes only has the first 16 bytes written. Unsure exactly what this means.

00000200  49 46 49 00 00 00 00 01 00 00 00 02 00 00 00 00  IFI.............
00000210  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
....
000003F0  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
Address Length Value Description
0x200 0x10 0x49464900 (String: "IFI") 0x1 0x2 0x0 Unknown

File Table

The next 1024 bytes contain the file entry table

Header

Small 16 byte header to describe length and entry count

00000400  00 00 00 01 00 00 00 0B 00 00 00 00 00 EF FC 00  .............ïü.
Address Length Value Description
0x0 0x4 0x01 Unknown
0x4 0x4 0x0B Entry Count
0x8 0x8 0xEFFC00 Length of Flash Region (relative to 0x400 (region start)

First is a header, this tells us how many files are stored here.

Entry Table

Then follows a 32 byte entry for each file

00000410  00 00 00 00 00 00 04 00 00 00 00 00 00 02 E8 00  ..............è.
00000420  61 73 65 63 75 72 65 5F 6C 6F 61 64 65 72 00 00  asecure_loader..
00000430  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Address Length Value Description
0x0 0x8 0x400 File offset relative to 0x400 (Region start)
0x8 0x8 0x2E800 File length
0x10 0x10 char[32]:"asecure_loader" File name
0x20 0x10 0x0 Blank/Unknown


asecure_loader region

Within asecure_loader is another file table similar to region 1

Header

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000800  00 00 00 01 00 00 00 01 00 00 00 00 00 02 E8 00  ..............è.

 u32 - unknown (0x01)
 u32 - Entry count (0x01)
 u64 - Length of Region (0x2E800)

Entry Table

Then follows a 32 byte entry for each file

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000810  00 00 00 00 00 00 00 40 00 00 00 00 00 00 E8 D0  .......@......èÐ
00000820  6D 65 74 6C 64 72 00 00 00 00 00 00 00 00 00 00  metldr..........
00000830  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

 u64 - offset - Relative to region start (0x40)
 u64 - size (0xE8D0)
 char[32] - name (metldr)

Example

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000800  00 00 00 01 00 00 00 01 00 00 00 00 00 02 E8 00  ..............è.
00000810  00 00 00 00 00 00 00 40 00 00 00 00 00 00 E8 D0  .......@......èÐ
00000820  6D 65 74 6C 64 72 00 00 00 00 00 00 00 00 00 00  metldr..........
00000830  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

Encrypted Files on Flash

Encrypted files on flash appear to have some sort of header, Here are two different samples from metldr and bootldr

From metldr

00000840  00 00 0E 8E 99 87 3B C7 15 F2 80 80 9C 30 22 25  ...Ž™‡;Ç.ò€€œ0"%
00000850  00 00 0E 8E 78 A5 61 E0 17 72 6E F7 A7 1B 41 AB  ...Žx¥aà.rn÷§.A«
00000840  00 00 0E 8E 99 87 3B C7 15 F2 80 80 9C 30 22 25  ...Ž™‡;Ç.ò€€œ0"%
00000850  00 00 0E 8E 81 2E 00 A9 59 75 01 CC C1 72 D5 50  ...Ž...©Yu.ÌÁrÕP

From bootldr

00FC0000  00 00 2F 4B 53 92 1C E7 F7 33 41 76 9B 7A 1E D6  ../KS’.ç÷3Av›z.Ö
00FC0010  00 00 2F 4B 78 A5 61 E0 17 72 6E F7 A7 1B 41 AB  ../Kx¥aà.rn÷§.A«
00FC0000  00 00 2F 4B CB 9E 15 24 28 B4 4F D2 F9 3F BC 43  ../KËž.$(´OÒù?¼C
00FC0010  00 00 2F 4B 81 2E 00 A9 59 75 01 CC C1 72 D5 50  ../K...©Yu.ÌÁrÕP

Observations

As you can see, some parts appear static depending on their purpose:

metldr

00000840  00 00 0E 8E 99 87 3B C7 15 F2 80 80 9C 30 22 25  ...Ž™‡;Ç.ò€€œ0"%
00000850  00 00 0E 8E xx xx xx xx xx xx xx xx xx xx xx xx  ...Žx...........

bootldr

00FC0000  00 00 2F 4B xx xx xx xx xx xx xx xx xx xx xx xx  ../K............
00FC0010  00 00 2F 4B xx xx xx xx xx xx xx xx xx xx xx xx  ../K............

per console in both samples

00000840  xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx  ................
00000850  xx xx xx xx 81 2E 00 A9 59 75 01 CC C1 72 D5 50  .......©Yu.ÌÁrÕP

The first 4 bytes appear to reffer to length. eg:

metldr length: 0xE920
0x00000E8E * 0x10 = 0xE8E0 + 0x40 = 0xE920
bootldr length:  0x2F4F0
0x00002F4B * 0x10 = 0x2F4B0 + 0x40 = 0x2F4F0

Header shown is 0x20 bytes, perhaps this means there is a 0x40 byte header. I was not able to find any correlation of the other 2x12 bytes here, perhaps these are keys of some sort.

Region 2 Format

This region appears to directly follow the other region (at 0xF0000 = region size + header)

Not much is known about this at this stage.

Header

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00F00000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00F00010  00 00 00 00 0F AC E0 FF 00 00 00 00 DE AD FA CE  .....¬àÿ....Þ.úÎ
00F00020  00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 02  ................
00F00030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
....
00F000B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00F000C0  00 00 00 00 00 00 79 00 00 00 00 00 00 00 01 00  ......y.........
00F000D0  10 70 00 00 01 00 00 01 00 00 00 00 00 00 00 03  .p..............
00F000E0  10 70 00 00 02 00 00 01 00 00 00 00 00 00 00 03  .p..............
00F000F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
....
00F00140  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00F00150  00 00 00 00 00 00 7A 00 00 00 00 00 00 00 04 00  ......z.........
00F00160  10 70 00 00 01 00 00 01 00 00 00 00 00 00 00 03  .p..............
00F00170  10 70 00 00 02 00 00 01 00 00 00 00 00 00 00 03  .p..............
00F00180  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
....
00F00FF0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

Bootloader

Located at 0xFC0000 to 0xFFFFFF (The last 256kb of flash)

NOR Files

The following is a list of files stored in NOR Flash

Name Offset Size
asecure_loader 0x400 0x2E800 (190,464 bytes)
eEID 0x2EC00 0x10000 (65,636 bytes)
cISD 0x3EC00 0x800 (2,048 bytes)
cCSD 0x3F400 0x800 (2,048 bytes)
trvk_prg0 0x03FC00 0x20000 (131,072 bytes)
trvk_pkg0 0x7FC00 0x20000 (131,072 bytes)
trvk_pkg1 0x9FC00 0x20000 (131,072 bytes)
ros0 0xBFC00 0x700000 (7,340,032 bytes)
ros1 0x7BFC00 0x700000 (7,340,032 bytes)
cvtrm 0XEBFC00 0x40000 (262,144 bytes)

NOR Unpacking // NOR Unpkg

/*
  # ../norunpkg norflash.bin norflash
  unpacking asecure_loader (size: 190xxx bytes)...
  unpacking eEID (size: 65536 bytes)...
  unpacking cISD (size: 2048 bytes)...
  unpacking cCSD (size: 2048 bytes)...
  unpacking trvk_prg0 (size: 131072 bytes)...
  unpacking trvk_prg1 (size: 131072 bytes)...
  unpacking trvk_pkg0 (size: 131072 bytes)...
  unpacking trvk_pkg1 (size: 131072 bytes)...
  unpacking ros0 (size: 7340032 bytes)...
  unpacking ros1 (size: 7340032 bytes)...
  unpacking cvtrm (size: 262144 bytes)...
*/

// Copyright 2010       Sven Peter
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
// nor modifications by rms.

#include "tools.h"
#include "types.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>

#ifdef WIN32
#define MKDIR(x,y) mkdir(x)
#else
#define MKDIR(x,y) mkdir(x,y)
#endif

u8 *pkg = NULL;

static void unpack_file(u32 i)
{
        u8 *ptr;
        u8 name[33];
        u64 offset;
        u64 size;

        ptr = pkg + 0x10 + 0x30 * i;

        offset = be64(ptr + 0x00);
        size   = be64(ptr + 0x08);

        memset(name, 0, sizeof name);
        strncpy((char *)name, (char *)(ptr + 0x10), 0x20);

        printf("unpacking %s (size: %d bytes)...\n", name, size);
        memcpy_to_file((char *)name, pkg + offset, size);
}

static void unpack_pkg(void)
{
        u32 n_files;
        u64 size;
        u32 i;

        n_files = be32(pkg + 4);
        size = be64(pkg + 8);

        for (i = 0; i < n_files; i++)
                unpack_file(i);
}

int main(int argc, char *argv[])
{
        if (argc != 3)
                fail("usage: norunpkg filename.nor target");

        pkg = mmap_file(argv[1]);

        /* kludge for header, i do not do sanity checks at the moment */
        pkg += 1024;

        MKDIR(argv[2], 0777);

        if (chdir(argv[2]) != 0)
                fail("chdir");

        unpack_pkg();

        return 0;
}

Source: http://rms.dukio.com/?p=25

RMS - eEID splitter

#include <stdio.h>
#include <stdlib.h>

void
DumpEidData (FILE * pFile, int iInputSize, int iEidCount)
{
  FILE *pOutput;
  char szFileName[8];
  char *szBuf;
  int iRes, iSize;

  printf("dumping EID%s from eEID at %p, size %d (%x)..\n",
         iEidCount, pFile, iInputSize, iInputSize
		 );

  szBuf = (char *) malloc (iInputSize + 1);

  if (szBuf == NULL)
    {
      perror ("malloc");
      exit (1);
    };

  iSize = fread (szBuf, iInputSize, 1, pFile);
  sprintf (szFileName, "EID%d", iEidCount);
  pOutput = fopen (szFileName, "wb");
  iRes = fwrite (szBuf, iInputSize, 1, pOutput);

  if (iRes != iSize)
    {
      perror ("fwrite");
      exit (1);
    };

  free (szBuf);
}

int
main (int argc, char **argv)
{
  FILE *pFile;

  pFile = fopen (argv[1], "rb");
  if (pFile == NULL)
    {
	  printf ("usage: %s <eEID>\n");
	  exit (1);
    }

  fseek (pFile, 0x70, SEEK_SET);

  DumpEidData (pFile, 2144, 0);
  DumpEidData (pFile, 672, 1);
  DumpEidData (pFile, 1840, 2);
  DumpEidData (pFile, 256, 3);
  DumpEidData (pFile, 48, 4);
  DumpEidData (pFile, 2560, 5);
}

Source: http://rms.dukio.com/?p=59