forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Program for parsing data in PARAM.SFO files

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
Guest






PostPosted: Sat Jan 08, 2005 6:32 am    Post subject: Program for parsing data in PARAM.SFO files Reply with quote

Ok, within each savefile directory is a file called PARAM.SFO that contains interesting data. I wrote a program to parse the fields within that file and print them out. Naturally, there are still mysteries within that file.

The firmware updates also contain a similar file that can be parsed by this program.

Enjoy!

Code:

/*
 * PSP PSF File Parser v 0.2
 *
 * Copyright Chris Barrera a.k.a. Gorim
 * Date  : January 8 2005
 *
 * This source is licensed under the terms of the Academic Free License 2.0
 *
 */

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

#define STRBUFSZ 512

/* For endian neutrality */
u_int32_t le32(u_int32_t bits)
{
   u_int8_t *bytes;
   bytes = (u_int8_t*)&bits;
   return(bytes[0] | (bytes[1]<<8) | (bytes[2]<<16) | (bytes[3]<<24));
}

/* For endian neutrality */
u_int16_t le16(u_int16_t bits)
{
   u_int8_t *bytes;
   bytes = (u_int8_t*)&bits;
   return(bytes[0] | bytes[1]<<8);
}

struct PsfHdr
{
   u_int8_t   magic[4];
   u_int8_t   rfu000[4];
   u_int32_t   label_ptr;
   u_int32_t   data_ptr;
   u_int32_t   nsects;
};

struct PsfSec
{
   u_int16_t   label_off;
   u_int8_t   rfu001;
   u_int8_t   data_type; /* string=2, integer=4, binary=0 */
   u_int32_t   datafield_used;
   u_int32_t   datafield_size;
   u_int32_t   data_off;
};

char PsfMagic[] = "\0PSF";
char PsfDefaultFile[] = "PARAM.SFO";

int main(int argc, char *argv[])
{
   FILE      *PsfFile;
   char      *PsfFilename;
   struct PsfHdr   *psfheader;
   struct PsfSec   *psfsections, *sect;
   u_int8_t   *psf;
   u_int8_t   *psflabels;
   u_int8_t   *psfdata;
   u_int8_t   strbuf[STRBUFSZ];
   int      dsize, i;

   PsfFilename = (argc != 2) ? PsfDefaultFile : argv[1];

   if (!(PsfFile = fopen(PsfFilename, "rb")))
   {
      perror("File cannot be opened.");
      exit(1);
   }

   fseek(PsfFile, 0, SEEK_END);
   dsize = ftell(PsfFile);
   psf = (u_int8_t*)malloc(dsize);
   rewind(PsfFile);
   fread(psf, dsize, 1, PsfFile);
   fclose(PsfFile);

   if (memcmp(PsfMagic, psf, 4))
   {
      printf("This file is not a PSF file ! [PSF Magic == 0x%08x]\n", *(u_int32_t*)PsfMagic);
      exit(1);
   }

   psfheader = (struct PsfHdr*)psf;
   psfsections = (struct PsfSec*)(psf + sizeof(struct PsfHdr));
   psflabels = psf + le32(psfheader->label_ptr);
   psfdata = psf + le32(psfheader->data_ptr);

   printf("=============================================================================\n");
   printf("PlayStation Portable PSF File Data\n");
   printf("=============================================================================\n");
   printf("\nFilename                : %s\n\n", PsfFilename);
   printf("Start of section labels : %2x\n", le32(psfheader->label_ptr));
   printf("Start of section data   : %2x\n", le32(psfheader->data_ptr));
   printf("Unknown header data     : %02x %02x %02x %02x\n",
      psfheader->rfu000[0], psfheader->rfu000[1], psfheader->rfu000[2],
      psfheader->rfu000[3]);
   printf("Number of Sections      : %d\n\n", le32(psfheader->nsects));
   printf("Sect Loff Doff Dsiz Duse Dtyp Unkn     Label             Value\n");
   printf("=============================================================================\n");

   for (i = 0, sect = psfsections; i < le32(psfheader->nsects); i++, sect++)
   {
      printf(" %2d  %04x %04x %04x %04x  %02x  %04x     %-16s = ", i,
         le16(sect->label_off), le32(sect->data_off), le32(sect->datafield_size),
         le32(sect->datafield_used), sect->data_type, sect->rfu001,
         &psflabels[le16(sect->label_off)]);

      switch(sect->data_type)
      {
         case 2:   /* string*/

            /* Because the data types can be arbitrarily specified,
               and we are explicitly given the data length, we should
               not assume strings are NULL terminated here. Ok, they might
               be anyway, but just let me be paranoid */

            dsize = le32(sect->datafield_used) < STRBUFSZ ?
               le32(sect->datafield_used) : STRBUFSZ-1;
            strncpy(strbuf, &psfdata[le32(sect->data_off)], dsize);
            strbuf[dsize] = '\0';

            printf("%s\n", strbuf);
            break;

         case 4: /* Integer word */
            printf("%d\n", le32(*(u_int32_t*)&psfdata[le32(sect->data_off)]));
            break;

         case 0: /* binary data ? */
            printf("Binary Data\n");
            break;

         default: /* Dunno yet */
            printf("Yet unknown. Please email save to wildwabbit@gmail.com\n");
            break;
      }
   }
   printf("=============================================================================\n");
   printf("Loff = Offset of the Label Field within the Label section.\n");
   printf("Doff = Offset of the Data Field within the Data section.\n");
   printf("Dsiz = Size of the Data Field within the Data section.\n");
   printf("Duse = Amount of the Data Field that currently contains data.\n");
   printf("Dtyp = The Data Field type. 0 = Binary (?), 4 = Integer Word, 2 = String.\n");
   printf("Unkn = Unknown field usage.\n\n");

   return 0;
}



Edits:
(1) Upped max mmap filesize for larger PARAM.SFO's. Was kinda arbitrary.
(2) Printed wrong values for string and int data types, they were swapped.
(3) Didn't verify the success of mmap. I tried to make this as portable as possible to any platform, but its only tested on MacOSX, so I better do as many sanity checks as possible.
(4) Use of mmap() wasn't portable, so I removed it and used standard file i/o routines to read in the param.sfo file data.
(5) changed fopen() mode from "r" to "rb" for non-UNIX OS's that care.


Last edited by Guest on Mon Apr 04, 2005 1:20 am; edited 5 times in total
Back to top
ooPo
Site Admin


