Editing PARAM.PFD

Jump to navigation Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.

Latest revision Your text
Line 80: Line 80:
     } pfd_entry_table_t;
     } pfd_entry_table_t;


 
    typedef struct
    typedef struct
     {
     {
         pfd_header_t header;
         pfd_header_t header;
Line 95: Line 94:


*Useful game saves used in this page as examples
*Useful game saves used in this page as examples
**http://www.gamefaqs.com/ps3/941950-mirrors-edge/saves ([https://web.archive.org/web/20240105221026/https://gamefaqs.gamespot.com/ps3/941950-mirrors-edge/saves Archive Mirror])
**http://www.gamefaqs.com/ps3/941950-mirrors-edge/saves (the first one region North America). Mirror: http://www.multiupload.nl/SWJ4Y4H7ER
**http://www.gamefaqs.com/ps3/933123-heavy-rain/saves ([https://web.archive.org/web/20210521155536/https://gamefaqs.gamespot.com/ps3/933123-heavy-rain/saves Archive Mirror])
**http://www.gamefaqs.com/ps3/933123-heavy-rain/saves


The structure of the PARAM.PFD used in Mirror's edge game save can be considered "rare", this wiki page uses this file for explaining the structure because is perfect to understand how it works, the structure contains all the "problems" not present in "standard" files that can be considered unknown... there are other game saves that can be used (MotoGP10, Heavy rain)... but the list of protected files in heavy rain contains more than 100 files (use heavy rain if you are coding an app as a "stress test")
The structure of the PARAM.PFD used in Mirror's edge game save can be considered "rare", this wiki page uses this file for explaining the structure because is perfect to understand how it works, the structure contains all the "problems" not present in "standard" files that can be considered unknown... there are other game saves that can be used (MotoGP10, Heavy rain)... but the list of protected files in heavy rain contains more than 100 files (use heavy rain if you are coding an app as a "stress test")
Line 614: Line 613:


===How to blank the tables===
===How to blank the tables===
In the header of the file there are 3 hashes that belongs to the 3 tables (X table, protected files table, and Y table). The first step needed to modify the file is to be able to generate this hashes for our "new" modified tables... but in fact, these hashes are the "only" thing needed to pwn the whole file security, because we can "clean-up" all the tables (in other words, we don't need to understand how this tables are built, how the protected files signatures are generated, or what this ID's means, because we can erase all this data):
In the header of the file there are 3 hashes that belongs to the 3 tables (X table, protected files table, and Y table). The first step needed to modify the file is to be able to generate this hashes for our "new" modifyed tables... but in fact, this hashes are the "only" thing needed to pwn the whole file security, because we can "clean-up" all the tables (in other words, we dont need to understand how this tables are built, how the protected files signatures are generated, or what this ID's means, because we can erase all this data):


*1.- First is needed to look at "X table" to find an entry marked as 0x72 (not used), then go to the "Y table" and using this same position make a copy of the entry (this will be needed later in step 5 when cleaning-up "Y table" by pasting this value repeatedly)
*1.- First is needed to look at "X table" to find an entry marked as 0x72 (not used), then go to the "Y table" and using this same position make a copy of the entry (this will be needed later in step 5 when cleaning-up "Y table" by pasting this value repeatedly)
*2.- Fill with zeroes the value "Protected files table used entries" (from 0x70 to 0x78)
*2.- Fill with zeroes the value "Protected files table used entries" (from 0x70 to 0x78)
*3.- Fill "X table" with "not-used" entries (from 0x78 to 0x240... paste 57 times the entry 0000000000000072)
*3.- Fill "X table" with "not-used" entryes (from 0x78 to 0x240... paste 57 times the entry 0000000000000072)
*4.- Fill with zeroes all the "protected files table" (from 0x240 to 0x7B60)
*4.- Fill with zeroes all the "protected files table" (from 0x240 to 0x7B60)
*5.- Fill "Y table" with "not-used" entries (from 0x7B60 to 0x7FD4... paste 57 times the "not used" value for this table copyed previously)
*5.- Fill "Y table" with "not-used" entries (from 0x7B60 to 0x7FD4... paste 57 times the "not used" value for this table copyed previously)


After cleaning-up the tables and regenerating its hashes, the behaviour of the PS3 when trying to load this "BLANKED.PFD" file can give some possible results:
After cleaning-up the tables and regenerating his hashes, the behaviour of the PS3 when trying to load this "BLANKED.PFD" file can give some possible results:
*File is valid, is loaded, but there is "something" that states this file originally had X "protected files" listed.... but now there is none = epic fail
*File is valid, is loaded, but there is "something" that states this file originally had X "protected files" listed.... but now there is none = epic fail
*File is valid, is loaded, and PARAM.SFO is added to the list of protected files (this is something that seems to happen "by default"), consequently the PARAM.PFD is updated, both files are valid = partial win
*File is valid, is loaded, and PARAM.SFO is added to the list of protected files (this is something that seems to happen "by default"), consequently the PARAM.PFD is updated, both files are valid = partial win
*File is valid, is loaded, no protected files are added to the list = epic win
*File is valid, is loaded, no protected files are added to the list = epic win


It depends of the function that creates/updates the .PFD which files needs to be added to the list of "protected files" (this is done the first time when the file is created), but probably games can add more files for their game saves
It depends of the function that creates/updates the .PFD wich files needs to be added to the list of "protected files" (this is done the first time when the file is created), but probably games can add more files for his game saves


The theory is simple... is a valid file with empty tables, it's something not tested yet, but if somebody finds a way to generate the header hashes... this theory is the next test that is worth a try
The theory is simple... is a valid file with empty tables, is something not tested yet, but if somebody finds a way to generate the header hashes... this theory is the next test that worths a try


===The "virtual index"===
===The "virtual index"===
Mirror's edge has a total of 33 "protected files" (listed in the protected files table)... this number matches with the 33 "indexed" numbers that are spreading between "X table" and "protected files table" itself... if we place all the entries from all tables together we can reorder all by using their ID number in a "virtual index"
Mirror's edge has a total of 33 "protected files" (listed in the protected files table)... this number matches with the 33 "indexed" numbers that are spreading between "X table" and "protected files table" itself... if we place all the entries from all tables together we can reorder all by using his ID number in a "virtual index"


{| class="wikitable"
{| class="wikitable"
Line 713: Line 712:


===More brainstorming===
===More brainstorming===
*The maximum number of entries in the '''Protected files table''' (114) is exactly the double than the maximum number of entries in '''X table''' (57) & '''Y table''' (57). Or from other point of view 114 = 57 + 57
*The maximun number of entries in the '''Protected files table''' (114) is exactly the double than the maximun number of entries in '''X table''' (57) & '''Y table''' (57). Or from other point of view 114 = 57 + 57
**Seems obvious that there is an "index number" assigned to each "protected file", but their positions are "scrambled"
**Seems obvious that there is an "index number" assigned to each "protected file", but his positions are "scrambled"




*The order of the files in the "protected files table" is based on timestamps (not alphabetically, not by size). Or in other words... tt's related with how the PARAM.PFD was generated for first time
*The order of the files in the "protected files table" is based in his timestamps (not alphabetically, not by size). Or in other words... is related with how the PARAM.PFD was generated for first time
**The original order when the file was created for first time (based on these timestamps), when the files in the list are updated by the ps3 (its timestamps change) keep their original position. When new files are added to the "protected files list table"... they are added to the end of the list, based on these timestamps.
**Is the original order when the file was created for first time (based in his timestamps), when the files in the list are updated by the ps3 (his timestamp changes) they keeps his original position. When new files are added to the "protected files list table"... are added to the end of the list, based in his timestamps.
**When several "protected files" have the same timestamp (something very probable because can be generated by the game very fast)... the order is alphabetical
**When several "protected files" has the same timestamp (something very probable because can be generated by the game very fast)... the order is alphabeticall
**So when ordering them, the timestamp is preferent... and when a timestamp matches it uses their name (alphabetically)
**So when ordering them, the timestamp is preferent... and when timestamp matches is used his name (alphabetically)




*Indexed files in the '''X table''' has a different number for each one, never repeats, but there is not direct relationship between the number of entries in '''X table''' & '''Y table''' (both are fixed to 57) and the number of files listed in the '''Protected files table''' (114)... the most logical explain if that this 114 "protected files" can be linked to both tables (57 each)... but in fact the only table that stores crypto is the '''Y table''' (limited to 57)... so what trick they used ? hmmmm
*Indexed files in the '''X table''' has a different number for each one, never repeats, but there is not direct relationship between the number of entries in '''X table''' & '''Y table''' (both are fixed to 57) and the numer of files listed in the '''Protected files table''' (114)... the most logicall explain if that this 114 "protected files" can be linked to both tables (57 each)... but in fact the only table that stores crypto is the '''Y table''' (limited to 57)... so what trick they used ? hmmmm




*What are this index in the '''X table''' and in the '''Protected files table''' itself?, its positions seems to be random (but the number of indexed files matches with the number of "protected files"), seems like an old school "lucas arts games" anticheat card where you pick 2 values and by mixing them you get the unlock code :D
*What are this index in the '''X table''' and in the '''Protected files table''' itself?, his positions seems to be random (but the number of indexed files matches with the number of "protected files"), seems like an old school "lucas arts games" anticheat card where you pick 2 values and by mixing them you get the unlock code :D
**Seems to be "jumps" from one table to the other. The files are read in order by the ps3 by "jumping" using its "index nº" to locate the next one... "Index nº0" seems to be located always at position 8 in the "X-Table" (offset 0xB8). In most complex PARAM.SFO (e.g: heavy rain, mirror's edge or motogp10/11) the value at this position is replaced by another "index nº" (by now seems random) that is pointing to the "protected files table" index area of each entry (where index nº0 is located). How this "jumps" works is partially unknown and by now is only notable in the first jump
**Seems to be "jumps" from one table to the other. The files are readed in order by the ps3 by "jumping" using his "index nº" to locate the next one... "Index nº0" seems to be located always at position 8 in the "X-Table" (offset 0xB8). In most complex PARAM.SFO (e.g: heavy rain, mirror's edge or motogp10/11) the value at this position is replaced by another "index nº" (by now seems random) that is pointing to the "protected files table" index area of each entry (where index nº0 is located). How this "jumps" works is partially unknown and by now is only notable in the first jump




Line 757: Line 756:
[https://github.com/BuXXe/PARAM.PFD-PS3-Demons-Souls-Savegame-Tool Github for a Python 2.7 PARAM.PFD (decryption/encryption/signing) for Demon's Souls]
[https://github.com/BuXXe/PARAM.PFD-PS3-Demons-Souls-Savegame-Tool Github for a Python 2.7 PARAM.PFD (decryption/encryption/signing) for Demon's Souls]


{{File Formats}}<noinclude>
{{File Formats}}<noinclude>[[Category:Main]]</noinclude>
[[Category:Main]]
</noinclude>
Please note that all contributions to PS3 Developer wiki are considered to be released under the GNU Free Documentation License 1.2 (see PS3 Developer wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To protect the wiki against automated edit spam, we kindly ask you to solve the following hCaptcha:

Cancel Editing help (opens in new window)