|
|
#1 | |
|
Homebrew Developer
![]() Join Date: Oct 2011
Location: dev_hdd0/home/
Posts: 510
Likes: 244
Liked 507 Times in 214 Posts
Mentioned: 100 Post(s)
Tagged: 0 Thread(s)
|
[Dissection] Understanding PARAM.SFO structure
Update 1: New image more detailed, text clean up
Update 2: Added "speciall variables with unknown content" and some info about gamesaves Intro I will try to explain how to build an .sfo from scratch with only a hex editor and a calculatorThis give you the flexibility to manipulate them more deeper than any of the actual existant apps (i.e. actually there is no way to "inject" a new variable to an existant .sfo)... additionally, SFO editor for windows has several bugs that ruins the file (it breaks ATRIBUTE, and it lets you add padding) The picture is a PARAM.SFO from the unnofficial SDK fleshl1ght, where i removed completly the variables LICENSE & PARENTAL_LEVEL (because i think are just restrictions for the user and not usefull, and let me create a minimall file for the example) My intention is to document this to ps3devwiki, but im more used to forums, so i will use this message to put some order in my notes PARAM.SFO layout ![]() The structure can be divided in 4 areas: 1,2,3,4,5 is the header 6,7,8,9,10 is the variable table 11 is name table 12 is data table Colours Yellow areas (3,6,11) refers to names (position, offset, and table) Blue areas (4,10,12) refers to datas (position, offset, and table) Light-blue areas (8,9) refers to data sizes (bytes used, block size) Padding & Sizes DONT ADD PADDING, the padding is fixed for every value and is very restrictive, the only place where there is padding is at the end of the "name table", is needed to adjust the size of the whole table to the next multiply of 4 (bytes) The values at the data table can be of 2 types (defined by "data type") UTF-8... or int32 UTF-8 values must be added +1 byte of separation (this includes all the names at the "name table") int32 values has a fixed "block size" that depends of the variable. I.E. TITLE is 128 bytes long, while BOOTABLE is 4 bytes long DONT CHANGE THE BLOCK SIZES, because the ps3 is waiting for a fixed block size (defined in other parts of the firmware), if you use a not-standard "block size" the rest of the .sfo will be readed like corrupted Note that areas 8 & 9 (data used size, and data block size) are very dependant By a simply substraction (9-8) you know the padding (btw... like i said, padding has no importance, because is fixed, and CANT be modifyed in ANY way)... either way, padding can be used for verification purposes When modifying the TITLE of a original PARAM.SFO (not created by you)... you need to change the "data used size" (8) of the value TITLE in his line of the variable table I.E. a game whose name is: "HIPERAMAZING" (is using 12 bytes + 1 because is UTF-8) and you change it to: "Decent Name Game" (you are using 16 + 1 because is UTF-8) Little endian & Big endian The header, and the variable table are in "little endian", the way humans read numbers is exactly the opposite (big endian), so is needed to reverse the order of the value byte by byte to understand something, some examples: Little endian --->reversed---> big endian 11 22 33 44 --->reversed---> 44 33 22 11 = 44332211 12 34 56 78 --->reversed---> 78 56 34 12 = 78563412 01 00 00 00 --->reversed---> 00 00 00 01 = 1 00 00 00 01 --->reversed---> 01 00 00 00 = 1000000 18 01 00 00 --->reversed---> 00 00 01 18 = 118 <----- this is the "data table start position" (4) used in the picture Calculations
Code:
File type
--------
.PSF
File version
-----------
1.1
Start of "Variable_Name_Table"
------------------------------
B4 00 00 00 --->reversed---> 00 00 00 B4 = 0x00B4
Start of "Variable_Data_Table"
------------------------------
18 01 00 00 --->reversed---> 00 00 01 18 = 0x0118
Number of Variables
-------------------
0A 00 00 00 --->reversed---> 00 00 00 0A = A <---hex2dec---> = 10
-----------------------------------------------------------------------------------------------
=============FROM THIS POINT THIS STRUCTURE REPEATS FOR EVERY VARIABLE=========
-----------------------------------------------------------------------------------------------
Zero based offset of variable "Name" from Start of "Variable_Name_Table" (name offset)
--------------------------------------------------------------------------------------
APP_VER 0x00B4-0x00B4=00 = 00 00 00 00 --->reversed---> 00 00 00 00
ATTRIBUTE 0x00BC-0x00B4=08 = 00 00 00 08 --->reversed---> 08 00 00 00
BOOTABLE 0x00C6-0x00B4=12 = 00 00 00 12 --->reversed---> 12 00 00 00
CATEGORY 0x00CF-0x00B4=1B = 00 00 00 1B --->reversed---> 1B 00 00 00
PS3_SYSTEM_VER 0x00D8-0x00B4=24 = 00 00 00 24 --->reversed---> 24 00 00 00
RESOLUTION 0x00E7-0x00B4=33 = 00 00 00 33 --->reversed---> 33 00 00 00
SOUND_FORMAT 0x00F2-0x00B4=3E = 00 00 00 3E --->reversed---> 3E 00 00 00
TITLE 0x00FF-0x00B4=4B = 00 00 00 4B --->reversed---> 4B 00 00 00
TITLE_ID 0x0105-0x00B4=51 = 00 00 00 51 --->reversed---> 51 00 00 00
VERSION 0x010E-0x00B4=5A = 00 00 00 5A --->reversed---> 5A 00 00 00
data_type
---------
04 02 = UTF8
04 04 = int32
04 04 = int32
04 02 = UTF8
04 02 = UTF8
04 04 = int32
04 04 = int32
04 02 = UTF8
04 02 = UTF8
04 02 = UTF8
Total Used Bytes of variable "Data" in Current Data Block (data size)
-------------------------------------------------------------------------
Data type 2=UTF-8 variables must be added + 1
01.00 =5+1=6 bytes <---dec2hex---> 6 = 00 00 00 06 --->reversed---> 06 00 00 00
00 00 02 00 =4 bytes <---dec2hex---> 4 = 00 00 00 04 --->reversed---> 04 00 00 00
01 00 00 00 =4 bytes <---dec2hex---> 4 = 00 00 00 04 --->reversed---> 04 00 00 00
DG =2+1=3 bytes <---dec2hex---> 3 = 00 00 00 03 --->reversed---> 03 00 00 00
03.4100 =7+1=8 bytes <---dec2hex---> 8 = 00 00 00 08 --->reversed---> 08 00 00 00
3F 00 00 00 =4 bytes <---dec2hex---> 4 = 00 00 00 04 --->reversed---> 04 00 00 00
17 03 00 00 =4 bytes <---dec2hex---> 4 = 00 00 00 04 --->reversed---> 04 00 00 00
Disc Package Installer =22+1=23 bytes <---dec2hex---> 17 = 00 00 00 17 --->reversed---> 17 00 00 00
DPIX00001 =9+1=10 bytes <---dec2hex---> A = 00 00 00 0A --->reversed---> 0A 00 00 00
01.00 =5+1=6 bytes <---dec2hex---> 6 = 00 00 00 06 --->reversed---> 06 00 00 00
Total Size In Bytes of variable "Data" in Current Data Block (block size)
-----------------------------------------------------------------------------------------------
Data type 2=UTF-8 variables must be added + 1
Valid block sizes in decimal ---> 2^1=2 2^2=4 2^3=8 2^4=16 2^5=32 2^6=64 2^7=128 2^8=256 2^9=512 2^10=1024 etc...
v
01.00 =5+1=6 bytes + 2 padding = 8 <---dec2hex---> 8 = 00 00 00 08 --->reversed---> 08 00 00 00
00 00 02 00 =4 bytes + 0 padding = 4 <---dec2hex---> 4 = 00 00 00 04 --->reversed---> 04 00 00 00
01 00 00 00 =4 bytes + 0 padding = 4 <---dec2hex---> 4 = 00 00 00 04 --->reversed---> 04 00 00 00
DG =2+1=3 bytes + 1 padding = 4 <---dec2hex---> 4 = 00 00 00 04 --->reversed---> 04 00 00 00
03.4100 =7+1=8 bytes + 0 padding = 8 <---dec2hex---> 8 = 00 00 00 08 --->reversed---> 08 00 00 00
3F 00 00 00 =4 bytes + 0 padding = 4 <---dec2hex---> 4 = 00 00 00 04 --->reversed---> 04 00 00 00
17 03 00 00 =4 bytes + 0 padding = 4 <---dec2hex---> 4 = 00 00 00 04 --->reversed---> 04 00 00 00
Disc Package Installer =22+1=23 bytes + 105 padding = 128 <---dec2hex---> 80 = 00 00 00 80 --->reversed---> 80 00 00 00
DPIX00001 =9+1=10 bytes + 6 padding = 16 <---dec2hex---> 10 = 00 00 00 10 --->reversed---> 10 00 00 00
01.00 =5+1=6 bytes + 2 padding = 8 <---dec2hex---> 8 = 00 00 00 08 --->reversed---> 08 00 00 00
Zero based offset of variable "Data" from start of "Variable_Data_Table" (data offset)
--------------------------------------------------------------------------------------
01.00 0x0118-0x0118= 00 = 00 00 00 00 --->reversed---> 00 00 00 00
00 00 02 00 0x0120-0x0118= 08 = 00 00 00 08 --->reversed---> 08 00 00 00
01 00 00 00 0x0124-0x0118= 0C = 00 00 00 0C --->reversed---> 0C 00 00 00
DG 0x0128-0x0118= 10 = 00 00 00 10 --->reversed---> 10 00 00 00
03.4100 0x012C-0x0118= 14 = 00 00 00 14 --->reversed---> 14 00 00 00
3F 00 00 00 0x0134-0x0118= 1C = 00 00 00 1C --->reversed---> 1C 00 00 00
17 03 00 00 0x0138-0x0118= 20 = 00 00 00 20 --->reversed---> 20 00 00 00
Disc Package Installer 0x013C-0x0118= 24 = 00 00 00 24 --->reversed---> 24 00 00 00
DPIX00001 0x01BC-0x0118= A4 = 00 00 00 A4 --->reversed---> A4 00 00 00
01.00 0x01CC-0x0118= B4 = 00 00 00 B4 --->reversed---> B4 00 00 00
Tips & Rules I used an "standard" .SFO for hombrew, apps, and disc games, but .SFO are used in many kinds of content as trophies, savegames, etc....SFO files are used as a preview of the folder, and to manage boot parameters of the content (like a program, a video, etc, etc...) The name of the variables included in the "variable name table" can vary depending of where the .sfo is used, but there are allways in alphabetically order (ATTRIBUTE, BOOTABLE, C..., D..., E..., and so on) The allowed variables for the PS3 firmware depends of where the .SFO is used (I.E.different entryes if the .SFO is from a savegame or from a blueray game) Some ones are mandatory for a CATTEGORY (I.E. BOOTABLE is mandatory if you want a program to boot) Others are optionall (like TITLE_02, TITLE03, TITLE04 for languages) Some others are ignored when you use them in other CATTEGORY not desired by sony (im not sure what is limiting this from the firmware), but as an example... you CANT add a SUB_TITLE text line for a homebrew For a non-complet-yet list of all variables look at this link ---> http://www.ps3devwiki.com/index.php?...Alphabetically ---------------------------------------------------------------------------------------------- When calculating the "data bytes used" is needed to add a +1 for every "UTF8" data type "data_block_size" has a fixed size in bytes that depends of the variable refered (size is in a relation of 2^x in decimal) i.e. LICENSE has a lenght og 128 bytes.... and BOOTABLE has a lenght of 4 bytes DONT CHANGE THIS LENGHTS... DONT ADD RANDOM PADDING If you need to know the padding (for some strange reason) you can by simply making a sustraction (block size in bytes - bytes used) For the block sizes refer to the previous list ---> http://www.ps3devwiki.com/index.php?...Alphabetically Int32 data type (in most cases) must be converted to binary, this is a way to understand the "flags" from a "human point of view" The most interesting flags are managed by ATTRIBUTE, there some unknown ones, and (especulation) some ones reserved for future implementations from sony For the (unfinished) list of ATTRIBUTE flags refer to this link ---> http://www.ps3devwiki.com/index.php?....SFO#ATTRIBUTE There are (at least) 3 different kinds of data type, remeber that UTF8 values needs a +1 when calculating, 04 00 = blank 04 02 = UTF8 04 04 = int32 Speciall variables with unknown content
Code:
Savegames ------------ 0x558 PARAMS (uint1024) 0x558 24 (8+4+4+4+4?) ????????? 0x570 (uint4) Console User Account nș 0x574 (uint16) Console ID 0x584 (uint4) Console User Account nș 0x588 (uint16) PSN User account ID 0x598 960 ? ????????? 0x958 PARAMS2 (uint12) 8+4 ? ![]() This values are the known part of the variable PARAMS from the screencapture
-----\o/----- I will keep editing this message with more tips, file examples, etc... enought by now ![]() Feel free to ask whatever doubt and i will reply with more examples, or make suggestions, by now is a bit mess The file used in the example picture is attached at the end of this message Last edited by sandungas; 12-09-2011 at 09:14 AM. Reason: update 2: addes "speciall variables with unknown content" |
|
|
|
|
|
Likes: (22) |
|
|
#2 | |
|
Apprentice
Join Date: Nov 2011
Posts: 4
Likes: 0
Liked 0 Times in 0 Posts
Mentioned: 0 Post(s)
Tagged: 0 Thread(s)
|
ps: unless you knw how to do ps3 could you teach me if so add me on skype zFakieHDz |
|
|
|
|
|
|
#3 |
|
Homebrew Developer
![]() Join Date: Oct 2011
Location: dev_hdd0/home/
Posts: 510
Likes: 244
Liked 507 Times in 214 Posts
Mentioned: 100 Post(s)
Tagged: 0 Thread(s)
|
Hmmm no, basically what a .SFO does are 2 things:
-Shows you a "preview" of the folder content This is visible in the XMB but the real content is not loaded yet -It can send "boot parameters" to the real content I.E. if you run a media player in MSdos with the modificators at the end of the command line this way: -audiomode5 -videomode8 -speciallfunction1 The interesting part are this "boot parameters" that are not documented, mostly the ATTRIBUTE
Last edited by sandungas; 11-29-2011 at 09:05 AM. Reason: changed "program" by "content" |
|
|
|
|
Likes: (1) |
|
|
#4 |
|
Member
![]() Join Date: Jan 2012
Posts: 98
Likes: 34
Liked 11 Times in 10 Posts
Mentioned: 3 Post(s)
Tagged: 0 Thread(s)
|
Thanks you for your really good work and explanations here, on wiki (I posted a little there on "your" page under Ada LoveLace) and crunch.
Sorry for my bad English and my lazy question. First about this Region_deny: I believe it s the news way for Sony for this sort of DRM but can t recollect yet what was the old way and make it more proper than to have a error message for the end user after install. I didn t check if Netflix or others examples are on the fw or from US PSN (here i m lazy) Can i have you point of view about it and the way the area this flag can cover. About others Param such as hybrid or commerc, i m not sur if Sony finally/ already implant it but i ll try to find somes examples (such as Torne, Twitter etc...) About the int32 attribut, i ll also have a look and try to find the oldest missings by cooking somes params (and you explain really well how to make them readable) One more thing are on my list but i ll reach somes limits (memory and ressources) are to provid official examples of thoses x0 and x4 (LV0000 NPSX00000 can be a good candidat) Thanks you for all your great work. Last edited by Lady Anne Blunt; 01-19-2012 at 02:50 PM. |
|
|
|
|
|
#5 |
|
Homebrew Developer
![]() Join Date: Jun 2010
Location: Outher Heaven
Posts: 351
Likes: 67
Liked 345 Times in 120 Posts
Mentioned: 112 Post(s)
Tagged: 0 Thread(s)
|
i think that this parameter say what nation can't use this app.
i can't use that app. |
|
|
|
|
|
#6 |
|
Member
![]() Join Date: Jan 2011
Location: Gliese 581g
Posts: 613
Likes: 531
Liked 346 Times in 176 Posts
Mentioned: 17 Post(s)
Tagged: 0 Thread(s)
|
just want thank you for your work....
__________________
![]() |
|
|
|
|
Likes: (1) |
|
|
#7 |
|
Member
![]() Join Date: Jan 2012
Posts: 98
Likes: 34
Liked 11 Times in 10 Posts
Mentioned: 3 Post(s)
Tagged: 0 Thread(s)
|
Thanks Deroad for your answer and your works around this subject and others on Wiki (also Euss about this wiki page)
My English may have done some confusing sentences. I know what this Region_deny is suppose to do or mean, but my question was more about when this is checked and which values and how Sony was doing it before 3.30 (as may be different by the form, EDDY function or the restriction of Torme or others usb devices) It was more to come by here and say thanks you to him for this wiki contribution. Last edited by Lady Anne Blunt; 01-19-2012 at 05:24 PM. |
|
|
|
|
|
#8 |
|
Senior Member
![]() Join Date: Sep 2010
Location: /dev/random
Posts: 1,687
Likes: 426
Liked 271 Times in 171 Posts
Mentioned: 14 Post(s)
Tagged: 0 Thread(s)
|
Nice I started to write some code for a command line tool to convert between SFO and SFX; similar to that of plutil, 2 days ago.
I was also puzzled by the 12 bytes in the end there, first I thought it to be some sort of sum, but I did not manage to make any sense of it... so far, i e
__________________
US 4USB ports OFW 3.15 PS Ubuntu
EU 4USB ports CFW 4.21.1 REX There is only one OS; AmigaOS, the rest are just [l]imitations. |
|
|
|
|
|
#9 | |
|
Homebrew Developer
![]() Join Date: Jun 2010
Location: Outher Heaven
Posts: 351
Likes: 67
Liked 345 Times in 120 Posts
Mentioned: 112 Post(s)
Tagged: 0 Thread(s)
|
probably it will boot anyway. |
|
|
|
|
|
|
#10 |
|
Senior Member
![]() Join Date: Sep 2010
Location: /dev/random
Posts: 1,687
Likes: 426
Liked 271 Times in 171 Posts
Mentioned: 14 Post(s)
Tagged: 0 Thread(s)
|
I would like to make this util in cpp here is how I read this file so far.
Code:
struct ourSFO {
u32 *fileType; /* File type */
u32 *fileVersion; /* File version */
u32 *indexTable; /* Index table */
u32 *dataTable; /* Data table */
u32 *varsIndexed; /* Vars indexed */
char[] *blob;
} FILE;
Code:
struct ourSFO {
u32 *fileType; /* File type */
u32 *fileVersion; /* File version */
u32 *ptrIndexTable; /* Ptr to Index */
u32 *ptrDataTable; /* Ptr to Data */
u32 *varsIndexed; /* Vars indexed */
u16 *indexNameOffset;
u16 *datatype;
u32 *dataSize;
u32 *dataBlock;
u32 *dataOffset;
u8 index[(ptrIndexTable-fileType)]; /* Index */
u8 data[(ptrIndexTable-fileType)]; /* Data */
} FILE;
__________________
US 4USB ports OFW 3.15 PS Ubuntu
EU 4USB ports CFW 4.21.1 REX There is only one OS; AmigaOS, the rest are just [l]imitations. Last edited by advocatusdiaboli; 01-20-2012 at 06:16 AM. |
|
|
|
|
Likes: (1) |
![]() |
| Bookmarks |
| Thread Tools | |
|
|