Joined: 17 Jan 2004
Posts: 2032
Location: Canada

PostPosted: Sat Jan 08, 2005 7:38 am    Post subject: Reply with quote

Pretty!
Back to top
View user's profile Send private message Visit poster's website
Guest






PostPosted: Sat Jan 08, 2005 8:15 am    Post subject: Sample program outputs from various save games - Mina No Gol Reply with quote

From the PSP memstick:/PSP/SAVEDATA/UCJS10001 (savegame dir)

Running the program produces this output:
Code:
=============================================================================
PlayStation Portable PSF File Data
=============================================================================

Filename                : PARAM.SFO

Start of section labels : 94
Start of section data   : 108
Unknown header data     : 01 01 00 00
Number of Sections      : 8

Sect Loff Doff Dsiz Duse Dtyp Unkn     Label             Value
=============================================================================
  0  0000 0000 0004 0002  02  0004     CATEGORY         = MS
  1  0009 0004 0004 0004  04  0004     PARENTAL_LEVEL   = 1
  2  0018 0008 0400 0001  02  0004     SAVEDATA_DETAIL  =
  3  0028 0408 0040 000a  02  0004     SAVEDATA_DIRECTORY = UCJS10001
  4  003b 0448 0c60 0c60  00  0004     SAVEDATA_FILE_LIST = Binary Data
  5  004e 10a8 0080 0080  00  0004     SAVEDATA_PARAMS  = Binary Data
  6  005e 1128 0080 0001  02  0004     SAVEDATA_TITLE   =
  7  006d 11a8 0080 0029  02  0004     TITLE            = ã¿ããªã®ï¼§ï¼¯ï¼¬ï¼¦ ãã¼ã¿ãã«
=============================================================================
Loff = Offset of the Label Field within the Label section.
Doff = Offset of the Data Field within the Data section.
Dsiz = Size of the Data Field within the Data section.
Duse = Amount of the Data Field that currently contains data.
Dtyp = The Data Field type. 0 = Binary (?), 4 = Integer Word, 2 = String.
Unkn = Unknown field usage.


Here is a basic hexdump -C of the same file:

Code:
00000000  00 50 53 46 01 01 00 00  94 00 00 00 08 01 00 00  |.PSF............|
00000010  08 00 00 00 00 00 04 02  02 00 00 00 04 00 00 00  |................|
00000020  00 00 00 00 09 00 04 04  04 00 00 00 04 00 00 00  |................|
00000030  04 00 00 00 18 00 04 02  01 00 00 00 00 04 00 00  |................|
00000040  08 00 00 00 28 00 04 02  0a 00 00 00 40 00 00 00  |....(.......@...|
00000050  08 04 00 00 3b 00 04 00  60 0c 00 00 60 0c 00 00  |....;...`...`...|
00000060  48 04 00 00 4e 00 04 00  80 00 00 00 80 00 00 00  |H...N...........|
00000070  a8 10 00 00 5e 00 04 02  01 00 00 00 80 00 00 00  |....^...........|
00000080  28 11 00 00 6d 00 04 02  29 00 00 00 80 00 00 00  |(...m...).......|
00000090  a8 11 00 00 43 41 54 45  47 4f 52 59 00 50 41 52  |....CATEGORY.PAR|
000000a0  45 4e 54 41 4c 5f 4c 45  56 45 4c 00 53 41 56 45  |ENTAL_LEVEL.SAVE|
000000b0  44 41 54 41 5f 44 45 54  41 49 4c 00 53 41 56 45  |DATA_DETAIL.SAVE|
000000c0  44 41 54 41 5f 44 49 52  45 43 54 4f 52 59 00 53  |DATA_DIRECTORY.S|
000000d0  41 56 45 44 41 54 41 5f  46 49 4c 45 5f 4c 49 53  |AVEDATA_FILE_LIS|
000000e0  54 00 53 41 56 45 44 41  54 41 5f 50 41 52 41 4d  |T.SAVEDATA_PARAM|
000000f0  53 00 53 41 56 45 44 41  54 41 5f 54 49 54 4c 45  |S.SAVEDATA_TITLE|
00000100  00 54 49 54 4c 45 00 00  4d 53 00 00 01 00 00 00  |.TITLE..MS......|
00000110  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000510  55 43 4a 53 31 30 30 30  31 00 00 00 00 00 00 00  |UCJS10001.......|
00000520  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000550  d0 64 69 08 00 00 00 00  00 00 00 00 00 00 00 00  |.di.............|
00000560  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000570  44 41 54 41 2e 42 49 4e  00 00 00 00 00 63 34 44  |DATA.BIN.....c4D|
00000580  55 0a 74 a6 d4 cc 30 af  f7 6a 51 ba 17 00 00 00  |U.t...0..jQ.....|
00000590  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000011b0  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000011c0  f2 1d 8f 8a 80 ed f2 a4  dd 85 63 a7 a7 93 b6 30  |..........c....0|
000011d0  a5 0c ba ad 7f 62 77 33  c3 98 95 ef 97 4c d3 42  |.....bw3.....L.B|
000011e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000012b0  e3 81 bf e3 82 93 e3 81  aa e3 81 ae ef bc a7 ef  |................|
000012c0  bc af ef bc ac ef bc a6  20 e3 83 9d e3 83 bc e3  |........ .......|
000012d0  82 bf e3 83 96 e3 83 ab  00 00 00 00 00 00 00 00  |................|
000012e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001330


Last edited by Guest on Sat Jan 08, 2005 10:11 pm; edited 1 time in total
Back to top
Guest






PostPosted: Sat Jan 08, 2005 8:19 am    Post subject: More savefile...this time from Oopo's bane Reply with quote

Not just savegames PARAM.SFO can be read. There is a similar file, probably by the same name, included in the "Oopo's Bane" firmware download package.

Here is output from the program:

Code:
=============================================================================
PlayStation Portable PSF File Data
=============================================================================

Filename                : ooposbane.sfo

Start of section labels : b4
Start of section data   : 11c
Unknown header data     : 01 01 00 00
Number of Sections      : 10

Sect Loff Doff Dsiz Duse Dtyp Unkn     Label             Value
=============================================================================
  0  0000 0000 0004 0004  04  0004     BOOTABLE         = 1
  1  0009 0004 0004 0003  02  0004     CATEGORY         = MG
  2  0012 0008 0010 000b  02  0004     DISC_ID          = ABCD-00000
  3  001a 0018 0008 0005  02  0004     DISC_VERSION     = 1.00
  4  0027 0020 0040 0001  02  0004     DRIVER_PATH      =
  5  0033 0060 0004 0003  02  0004     LANGUAGE         = JP
  6  003c 0064 0004 0004  04  0004     PARENTAL_LEVEL   = 1
  7  004b 0068 0008 0005  02  0004     PSP_SYSTEM_VER   = 1.00
  8  005a 0070 0004 0004  04  0004     REGION           = 32768
  9  0061 0074 0080 000f  02  0004     TITLE            = APP00(balloon)
=============================================================================
Loff = Offset of the Label Field within the Label section.
Doff = Offset of the Data Field within the Data section.
Dsiz = Size of the Data Field within the Data section.
Duse = Amount of the Data Field that currently contains data.
Dtyp = The Data Field type. 0 = Binary (?), 4 = Integer Word, 2 = String.
Unkn = Unknown field usage.


And of course, the basic hexdump -C of the same file:

Code:
00000000  00 50 53 46 01 01 00 00  b4 00 00 00 1c 01 00 00  |.PSF............|
00000010  0a 00 00 00 00 00 04 04  04 00 00 00 04 00 00 00  |................|
00000020  00 00 00 00 09 00 04 02  03 00 00 00 04 00 00 00  |................|
00000030  04 00 00 00 12 00 04 02  0b 00 00 00 10 00 00 00  |................|
00000040  08 00 00 00 1a 00 04 02  05 00 00 00 08 00 00 00  |................|
00000050  18 00 00 00 27 00 04 02  01 00 00 00 40 00 00 00  |....'.......@...|
00000060  20 00 00 00 33 00 04 02  03 00 00 00 04 00 00 00  | ...3...........|
00000070  60 00 00 00 3c 00 04 04  04 00 00 00 04 00 00 00  |`...<...........|
00000080  64 00 00 00 4b 00 04 02  05 00 00 00 08 00 00 00  |d...K...........|
00000090  68 00 00 00 5a 00 04 04  04 00 00 00 04 00 00 00  |h...Z...........|
000000a0  70 00 00 00 61 00 04 02  0f 00 00 00 80 00 00 00  |p...a...........|
000000b0  74 00 00 00 42 4f 4f 54  41 42 4c 45 00 43 41 54  |t...BOOTABLE.CAT|
000000c0  45 47 4f 52 59 00 44 49  53 43 5f 49 44 00 44 49  |EGORY.DISC_ID.DI|
000000d0  53 43 5f 56 45 52 53 49  4f 4e 00 44 52 49 56 45  |SC_VERSION.DRIVE|
000000e0  52 5f 50 41 54 48 00 4c  41 4e 47 55 41 47 45 00  |R_PATH.LANGUAGE.|
000000f0  50 41 52 45 4e 54 41 4c  5f 4c 45 56 45 4c 00 50  |PARENTAL_LEVEL.P|
00000100  53 50 5f 53 59 53 54 45  4d 5f 56 45 52 00 52 45  |SP_SYSTEM_VER.RE|
00000110  47 49 4f 4e 00 54 49 54  4c 45 00 00 01 00 00 00  |GION.TITLE......|
00000120  4d 47 00 00 41 42 43 44  2d 30 30 30 30 30 00 00  |MG..ABCD-00000..|
00000130  00 00 00 00 31 2e 30 30  00 00 00 00 00 00 00 00  |....1.00........|
00000140  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000170  00 00 00 00 00 00 00 00  00 00 00 00 4a 50 00 00  |............JP..|
00000180  01 00 00 00 31 2e 30 30  00 00 00 00 00 80 00 00  |....1.00........|
00000190  41 50 50 30 30 28 62 61  6c 6c 6f 6f 6e 29 00 00  |APP00(balloon)..|
000001a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000210


Last edited by Guest on Sat Jan 08, 2005 10:11 pm; edited 1 time in total
Back to top
Guest






PostPosted: Sat Jan 08, 2005 8:27 am    Post subject: Reply with quote

Now for some more commentary,

The files in question appear to contain paramters/environment that are relevant to the respective functions of the "saves". In the case of hot shotz golf, that was a bonafide savegame. In the case of the firmware update, its more relevant to the act of updating firmware.

There are still some fields of the header and sections that I haven't figured out.

Also, especially in the hot shots golf save, there are from data fields that appear to contain, not just specific basic data types, but extended data types.

Given the heavy usage of offsets and strings in these files, it offers interesting possibilities for naughty tinkering.
Back to top
ooPo
Site Admin


Joined: 17 Jan 2004
Posts: 2032
Location: Canada

PostPosted: Sat Jan 08, 2005 11:35 am    Post subject: Reply with quote

ooposbane.sfo

I like it. :)
Back to top
View user's profile Send private message Visit poster's website
Guest






PostPosted: Sat Jan 08, 2005 10:05 pm    Post subject: Ridge Racers Reply with quote

Here is a savegame, from Ridge Racers, which has much more in terms of embedded data. For instance. DATA.BIN is seen in the hexdump, but it isn't seen by the program because it can't understand the huge data blob that happens to contain that string.

Also, some of the string data is in Japanese. You should be able to see some Kanji and Katakna text. You may need to set UTF-8 encoding in your browers to see it properly.

Here is the PARAM.SFO parsing:

Code:
=============================================================================
PlayStation Portable PSF File Data
=============================================================================

Filename                : PARAM.SFO

Start of section labels : 94
Start of section data   : 108
Unknown header data     : 01 01 00 00
Number of Sections      : 8

Sect Loff Doff Dsiz Duse Dtyp Unkn     Label             Value
=============================================================================
  0  0000 0000 0004 0002  02  0004     CATEGORY         = MS
  1  0009 0004 0004 0004  04  0004     PARENTAL_LEVEL   = 1
  2  0018 0008 0400 0068  02  0004     SAVEDATA_DETAIL  = 「リッジレーサーズ」ゲームデータ
プレイヤーネーム:XEVIOUS
走行距離:0km

  3  0028 0408 0040 000d  02  0004     SAVEDATA_DIRECTORY = ULJS00001000
  4  003b 0448 0c60 0c60  00  0004     SAVEDATA_FILE_LIST = Binary Data
  5  004e 10a8 0080 0080  00  0004     SAVEDATA_PARAMS  = Binary Data
  6  005e 1128 0080 0013  02  0004     SAVEDATA_TITLE   = ゲームデータ
  7  006d 11a8 0080 0019  02  0004     TITLE            = リッジレーサーズ
=============================================================================
Loff = Offset of the Label Field within the Label section.
Doff = Offset of the Data Field within the Data section.
Dsiz = Size of the Data Field within the Data section.
Duse = Amount of the Data Field that currently contains data.
Dtyp = The Data Field type. 0 = Binary (?), 4 = Integer Word, 2 = String.
Unkn = Unknown field usage.


And of course, the hexdump:

Code:
00000000  00 50 53 46 01 01 00 00  94 00 00 00 08 01 00 00  |.PSF............|
00000010  08 00 00 00 00 00 04 02  02 00 00 00 04 00 00 00  |................|
00000020  00 00 00 00 09 00 04 04  04 00 00 00 04 00 00 00  |................|
00000030  04 00 00 00 18 00 04 02  68 00 00 00 00 04 00 00  |........h.......|
00000040  08 00 00 00 28 00 04 02  0d 00 00 00 40 00 00 00  |....(.......@...|
00000050  08 04 00 00 3b 00 04 00  60 0c 00 00 60 0c 00 00  |....;...`...`...|
00000060  48 04 00 00 4e 00 04 00  80 00 00 00 80 00 00 00  |H...N...........|
00000070  a8 10 00 00 5e 00 04 02  13 00 00 00 80 00 00 00  |....^...........|
00000080  28 11 00 00 6d 00 04 02  19 00 00 00 80 00 00 00  |(...m...........|
00000090  a8 11 00 00 43 41 54 45  47 4f 52 59 00 50 41 52  |....CATEGORY.PAR|
000000a0  45 4e 54 41 4c 5f 4c 45  56 45 4c 00 53 41 56 45  |ENTAL_LEVEL.SAVE|
000000b0  44 41 54 41 5f 44 45 54  41 49 4c 00 53 41 56 45  |DATA_DETAIL.SAVE|
000000c0  44 41 54 41 5f 44 49 52  45 43 54 4f 52 59 00 53  |DATA_DIRECTORY.S|
000000d0  41 56 45 44 41 54 41 5f  46 49 4c 45 5f 4c 49 53  |AVEDATA_FILE_LIS|
000000e0  54 00 53 41 56 45 44 41  54 41 5f 50 41 52 41 4d  |T.SAVEDATA_PARAM|
000000f0  53 00 53 41 56 45 44 41  54 41 5f 54 49 54 4c 45  |S.SAVEDATA_TITLE|
00000100  00 54 49 54 4c 45 00 00  4d 53 00 00 01 00 00 00  |.TITLE..MS......|
00000110  e3 80 8c e3 83 aa e3 83  83 e3 82 b8 e3 83 ac e3  |................|
00000120  83 bc e3 82 b5 e3 83 bc  e3 82 ba e3 80 8d e3 82  |................|
00000130  b2 e3 83 bc e3 83 a0 e3  83 87 e3 83 bc e3 82 bf  |................|
00000140  0a e3 83 97 e3 83 ac e3  82 a4 e3 83 a4 e3 83 bc  |................|
00000150  e3 83 8d e3 83 bc e3 83  a0 ef bc 9a 58 45 56 49  |............XEVI|
00000160  4f 55 53 0a e8 b5 b0 e8  a1 8c e8 b7 9d e9 9b a2  |OUS.............|
00000170  ef bc 9a 30 6b 6d 0a 00  00 00 00 00 00 00 00 00  |...0km..........|
00000180  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000510  55 4c 4a 53 30 30 30 30  31 30 30 30 00 00 00 00  |ULJS00001000....|
00000520  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000550  48 24 6b 08 00 00 00 00  00 00 00 00 00 00 00 00  |H$k.............|
00000560  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000570  44 41 54 41 2e 42 49 4e  00 00 00 00 00 d7 44 a4  |DATA.BIN......D.|
00000580  a2 d4 79 79 33 79 30 74  c8 1d 1a 41 fa 00 00 00  |..yy3y0t...A....|
00000590  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000011b0  01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000011c0  47 16 b8 45 53 10 f0 3a  69 e8 82 d2 38 17 20 fd  |G..ES..:i...8. .|
000011d0  64 3e 2b 3d e3 76 80 c2  09 50 3c 11 df 8d 90 3f  |d>+=.v...P<....?|
000011e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001230  e3 82 b2 e3 83 bc e3 83  a0 e3 83 87 e3 83 bc e3  |................|
00001240  82 bf 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00001250  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000012b0  e3 83 aa e3 83 83 e3 82  b8 e3 83 ac e3 83 bc e3  |................|
000012c0  82 b5 e3 83 bc e3 82 ba  00 00 00 00 00 00 00 00  |................|
000012d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001330
Back to top
beatwho



Joined: 15 Dec 2004
Posts: 28

PostPosted: Sun Jan 09, 2005 1:36 pm    Post subject: Reply with quote

so i tried to get it working, copied the data into a psp.c
make psp
ran it..

Seg fault?

tried it with another game... same thing

what am I doing wrong?

edit: removed links


Last edited by beatwho on Sun Jan 09, 2005 9:25 pm; edited 1 time in total
Back to top
View user's profile Send private message
Guest






PostPosted: Sun Jan 09, 2005 3:50 pm    Post subject: Reply with quote

I tried your dokodemo save and it worked fine for me.

I haven't tested this on platforms over than Mac OSX, but its written so that it should work with no problem anywhere POSIX. Anyhow please let me know the following:

1. Are there any messages (warnings, etc...) printed when you compile it ?
2. Does the program manage to print ANYTHING when its run, besides segfault ?
3. Anyhow, I made one modification to the program to check if the mmap call succeeds and print a message if it doesn't. Otherwise, if it fails, a segfault will occur for sure (though dunno why it should fail). Anyhow, try recopying and rerunning the program and let me know if anything gets printed out at all.
Back to top
beatwho



Joined: 15 Dec 2004
Posts: 28

PostPosted: Sun Jan 09, 2005 4:55 pm    Post subject: Reply with quote

[root@heis psp]# make psp
cc psp.c -o psp
[root@heis psp]# ls
PARAM.SFO psp psp.c
[root@heis psp]# ./psp
mmap failed!: Invalid argument
[root@heis psp]# uname -a
Linux heis.nakedinjapan.net 2.4.27 #1 Wed Nov 17 20:29:58 JST 2004 i686 i686 i386 GNU/Linux

well there ya go, looks like it opens the file fine then mmap fails. I might go read the man page for mmap since i've never even heard of it before :)

Thanks

edit: I changed the mmap stuff to fopen/fread and it worked ^_^
Back to top
View user's profile Send private message
Guest






PostPosted: Sun Jan 09, 2005 5:18 pm    Post subject: Reply with quote

beatwho wrote:


edit: I changed the mmap stuff to fopen/fread and it worked ^_^


Yeah, thats what I was going to do if it turned out to be mmap that was the problem. I am a mmap-kinda-guy which is why I used it, but there is no reason its a must.

Later when I get back from Akihabara I will throw out the mmap stuff and replace it with:

fopen(...)
fseek(...,SEEK_END)
fsize = ftell()
frewind(...)
psf = (u_int8_t*)calloc(fsize);
fread(psf,...,fsize,...)
fclose(...)

Which should make it more portable.

Thanks for testing it out!
Back to top
Guest






PostPosted: Sun Jan 09, 2005 9:18 pm    Post subject: Reply with quote

Ok, I updated the program listing at the top of this thread with the newest version that removes the mmap() and replaces it with standard file i/o routines to accomplish the same thing. It should now be more portable.
Back to top
annerajb



Joined: 31 Mar 2005
Posts: 40

PostPosted: Thu Mar 31, 2005 6:20 am    Post subject: Reply with quote

this my seen like a noob question but. how the you compile this program. and what is made in c c++ . btw i have visual basic .net
Back to top
View user's profile Send private message MSN Messenger
DBG



Joined: 28 Mar 2005
Posts: 12

PostPosted: Thu Mar 31, 2005 9:48 am    Post subject: Reply with quote

You will need a C compilier, personally I use www.cygwin.com or www.mingw.org. There are lots of how-to's out there, but if you need more help just ask. I don't believe VB can handle the file, but if you have access to Visual Studio you should be able to copy the text into a .c file and build that.
Back to top
View user's profile Send private message
Deathbringer



Joined: 01 Apr 2005
Posts: 11

PostPosted: Fri Apr 01, 2005 5:03 am    Post subject: Reply with quote

Can someone compile it for me? Since my good pc are screved up and this machine has Admin lock so i cant install anything...
Back to top
View user's profile Send private message
Grover



Joined: 23 Feb 2005
Posts: 50

PostPosted: Sat Apr 02, 2005 3:00 am    Post subject: Reply with quote

Wondering about these bin files - assuming they are binary files. Is it possible these are executed mips binaries? Or (more likely) specific binary data dictating the way background is drawn, and other effects (sound/music?).
_________________
Bye.
Back to top
View user's profile Send private message
XenuPSP



Joined: 04 Apr 2005
Posts: 3

PostPosted: Mon Apr 04, 2005 12:55 am    Post subject: Reply with quote

FYI--

I've got this compiled and running on my WinXP box using MinGW tools. Running it against an Untold Legends .SFO, I noticed a character in the data section was being gobbled up. I corrected it by changing the fopen() mode from "r" to "rb".
Back to top
View user's profile Send private message
Guest






PostPosted: Mon Apr 04, 2005 1:19 am    Post subject: Reply with quote

XenuPSP wrote:
FYI--

I've got this compiled and running on my WinXP box using MinGW tools. Running it against an Untold Legends .SFO, I noticed a character in the data section was being gobbled up. I corrected it by changing the fopen() mode from "r" to "rb".


Thanks for the update, I will correct the source.

Note, UNIX ignores "b" typically because there is no difference between text and binary data during file I/O, but dos/win implementations of fopen() in the C library may make such a distinction.
Back to top
LiquidIce



Joined: 04 Apr 2005
Posts: 55

PostPosted: Mon Apr 04, 2005 1:24 am    Post subject: Reply with quote

This is good stuff gorim, thanks!

I compiled this under WinXP using cygwin, worked flawlessly.

Here is the output of some of my game saves if anyone is intrested:

Code:

NFS Underground:

=============================================================================
PlayStation Portable PSF File Data
=============================================================================

Filename                : PARAM.SFO

Start of section labels : 94
Start of section data   : 108
Unknown header data     : 01 01 00 00
Number of Sections      : 8

Sect Loff Doff Dsiz Duse Dtyp Unkn     Label             Value
=============================================================================
  0  0000 0000 0004 0002  02  0004     CATEGORY         = MS
  1  0009 0004 0004 0004  04  0004     PARENTAL_LEVEL   = 3
  2  0018 0008 0400 0001  02  0004     SAVEDATA_DETAIL  =
  3  0028 0408 0040 000d  02  0004     SAVEDATA_DIRECTORY = ULUS10007001
  4  003b 0448 0c60 0c60  00  0004     SAVEDATA_FILE_LIST = Binary Data
  5  004e 10a8 0080 0080  00  0004     SAVEDATA_PARAMS  = Binary Data
  6  005e 1128 0080 0007  02  0004     SAVEDATA_TITLE   = LIQUID
  7  006d 11a8 0080 0025  02  0004     TITLE            = NEED FOR SPEED™ UNDERGROUND RIVALS
=============================================================================
Loff = Offset of the Label Field within the Label section.
Doff = Offset of the Data Field within the Data section.
Dsiz = Size of the Data Field within the Data section.
Duse = Amount of the Data Field that currently contains data.
Dtyp = The Data Field type. 0 = Binary (?), 4 = Integer Word, 2 = String.
Unkn = Unknown field usage.





Code:

Untold Legends

=============================================================================
PlayStation Portable PSF File Data
=============================================================================

Filename                : PARAM.SFO

Start of section labels : 94
Start of section data   : 108
Unknown header data     : 01 01 00 00
Number of Sections      : 8

Sect Loff Doff Dsiz Duse Dtyp Unkn     Label             Value
=============================================================================
  0  0000 0000 0004 0002  02  0004     CATEGORY         = MS
  1  0009 0004 0004 0004  04  0004     PARENTAL_LEVEL   = 5
  2  0018 0008 0400 002e  02  0004     SAVEDATA_DETAIL  = The City of Aven
Search the Secret Catacombs
  3  0028 0408 0040 000e  02  0004     SAVEDATA_DIRECTORY = LUS100030000
  4  003b 0448 0c60 0c60  00  0004     SAVEDATA_FILE_LIST = Binary Data
  5  004e 10a8 0080 0080  00  0004     SAVEDATA_PARAMS  = Binary Data
  6  005e 1128 0080 0018  02  0004     SAVEDATA_TITLE   = IQUIDICE <Berserker> 3
  7  006d 11a8 0080 0029  02  0004     TITLE            = ntold Legends: Brotherhood of the Blade
=============================================================================
Loff = Offset of the Label Field within the Label section.
Doff = Offset of the Data Field within the Data section.
Dsiz = Size of the Data Field within the Data section.
Duse = Amount of the Data Field that currently contains data.
Dtyp = The Data Field type. 0 = Binary (?), 4 = Integer Word, 2 = String.
Unkn = Unknown field usage.



Code:

Dynasty Warriors

=============================================================================
PlayStation Portable PSF File Data
=============================================================================

Filename                : PARAM.SFO

Start of section labels : 94
Start of section data   : 108
Unknown header data     : 01 01 00 00
Number of Sections      : 8

Sect Loff Doff Dsiz Duse Dtyp Unkn     Label             Value
=============================================================================
  0  0000 0000 0004 0002  02  0004     CATEGORY         = MS
  1  0009 0004 0004 0004  04  0004     PARENTAL_LEVEL   = 5
  2  0018 0008 0400 0071  02  0004     SAVEDATA_DETAIL  = The Battlefield has been shifted to
the "PSP"!
Join the fight for supremacy now and become a DYNASTY WARRIOR!
  3  0028 0408 0040 000d  02  0004     SAVEDATA_DIRECTORY = US10004000
  4  003b 0448 0c60 0c60  00  0004     SAVEDATA_FILE_LIST = Binary Data
  5  004e 10a8 0080 0080  00  0004     SAVEDATA_PARAMS  = Binary Data
  6  005e 1128 0080 000a  02  0004     SAVEDATA_TITLE   = me data
  7  006d 11a8 0080 0011  02  0004     TITLE            = NASTY WARRIORS
=============================================================================
Loff = Offset of the Label Field within the Label section.
Doff = Offset of the Data Field within the Data section.
Dsiz = Size of the Data Field within the Data section.
Duse = Amount of the Data Field that currently contains data.
Dtyp = The Data Field type. 0 = Binary (?), 4 = Integer Word, 2 = String.
Unkn = Unknown field usage.



Just so that we're all on the same page. Are you all suggesting we may be able to modify the saved game files to inject our own code?
Back to top
View user's profile Send private message Visit poster's website
Guest






PostPosted: Mon Apr 04, 2005 1:36 am    Post subject: Reply with quote

LiquidIce wrote:
Just so that we're all on the same page. Are you all suggesting we may be able to modify the saved game files to inject our own code?


That possibility always exists wherever file i/o is done and we can modify the files being read.

However, as shown in another thread on manipulating the .SFO file data, modifications can even be used to probe and display internal memory data, which in itself is a very important ability. Especially since we are still far from being able to inject code.
Back to top
ModernRonin



Joined: 07 May 2005
Posts: 10
Location: Colorado

PostPosted: Sat May 07, 2005 5:55 pm    Post subject: Port to Win98 done. Reply with quote

I added some typedefs to your code to make this compile under Visual C++ 6.0 on Win98. Three typedefs:

Code:

// Some data type definitions for Intel Doze platforms, 2005/05/06, bwc
typedef unsigned int u_int32_t;
typedef unsigned short int u_int16_t ;
typedef unsigned char u_int8_t;


And I had to cast some pointers explicitly under case 2 to make the compiler quit whining:

Code:

strncpy((char *)strbuf, (const char *)&psfdata[le32(sect->data_off)], dsize);


In any event, it compiles and seems to work. Here's the output of running it the on PARAM.SFO inside Sony's Upgrade to 1.5 EBOOT.PBP:

Code:

=============================================================================
PlayStation Portable PSF File Data
=============================================================================

Filename                : PARAM.SFO

Start of section labels : 104
Start of section data   : 18c
Unknown header data     : 01 01 00 00
Number of Sections      : 15

Sect Loff Doff Dsiz Duse Dtyp Unkn     Label             Value
=============================================================================
  0  0000 0000 0004 0004  04  0004     BOOTABLE         = 1
  1  0009 0004 0004 0003  02  0004     CATEGORY         = MG
  2  0012 0008 0008 0005  02  0004     DISC_VERSION     = 1.00
  3  001f 0010 0004 0004  04  0004     PARENTAL_LEVEL   = 1
  4  002e 0014 0004 0004  04  0004     REGION           = 32768
  5  0035 0018 0080 0017  02  0004     TITLE            = PSP_äó Update ver 1.
  6  003b 0098 0080 0023  02  0004     TITLE_0          = PSP_äó ¶éó¶ââ¶âù¶âç¶
  7  0043 0118 0080 001e  02  0004     TITLE_2          = Mise +á jour PSP_äó
  8  004b 0198 0080 0023  02  0004     TITLE_3          = Actualizaci+¦n de PS
  9  0053 0218 0080 0020  02  0004     TITLE_4          = PSP_äó-Aktualisierun_
 10  005b 0298 0080 0025  02  0004     TITLE_5          = Aggiornamento della _
ver. 1.50                                                                     _
 11  0063 0318 0080 001a  02  0004     TITLE_6          = PSP_äó-update versie_
 12  006b 0398 0080 001f  02  0004     TITLE_7          = Actualiza+º+úo PSP_ä_
 13  0073 0418 0080 0029  02  0004     TITLE_8          = -P-_-+-+-_-+-¦-+-+-¦_
 14  007b 0498 0008 0005  02  0004     UPDATER_VER      = 1.50                _
============================================================================= _
Loff = Offset of the Label Field within the Label section.                    _
Doff = Offset of the Data Field within the Data section.                      _
Dsiz = Size of the Data Field within the Data section.                        _
Duse = Amount of the Data Field that currently contains data.                 _
Dtyp = The Data Field type. 0 = Binary (?), 4 = Integer Word, 2 = String.     _
Unkn = Unknown field usage.                                                   _


Source code and a compiled executable are available at the URL in my signature. Though if you're smart you'll compile it yourself - running random .EXE files off the net is a real, real stupid thing to do.
_________________
http://www.kaosol.net/~mackys/psp/
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Guest






PostPosted: Sun May 08, 2005 4:01 pm    Post subject: Reply with quote

Hey thanks for the update on letting people know how they can compile it on win98! Do newer windows platforms understand the u_intX_t types ? Or is that just a GCC thing ?

The reason I stuck with the u_intX_t types is to guarantee hardware neutrality as much as possible, and to be as specific as possible in how large struct members in the file are.

I may merge this in to the main PARAM.SFO source via #ifdefs platform checks if there is enough demand for win98, or I can just let you maintain that variant of the source.
Back to top
ModernRonin



Joined: 07 May 2005
Posts: 10
Location: Colorado

PostPosted: Sun May 08, 2005 5:19 pm    Post subject: Reply with quote

Hey thanks for the update on letting people know how they can compile it on win98!

I'm kinda curious if my executable works under 2k or XP. Actually, I'm curious if it even works on someone else's 98 box. For all I know it may depend on some weirdo DLL that only I have.

Do newer windows platforms understand the u_intX_t types ? Or is that just a GCC thing ?

I don't know. We have a couple of people here who seem to have VC++ 7.0 (.NET edition or something), maybe one of them can try and compile it and tell us.

The reason I stuck with the u_intX_t types is to guarantee hardware neutrality as much as possible, and to be as specific as possible in how large struct members in the file are.

Yeah, I think that's a good thing. That's why I put in typedefs instead of just search and replacing the code. Actually, at first I tried to make it even simpler, using #defines. But that breaks some things. The compiler doesn't seem to be able to handle casts or variable declarations with a #defined type. Don't ask me why, I have no idea...

I may merge this in to the main PARAM.SFO source via #ifdefs platform checks if there is enough demand for win98, or I can just let you maintain that variant of the source.

Probably best to merge it into the main source. I'm not sure what symbol you can check to determine if you're on a Win9X box, though... maybe there's some OS_VER() macro that I don't know about.

Ah, here we go... http://softwareforums.intel.com/ids/board/message?board.id=16&message.id=1811

Looks like you can check #if _MSC_VER == 1200. That's the giveaway that you're working with Visual C++ 6.0, which is the Win98, circa 1998 version of VC++.
_________________
http://www.kaosol.net/~mackys/psp/


Last edited by ModernRonin on Sun May 08, 2005 5:22 pm; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail Visit poster's website
MelGibson



Joined: 10 Apr 2005
Posts: 58

PostPosted: Sun May 08, 2005 5:21 pm    Post subject: Reply with quote

Short Info: Even though it was compiled on and for win98 the program runs flawless on a win2000 /SP4 box i tested.
Back to top
View user's profile Send private message
ModernRonin



Joined: 07 May 2005
Posts: 10
Location: Colorado

PostPosted: Sun May 08, 2005 5:26 pm    Post subject: Reply with quote

Short Info: Even though it was compiled on and for win98 the program runs flawless on a win2000 /SP4 box i tested.

Sweet! Thanks, Mel.
_________________
http://www.kaosol.net/~mackys/psp/
Back to top
View user's profile Send private message Send e-mail Visit poster's website
larox



Joined: 04 Jul 2005
Posts: 2
Location: Singapore

PostPosted: Mon Jul 04, 2005 4:45 pm    Post subject: questions Reply with quote

hey guys, can I ask you all some questions?
From the above posts, there is this u_int32_t thing...
I don't know what is it for, can you guys tell me?
is u_int32_t same as uint32_t ? And what is uint32_t used for?
Sorry for the questions, I am new to software development.
Thanks
_________________
Never compare N.A with Turbo cars because they are of different classes~
Back to top
View user's profile Send private message
Guest






PostPosted: Mon Jul 04, 2005 5:39 pm    Post subject: Reply with quote

u_int32_t == unsigned integer 32 bit type.

uint32_t is almost certainly the same thing, just without an underscore.

Is it quite common for people to use typedef's or #define's in order to make such types less awkward. Also, different compilers might define them different ways. I really don't know if this is a compiler implementation-dependant issue, but it appears to be.

In your case, I don't really know if uint32_t is a compiler defined type, a standard #include defined type, or is in some user created source file. Nor would I know if it is #define'd or typedef'ed in the include file if that was the location. Check your compiler's manual.

Anyhow, as I mentioned, the reason for being specific, is that things such as "long" and "int" are actually vague with respect to the size of the type in terms of bits - they are hardware platform dependant.
Back to top
larox



Joined: 04 Jul 2005
Posts: 2
Location: Singapore

PostPosted: Tue Jul 05, 2005 1:05 am    Post subject: thank you Reply with quote

thanks alot for help. i am actually intending to do up my project which i think might require this uint32_t data type for the assigning of static ip address.

good day.~
_________________
Never compare N.A with Turbo cars because they are of different classes~
Back to top
View user's profile Send private message
LanThief



Joined: 18 Jan 2006
Posts: 1
Location: Austin, TX

PostPosted: Wed Jan 18, 2006 3:39 am    Post subject: Python port of PARAM.SFO reader Reply with quote

I was searching on PARAM.SFO files when I came across this thread, and found this C example very helpful. Thanks Chris Barrera for the code example. I do most of my game development in Python so after using this C example last night, I took a crack at it in Python for anyone interested.

Yes, there are more mysteries to uncover and so there will be more edits to come as we all contribute to the C example.

Cheers !

Code:
"""
    Many Thanks to Chris Barrera for the C example that was used in converting
    over to python.  I tried to keep it as close to the C example so people can
    follow them both.  It could be written a little cleaner.  Please feel free :)

    /*
     * PSP PSF File Parser v 0.2
     *
     * Copyright Chris Barrera a.k.a. Gorim
     * Date  : January 8 2005
     *
     * This source is licensed under the terms of the Academic Free License 2.0
     *
     */

    Python Conversion by: Chris Kreager a.k.a LanThief
    Date: January 17, 2006
"""

#Extra Hex Tool: Start------------------------------------------------------------------
"""
    Here are some extra functions I use for hex conversions
    You may want to replace them with your own.
    I usually import these from a separate module, but I cut
    and pasted them here so the example could work as is.
"""

def str2hex(s,size=8):
    "String converter to hex"
    if (len(s)*size) <= 32:    h = 0x0
    else:                      h = 0x0L
    for c in s:
        h = (h << size) | ord(c)
    return h

def hex2hexList(h,size=8,reverse=True):
    "hex converter to hex list"
    return hex2hexList_charList(h,size,reverse,False)

def hex2hexList_charList(h,size=8,reverse=True,ischr=True):
    "hex converter to either chr list or hex list"
    l = []
    if h == 0x0:
        if ischr: l.append(chr(h))
        else: l.append(h)
        return l
    while h:
        _h = (h & mask_bit(size))
        if ischr: horc = chr(_h)
        else: horc = _h
        l.append(horc)
        h = (h >> size)
    if reverse:l.reverse()
    return l

def str2hexList(s, size = 8, reverse=True):
    "String converter to hex list"
    return hex2hexList( str2hex(s), size, reverse )

def mask_bit(size=8):
    if size > 32:   return (0x1L << size) - (0x1)
    else:           return (0x1  << size) - (0x1)
   
#Extra Hex Tool: End------------------------------------------------------------------


#Example Python Code: Start--------------------------------------------------------
"""
    Below is a quick python like equivalent to the C example.
    I put this together last night for myself and any of you that
    might like to try your hand with this in Python

    Cheers,
    - LanThief@GMail.com
"""
import sys

PsfMagic = "\0PSF"
PsfDefaultFile = "PARAM.SFO"


def le32(bits):
    bytes = str2hexList(bits)
    result = 0x0
    offset = 0
    for byte in bytes:
        result |= byte << offset
        offset +=8
    return result
##    # IndexError on zero bits - removed code
##    return (bytes[0] | (bytes[1]<<8) | (bytes[2]<<16) | (bytes[3]<<24)) 

def le16(bits):
    bytes = str2hexList(bits)
    if len(bytes) > 1:
        return (bytes[0] | bytes[1]<<8)
    return (bytes[0] | 0x0<<8)

class PsfHdr:
    size = 20
    def __init__(self, bits):
        self.size = 20
        self.data = bits[:self.size]
        self.magic = str2hexList( bits[:4] )
        self.rfu000 = str2hexList( bits[4:8] )
        self.label_ptr = bits[8:12]
        self.data_ptr = bits[12:16]
        self.nsects = bits[16:20]

    def __len__(self):
        return self.size

class PsfSec:
    size = 16
    def __init__(self, bits):
        self.size = 16
        self.data = bits[:self.size]
        self.label_off = bits[:2]
        self.rfu001 = bits[2:3]
        self.data_type = str2hex(bits[3:4]) # string=2, integer=4, binary=0
        self.datafield_used = bits[4:8]
        self.datafield_size = bits[8:12]
        self.data_off = bits[12:16]

    def __len__(self):
        return self.size
       
psf = None

def main(argc, argv):
    global psf

    PsfFilename = ( argv[1:2], PsfDefaultFile )[argc !=2]   # I use a slice [1:2] to avoid IndexError

    try:
        PsfFile = open(PsfFilename,'rb')
    except IOError, name:
            print "File cannot be opened.", name
            sys.exit(1)

    psf = PsfFile.read()
    PsfFile.close()

    if not psf.find(PsfMagic) == 0:
        print "This file is not a PSF file ! [PSF Magic == 0x%08X]\n" % str2hex(PsfMagic)
        sys.exit(1)

    psfheader = PsfHdr(psf)
    psfsections = PsfSec(psf[PsfHdr.size:])
    psflabels = psf[le32(psfheader.label_ptr):]
    psfdata = psf[le32(psfheader.data_ptr):]

    print "============================================================================="
    print "PlayStation Portable PSF File Data"
    print "============================================================================="
    print "\nFilename                : %s\n" % PsfFilename
    print "Start of section labels : %2x" % le32(psfheader.label_ptr)
    print "Start of section data   : %2x" % le32(psfheader.data_ptr)
    print "Unknown header data     : %02x %02x %02x %02x" % (
            psfheader.rfu000[0],psfheader.rfu000[1],psfheader.rfu000[2],
            psfheader.rfu000[3])
    print "Number of Sections      : %d\n" % le32(psfheader.nsects)
    print "Sect Loff Doff Dsiz Duse Dtyp Unkn     Label             Value"
    print "============================================================================="

    index = PsfHdr.size
    sect = psfsections
   
    for i in xrange(0, le32(psfheader.nsects) ):
        print " %2d  %04x %04x %04x %04x  %02x  %04x     %-18s = " % ( i,
            le16(sect.label_off), le32(sect.data_off), le32(sect.datafield_size),
            le32(sect.datafield_used), sect.data_type, str2hex(sect.rfu001),
            psflabels[le16(sect.label_off):].split('\x00')[0] ),

        if sect.data_type   == 0x2:         # string
            print "%s" % psfdata[le32(sect.data_off):].split('\x00\x00')[0]
           
        elif sect.data_type == 0x4:         # Integer
            print "%d" % le32(psfdata[le32(sect.data_off)])
                   
        elif sect.data_type == 0x0:         # binary data ?
            print "Binary Data"
           
        else:                               # Dunno yet
            print "Yet unknown. Please email save to wildwabbit@gmail"

        index += PsfSec.size
        sect = PsfSec(psf[index:])


    print "=============================================================================\n"
    print "Loff = Offset of the Label Field within the Label section."
    print "Doff = Offset of the Data Field within the Data section."
    print "Dsiz = Size of the Data Field within the Data section."
    print "Duse = Amount of the Data Field that currently contains data."
    print "Dtyp = The Data Field type. 0 = Binary (?), 4 = Integer Word, 2 = String."
    print "Unkn = Unknown field usage.\n"

    return True

#Example Python Code: END--------------------------------------------------------

if __name__ == '__main__':
    import sys
    main(len(sys.argv),sys.argv)

_________________
-lan
Back to top
View user's profile Send private message Send e-mail Visit poster's website AIM Address Yahoo Messenger MSN Messenger
PSP250



Joined: 19 Nov 2005
Posts: 12

PostPosted: Wed Jan 18, 2006 6:49 am    Post subject: Reply with quote

Good Job.

From my memdumps I could note these stubs are used for retrieving the information:

sceSystemFileGetIndexInfo
sceSystemFileGetIndex
sceSystemFileLoadIndex
sceSystemFileLoadAll2

Anyone actually succeeded in doing this on the PSP itself?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group