Page 6 of 10 FirstFirst ... 45678 ... LastLast
Results 51 to 60 of 91



  1. #51
    Forum Moderator PS3 News's Avatar
    Join Date
    Apr 2005
    Posts
    26,896

    PS3 Save Game Tools Pack Updated by Flat_z, PFDTool v0.2.0 Fix

    Following up on his initial release, this weekend PlayStation 3 developer Flat_z has updated his PS3 Save Game Tools hacking pack alongside a fix for PFDTool v0.2.0 followed by v0.2.1 and v0.2.2 with details below.

    Download: PS3 Save Game Tools Pack v0.2.0 / PFDTool v0.2.0 Fix / PFDTool v0.2.2 (Removed) / PFDTool v0.2.2 Fix / PFDTool v0.2.2 (Final) / http://www.dll-files.com/dllindex/dll-files.shtml?msvcr100 (Required)

    From the included ReadMe file: Guys, here is an updated version of pfdtool.

    Please test it carefully because I have no time at the moment to test it by myself.

    Changelog:
    • Support of PARAM.PFD for trophies (without keys, of course)
    • Support of PARAM.PFD v4 which used in a newer SDK
    • Fixed a bug with verify operation on signature hashes
    • Now you can use a list of product codes delimeted by '/' (slash), for example: [BLUS31142/BLES01403], they should use the same disc hash key and secure file IDs
    • Show an information about .PFD type and version

    The format for 'global.conf' is different. Please add these changes to your files:

    1. Add a new parameter called 'user_id' which set the user identifier (the same number as used in your home folder: /dev_hdd0/home/[user_id]/)
    2. Add a new parameter called 'keygen_key'. Open 'Talk:Keys' page on the PS3DevWiki and search for string 'KeygenV4'
    3. Rename the parameter 'param_sfo_key' to 'savegame_param_sfo_key' (see below)
    4. There a bunch of new keys for trophies: 'trophy_param_sfo_key', 'tropsys_dat_key', 'tropusr_dat_key', 'troptrns_dat_key', 'tropconf_sfm_key' and they are not public so left them as XX.
    Code:
    ; Global settings
    
    [global]
    authentication_id=1010000001000003
    console_id=
    user_id=00000001
    syscon_manager_key=
    keygen_key=
    savegame_param_sfo_key=
    trophy_param_sfo_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    tropsys_dat_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    tropusr_dat_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    troptrns_dat_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    tropconf_sfm_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    fallback_disc_hash_key=
    Also I noticed that some of you use a kernel swapping feature in the REX firmware. Don't forget to use your current (!) console ID. For example, if you made a save game on a DEX then you need to specify a DEX console ID.

    Disc hash keys are sent to the PS3 by the Blu Ray Drive itself (well, not the actual disc hash key but some data from the disc which will be encrypted after that and used as a disc hash key).

    PFDTool 0.2.1 Changelog:
    • Fixed issues with the file size.

    PFDTool 0.2.2 Changelog:
    • Now encrypt and decrypt operations update hashes automatically (be sure to use all keys!).
    • Fixed another issue with the file size of modified files.
    • Removed a verbose flag because it is not used at the moment.

    PS3 Save Game Tools Pack Updated by Flat_z, PFDTool v0.2.0 Fix

    More PlayStation 3 News...
    Attached Images<br><br> Attached Images

    Attached Files Attached Files

  2. #52
    Contributor eric994's Avatar
    Join Date
    Sep 2012
    Posts
    21
    this is a favour i want to ask for anyone who understands this stuff.

    Could it be possible to fix the "corrupt save data" dilemma in the call of duty: black ops II(BLES01717) with will highly appreciated by me and many others with the same copies of this amazing game.

  3. #53
    Registered User GMOTE's Avatar
    Join Date
    Nov 2012
    Posts
    6
    Nice news.

  4. #54
    Forum Moderator PS3 News's Avatar
    Join Date
    Apr 2005
    Posts
    26,896

    PS3 Save Game Tools Pack Updated by Flat_z, PFDTool v0.2.3 Out

    Following up on his previous update, today PlayStation 3 developer Flat_z has updated the PS3 Save Game Tools Pack to include SFOPatcher v0.2.0 and PFDTool version 0.2.3 alongside an update to the BruteforceSaveData GUI by aldostools below.

    Download: PS3 Save Game Tools Pack Update (121412) / PFDTool and SFOPatcher Source Code / http://aldostools.org/temp/BruteforceSaveData.rar

    From Flat_z: Some people asked me about the source code of pfd & sfo tools.. here they are (linked above).

    Guys, here is an update of my tools. It contains an update to sfopatcher (see the changelog below) and a small update to pfdtool. Previously you should make a save game for your game on your console and then use PARAM.SFO from it as a template to PARAM.SFO from a foreign save game to build a new PARAM.SFO which will contain the data specific to your console. A newer version of sfopatcher will use a foreign save data directory and params only if you specify these options.

    From aldostools: A new version of the frontend is available with the updated tools from flatz and new settings to take advantage of these features.

    Changes: new "Rebuild" option, new "Restore" option, updated the database with secure_file_id for more than 750 games (over 3140 title ids). Added a new "date" column. Special thanks to flatz, Alex at CMP, acab, skillerCMP, gingerbread and many others

    Changelog:

    pfdtool 0.2.3
    • Added an option to specify the relative offset to advance each time while bruteforcing a secure file ID.

    Below is a guide from zorrolaro on how to use PFDTool without PS3 CFW using Borderlands 2 as an example:

    Required Tools:

    Guide:
    • Create a folder near your root drive for pfdtool (i.e. c:/pfdtool/), then extract all files into that folder from the linked archive.
    • Download and install wireshark and winPcap (included with the wireshark installer)
    • Download and install the .net runtimes
    • Download and install PS3 ProxyServer
    • Open a command prompt (start menu -> all programs -> accessories -> command prompt) and enter command "ipconfig". Write down the IPv4 address (should look like 192.168.0.10 or something similar)
    • Open PS3 ProxyServer and copy the IPv4 address you wrote down into the IP Address field and check of PS3 mode, leave the other options alone. Hit the big start button. Keep you IPv4 number handy, you'll need it again. Leave this program running.
    • Open Wireshark. On the left side there is an option to start capture. Left click with your mouse to select the appropriate network adapter listed below the start command. If you are not sure about which adapter to use, select them all using ctrl + left mouse click. Hit the start button once you've highlighted the appropriate adapters. Leave this program running.
    • Boot up your PS3 and navigate to Settings -> Network Settings -> Internet Connection Settings. on the first page select Custom, on the second select whether you are connected wirelessly or wired. Skip all other options by hitting right on your controller until you get to the Proxy Server page, then select use for that option. input the IPv4 address you wrote down earlier into the top field.

      Make sure that the port number on this page matches the port number on PS3 ProxyServer (should both say 8080). Skip to the last page on the configuration and hit x. Test connection when prompted by hitting x again. As long as the top 3 fields say succeeded you can carry on to the next step. if not, review your settings in this step and steps 5 and 6 and retry.
    • Sign into the playstation network and login to the psn store.
    • Go back to your pc and check Wireshark. There should be a whole bunch of information displayed on the screen, don't worry you don't need to know what it means. Press [ctrl]+ e to stop capturing, then press [ctrl]+f to bring up your search dialogue. Under "find" check of "string" and under "Search In" check off "Packet bytes". Enter 0000000100 as your search criteria and hit enter. If the necessary packet was found, in the bottom frame it should show the number highlighted on the right side (plaintext view) to ensure you have the right packet, right before the highlighted text it should say "devideID":" and then the numbers you searched for.

      Take all the numbers and letters starting with your highlighted numbers and copy everything down until you find the next quotation mark in the plaintext. You should have a total of 32 digits written down. Should look something like 000000010084 followed by a bunch of letters and numbers. This is your console id.
    • Go to the folder you installed pfdtool in. Open global.conf in notepad. Eidt the line where it says console_id=by adding the console id you just captured after the =. Also change the other fields that are bolded below to match
      Code:
      ; Global settings
      
      [global]
      authentication_id=1010000001000003
      console_id=00000001008400xxx01dxxxx239xx6x6
      user_id=00000001
      syscon_manager_key=D413B89663E1FE9F75143D3BB4565274
      keygen_key=6B1ACEA246B745FD8F93763B920594CD53483B82
      savegame_param_sfo_key=0C08000E090504040D010F000406020209060D03
      trophy_param_sfo_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      tropsys_dat_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      tropusr_dat_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      troptrns_dat_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      tropconf_sfm_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      fallback_disc_hash_key=D1C1E10B9C547E689B805DCD9710CE8D
    • Save file and exit (make sure you save as .conf not .txt)
    • Open the games.conf file in the same folder. Edit it as follows for NA retail disc version only. You'll have a different game id (the BLUS30982) and secure_file_id. You'll need to ask for someone on the forums to get those for you if you are using a different region, version or entirely differnt game. You can add additional games follwing the same layout by adding more lines. The disc_hash_key is commented out, so you will get a notifaction everytime you use pfdtool, but it still works fine.
      Code:
      ; "Borderlands 2"
              [BLUS30982]
              ;disc_hash_key=
              secure_file_id:*=02010508040102010508030A0F070C0D
    • Save and close the file once you are done adding games. Again make sure you save as .conf, not .txt.
    • Make sure you have a copy of your save game on your pc. I like to copy them right into the same folder as pfdtool to make for shorter commands.
    • You are now ready to actually use pfdtool. Navigate your command prompt to the folder you installed it (command to use is simply the path of the folder, ie "c:/pfdtool"). To decrypt we use the following command:
      Code:
      pfdtool -g BLUS30982 -d "C:/pfdtool/BLUS30982-SAVE-SAVE0001" SAVE0001.SAV
    • Where the part in quotations will be changed to reflect your actual drive location and the name of the file will be changed to your actual file name. The file name and path are case sensitive, make sure you double check you have the right case.
    • You now have a decrypted save file. Use your hex editor of choice or in the case of Borderlands 2 you can use the latest version of Gibbed's Borderlands 2 Save Editor. Once you are done editing, sae your game again and onto the last step.
    • All that's left at this point is to encrypt the file again. See below, same notes as when decrypting about file path and name.
      Code:
      pfdtool -g BLUS30982 -e "C:/pfdtool/BLUS30982-SAVE-SAVE0001" SAVE0001.SAV
    • You can now transfer your save game back to your PS3.

    A couple of quick notes: I have tried to make this as noob friendly as possible, but you still need some basic knowledge to follow this guide. Also, atm I really have no interest in modding any other save games so I do not have the info for other games to place in your games.conf file, though if anyone wants to post them I will be happy to add them to the guide. I did not write nor do I support any of the software mentioned in this guide.

    Unfortunately we can't extract it from .PFD because IDPS is not stored there. They used it as a HMAC key to hash the content of PARAM.SFO.

    I already said many times that some hashes are not checked. That's why Xploder works fine without your console ID. But my goal was the correct generation of the PFD (because S0ny can add new checks in the future) and I had managed to use all keys but you can omit some of them (based on your console id or disc hash key, for example).

    From cheetahh: I can confirm that flat_z tool can be used to decrypt TROPTRANS.DAT file and if you know how to modify all the files correctly (there are different checksums and hashes in the files) you can sync those unlocked trophies to PSN as well.

    From Sunny992: All information should be free, don't conceal it if it's already leaked, which it was.
    Code:
    troptrns_dat_key=91EE81555ACC1C4FB5AAE5462CFE1C62A4AF36A5
    It was leaked on NGU.

    Finally, from <GEEK> comes a VB.NET/C# PARAM.PFD Code Snippet below, as follows:

    Figured I would share this as it is a starting point to anyone who wants to work with PARAM.PFD files within VB.NET/C#. Use it, change it, do what you want with it. I used a code converter to avoid rewriting everything between the 2 languages, and then went through and fixed what broke during the conversion.

    The code could be optimized... Most of the classes/functions could easily be combined down to just a few classes/functions, and global variables should be avoided when possible other than for this demonstration. The reason it is the way it is now is so that it is easier to see what is going on. If anyone actually uses this, and wants an optimized set of functions or classes just ask.

    With that said, all that is needed is a decryption/encryption (AES 128 CTR Mode) function/class for save files and you can be on your way to making your own cheat editor without the need of bundling in flatz pfdtools.

    VB.NET Code
    Code:
    Add to a module:
        '**************************************************************************************************************************'
        '*                                             GLOBAL KEYS                                                                *'
        '**************************************************************************************************************************'
        Public SYSCON_MANAGER_KEY As Byte() = New Byte() {&HD4, &H13, &HB8, &H96, &H63, &HE1, &HFE, &H9F, &H75, &H14, &H3D, &H3B, &HB4, &H56, &H52, &H74}
    
        '**************************************************************************************************************************'
        '*                                      GLOBAL HEADER TABLE VARIABLES                                                     *'
        '**************************************************************************************************************************'
        Public Structure PFD_HEADER
            Const OFFSET As Long = &H0
            Const SIZE As Integer = 96
            Const MAGIC_OFFSET As Long = &H0
            Const MAGIC_SIZE As Integer = 8
            Const VERSION_OFFSET As Long = &H8
            Const VERSION_SIZE As Integer = 8
            Const IV_OFFSET As Long = &H10
            Const IV_SIZE As Integer = 16
            Const SIGNATURE_OFFSET As Long = &H20
            Const SIGNATURE_SIZE As Integer = 64
            Const TOP_HASH_OFFSET As Long = &H0
            Const TOP_HASH_SIZE As Integer = 20
            Const BOTTOM_HASH_OFFSET As Long = &H14
            Const BOTTOM_HASH_SIZE As Integer = 20
        End Structure
        Public PFD_HEADER_TABLE As Byte() = New Byte(PFD_HEADER.SIGNATURE_SIZE) {}
        Public PFD_HEADER_MAGIC As Byte() = New Byte(PFD_HEADER.MAGIC_SIZE) {}
        Public PFD_HEADER_VERSION As Byte() = New Byte(PFD_HEADER.VERSION_SIZE) {}
        Public PFD_HEADER_TABLE_IV As Byte() = New Byte(PFD_HEADER.IV_SIZE) {}
        Public PFD_HEADER_SIGNATURE As Byte() = New Byte(PFD_HEADER.SIGNATURE_SIZE) {}
        Public PFD_HEADER_DECRYPTED As Byte() = New Byte(PFD_HEADER.SIGNATURE_SIZE) {}
        Public PFD_HEADER_DECRYPTED_TOP_HASH As Byte() = New Byte(PFD_HEADER.TOP_HASH_SIZE) {}
        Public PFD_HEADER_DECRYPTED_BOTTOM_HASH As Byte() = New Byte(PFD_HEADER.BOTTOM_HASH_SIZE) {}
        '**************************************************************************************************************************'
        '*                                      GLOBAL HASH TABLE VARIABLES                                                       *'
        '**************************************************************************************************************************'
        Public Structure HASH_TABLE
            Const MAX_ENTRIES As Integer = 57
            Const HEADER_OFFSET As Long = &H60
            Const HEADER_SIZE As Integer = 24
            Const OFFSET As Long = &H78
            Const SIZE As Integer = 456
            Const TABLE_ENTRY_SIZE As Integer = 8
        End Structure
        Public PFD_HASH_TABLE_HEADER As Byte() = New Byte(HASH_TABLE.HEADER_SIZE) {}
        Public PFD_HASH_TABLE As Byte() = New Byte(HASH_TABLE.SIZE) {}
        Public PFD_HASH_TABLE_ALL_ENTRIES As Byte() = New Byte(HASH_TABLE.SIZE / HASH_TABLE.TABLE_ENTRY_SIZE) {}
        '**************************************************************************************************************************'
        '*                                  GLOBAL PROTECTED FILES TABLE VARIABLES                                                *'
        '**************************************************************************************************************************'
        Public Structure PF_TABLE
            Const OFFSET As Long = &H240
            Const SIZE As Integer = 31008
            Const ENTRY_SIZE As Integer = 272
            Const ENTRY_INDEX_SIZE As Integer = 8
            Const ENTRY_NAME_SKIP_BYTES As Integer = 8
            Const ENTRY_NAME_SIZE As Integer = 65
            Const ENTRY_GARBAGE_SKIP_BYTES As Integer = 73
            Const ENTRY_GARBAGE_SIZE As Integer = 7
            Const ENTRY_DATA_SKIP_BYTES As Integer = 80
            Const ENTRY_DATA_SIZE As Integer = 192
            Const ENTRY_KEY_SKIP_BYTES As Integer = 80
            Const ENTRY_KEY_SIZE As Integer = 64
            Const ENTRY_HASHES_SKIP_BYTES As Integer = 144
            Const ENTRY_HASHES_SIZE As Integer = 80
            Const ENTRY_HASH1_SKIP_BYTES As Integer = 144
            Const ENTRY_HASH_SIZE As Integer = 20
            Const ENTRY_HASH2_SKIP_BYTES As Integer = 164
            Const ENTRY_HASH3_SKIP_BYTES As Integer = 184
            Const ENTRY_HASH4_SKIP_BYTES As Integer = 204
            Const ENTRY_PADDING_SKIP_BYTES As Integer = 224
            Const ENTRY_PADDING_SIZE As Integer = 40
            Const ENTRY_FILESIZE_SKIP_BYTES As Integer = 264
            Const ENTRY_FILESIZE_SIZE As Integer = 8
        End Structure
        Public PFD_PROTECTED_FILES_TABLE As Byte() = New Byte(PF_Table.SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY As Byte() = New Byte(PF_Table.ENTRY_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ALL_ENTRIES As Byte() = New Byte(PF_Table.SIZE / PF_Table.ENTRY_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_INDEX As Byte() = New Byte(PF_Table.ENTRY_INDEX_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_NAME As Byte() = New Byte(PF_Table.ENTRY_NAME_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_GARBAGE As Byte() = New Byte(PF_Table.ENTRY_GARBAGE_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_DATA As Byte() = New Byte(PF_Table.ENTRY_DATA_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_KEY As Byte() = New Byte(PF_Table.ENTRY_KEY_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_HASHES As Byte() = New Byte(PF_Table.ENTRY_HASHES_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_HASH1 As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_HASH2 As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_HASH3 As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_HASH4 As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_PADDING As Byte() = New Byte(PF_Table.ENTRY_PADDING_SIZE) {}
        Public PFD_PROTECTED_FILES_TABLE_ENTRY_FILESIZE As Byte() = New Byte(PF_Table.ENTRY_FILESIZE_SIZE) {}
        '**************************************************************************************************************************'
        '*                                          GLOBAL Y TABLE VARIABLES                                                      *'
        '**************************************************************************************************************************'
        Public Structure Y_TABLE
            Const MAX_ENTRIES As Integer = 57
            Const OFFSET As Long = &H7B60
            Const SIZE As Integer = 1140
            Const TABLE_ENTRY_SIZE As Integer = 20
        End Structure
        Public PFD_Y_TABLE As Byte() = New Byte(Y_Table.SIZE) {}
        Public PFD_Y_ALL_ENTRIES As Byte() = New Byte(Y_Table.SIZE / Y_Table.TABLE_ENTRY_SIZE) {}
        '**************************************************************************************************************************'
        '*                                          GLOBAL PADDING VARIABLES                                                      *'
        '**************************************************************************************************************************'
        Public Structure BOTTOM_PADDING
            Const OFFSET As Long = &H7FD4
            Const SIZE As Integer = 44
        End Structure
        Public PFD_BOTTOM_PADDING As Byte() = New Byte(BOTTOM_PADDING.SIZE) {}
    
    Add to a module:
        '**************************************************************************************************************************'
        '*                                  READ THE TOP HASH FROM DECRYPTED HEADER IN AN ARRAY                                   *'
        '**************************************************************************************************************************'
        Public Function Read_Decrypted_Header_Top_Hash(ByVal decrypted_header_array As Byte(), ByVal offset As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PFD_HEADER.TOP_HASH_SIZE - 1) {}
    
            Buffer.BlockCopy(decrypted_header_array, offset, output_array, 0, PFD_HEADER.TOP_HASH_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                                READ THE BOTTOM HASH FROM DECRYPTED HEADER IN AN ARRAY                                  *'
        '**************************************************************************************************************************'
        Public Function Read_Decrypted_Header_Bottom_Hash(ByVal decrypted_header_array As Byte(), ByVal offset As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PFD_HEADER.BOTTOM_HASH_SIZE - 1) {}
    
            Buffer.BlockCopy(decrypted_header_array, offset, output_array, 0, PFD_HEADER.BOTTOM_HASH_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                                  READ ALL ENTRIES FROM HASH TABLE TO A LIST OF ARRAYS                                  *'
        '**************************************************************************************************************************'
        Public Function Build_Hash_Table_Entries_Array(ByVal hash_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To Hash_Table.SIZE - 1 Step 8
                Dim output_array As Byte() = New Byte(Hash_Table.TABLE_ENTRY_SIZE - 1) {}
                Buffer.BlockCopy(hash_table_array, i, output_array, 0, 8)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                                    READ A SINGLE ENTRY FROM HASH TABLE IN AN ARRAY                                     *'
        '**************************************************************************************************************************'
        Public Function Read_Hash_Table_Entry(ByVal hash_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(Hash_Table.TABLE_ENTRY_SIZE - 1) {}
    
            Buffer.BlockCopy(hash_table_array, entry_index * 8, output_array, 0, 8)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                              READ ALL ENTRIES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                           *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i, output_array, 0, 272)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                              READ A SINGLE ENTRY FROM PROTECTED FILES TABLE INTO AN ARRAY                              *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Entry(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272, output_array, 0, 272)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                           READ ALL INDEXES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                              *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Index_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_INDEX_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i, output_array, 0, PF_Table.ENTRY_INDEX_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                          READ A SINGLE ENTRIES INDEX FROM PROTECTED FILES TABLE INTO AN ARRAY                          *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Index(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_INDEX_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272, output_array, 0, PF_Table.ENTRY_INDEX_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                           READ ALL FILE NAMES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                           *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Name_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_NAME_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i + PF_Table.ENTRY_NAME_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_NAME_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                         READ A SINGLE ENTRIES FILE NAME FROM PROTECTED FILES TABLE INTO AN ARRAY                       *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Name(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_NAME_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + PF_Table.ENTRY_NAME_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_NAME_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                           READ ALL GARBAGE BYTES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                        *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Garbage_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_GARBAGE_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i + PF_Table.ENTRY_GARBAGE_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_GARBAGE_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                        READ A SINGLE ENTRIES GARBAGE BYTES FROM PROTECTED FILES TABLE INTO AN ARRAY                    *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Garbage(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_GARBAGE_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + PF_Table.ENTRY_GARBAGE_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_GARBAGE_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                              READ ALL DATA FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                              *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Data_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_DATA_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i + PF_Table.ENTRY_DATA_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_DATA_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                            READ A SINGLE ENTRIES DATA FROM PROTECTED FILES TABLE INTO AN ARRAY                         *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Data(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_DATA_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272, output_array, 0, PF_Table.ENTRY_DATA_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                            READ ALL ENTRY KEYS FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                          *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Key_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_KEY_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i + PF_Table.ENTRY_KEY_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_KEY_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                           READ A SINGLE ENTRIES KEY FROM PROTECTED FILES TABLE INTO AN ARRAY                           *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Key(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_KEY_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + PF_Table.ENTRY_KEY_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_KEY_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                           READ ALL FILE HASHES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                          *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Hashes_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_HASHES_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i + PF_Table.ENTRY_HASHES_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_HASHES_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                           READ A SINGLE ENTRIES HASHES FROM PROTECTED FILES TABLE INTO AN ARRAY                        *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Hashes(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_HASHES_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + PF_Table.ENTRY_HASHES_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_HASHES_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                        READ ALL THE FIRST HASHES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                        *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Hashes_1_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i + PF_Table.ENTRY_HASH1_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_HASH_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                        READ A SINGLE ENTRIES FIRST HASH FROM PROTECTED FILES TABLE INTO AN ARRAY                       *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Hashes_1(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + PF_Table.ENTRY_HASH1_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_HASH_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                        READ ALL THE SECOND HASHES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                       *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Hashes_2_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i + PF_Table.ENTRY_HASH2_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_HASH_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                        READ A SINGLE ENTRIES SECOND HASH FROM PROTECTED FILES TABLE INTO AN ARRAY                      *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Hashes_2(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + PF_Table.ENTRY_HASH2_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_HASH_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                        READ ALL THE THIRD HASHES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                        *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Hashes_3_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i + PF_Table.ENTRY_HASH3_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_HASH_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                        READ A SINGLE ENTRIES THIRD HASH FROM PROTECTED FILES TABLE INTO AN ARRAY                       *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Hashes_3(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + PF_Table.ENTRY_HASH3_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_HASH_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                        READ ALL THE FOURTH HASHES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                       *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Hashes_4_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i + PF_Table.ENTRY_HASH4_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_HASH_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                        READ A SINGLE ENTRIES FOURTH HASH FROM PROTECTED FILES TABLE INTO AN ARRAY                      *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Hashes_4(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_HASH_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + PF_Table.ENTRY_HASH4_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_HASH_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                        READ ALL THE PADDING BYTES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                       *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_Padding_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_PADDING_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i + PF_Table.ENTRY_PADDING_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_PADDING_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                          READ A SINGLE ENTRIES PADDING FROM PROTECTED FILES TABLE INTO AN ARRAY                        *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_Padding(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_PADDING_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + PF_Table.ENTRY_PADDING_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_PADDING_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                          READ ALL THE FILE SIZES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS                        *'
        '**************************************************************************************************************************'
        Public Function Build_Protected_Files_Table_Entries_FileSize_Array(ByVal protected_files_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To PF_Table.SIZE - 1 Step 272
                Dim output_array As Byte() = New Byte(PF_Table.ENTRY_FILESIZE_SIZE - 1) {}
                Buffer.BlockCopy(protected_files_table_array, i + PF_Table.ENTRY_FILESIZE_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_FILESIZE_SIZE)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                        READ A SINGLE ENTRIES FILE SIZE FROM PROTECTED FILES TABLE INTO AN ARRAY                        *'
        '**************************************************************************************************************************'
        Public Function Read_Protected_Files_Table_FileSize(ByVal protected_files_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PF_Table.ENTRY_FILESIZE_SIZE - 1) {}
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + PF_Table.ENTRY_FILESIZE_SKIP_BYTES, output_array, 0, PF_Table.ENTRY_FILESIZE_SIZE)
    
            Return output_array
        End Function
        '**************************************************************************************************************************'
        '*                               READ ALL THE HASHES FROM THE Y TABLE TO A LIST OF ARRAYS                                 *'
        '**************************************************************************************************************************'
        Public Function Build_Y_Table_Entries_Array(ByVal y_table_array As Byte()) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
    
            For i As Integer = 0 To Y_Table.SIZE - 1 Step 20
                Dim output_array As Byte() = New Byte(Y_Table.TABLE_ENTRY_SIZE - 1) {}
                Buffer.BlockCopy(y_table_array, i, output_array, 0, 20)
                output_bytes.Add(output_array)
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                                      READ A SINGLE HASH FROM Y TABLE INTO AN ARRAY                                     *'
        '**************************************************************************************************************************'
        Public Function Read_Y_Table_Entry(ByVal y_table_array As Byte(), ByVal entry_index As Integer) As Byte()
            Dim output_array As Byte() = New Byte(Y_Table.TABLE_ENTRY_SIZE - 1) {}
    
            Buffer.BlockCopy(y_table_array, entry_index * 20, output_array, 0, 20)
    
            Return output_array
        End Function
    
    Add to a module:
      '***************************************************************************************************************'
        '*                                  OPEN FILE DIALOG BOX : RETURNS A STRING                                    *'
        '***************************************************************************************************************'
        Public Function File_Dialog(OFD As OpenFileDialog, ByVal sTitle$, ByVal sFilter$, ByVal sFileName$) As String
            Dim FileOpened As Boolean
    
            OFD.InitialDirectory = Application.ExecutablePath
            OFD.Title = sTitle$
            OFD.Filter = sFilter$
            OFD.FileName = sFileName$
            FileOpened = OFD.ShowDialog()
            File_Dialog = OFD.FileName
    
            If FileOpened = DialogResult.Cancel Then
                Return (vbNullString)
            Else
                Return (File_Dialog)
            End If
        End Function
        '***************************************************************************************************************'
        '*                 CONVERT A BYTE ARRAY TO A HEXADECIMAL STRING : FROM FILE IN SPECIFIED CHUNKS                *'
        '***************************************************************************************************************'
        Public Function Read_PFD(ByVal pfd_file$, ByVal start_offset As Long, ByVal chunk_size As Long) As Byte()
            Dim bytes As Byte() = New Byte(chunk_size - 1) {}
    
            Using fs As FileStream = New FileStream(pfd_file$, FileMode.Open, FileAccess.Read)
                fs.Seek(start_offset, IO.SeekOrigin.Begin)
                fs.Read(bytes, 0, chunk_size)
                fs.Close()
                fs.Dispose()
            End Using
    
            Return bytes
        End Function
        '***************************************************************************************************************'
        '*                      		CONVERT A BYTE ARRAY TO A HEXADECIMAL STRING	                           *'
        '***************************************************************************************************************'
        Public Function ByteArray_To_Hex(bytes As Byte(), Optional ByVal separator$ = Nothing) As String
            Dim strHex As New StringBuilder(bytes.Length * 2)
    
            For Each b As Byte In bytes
                strHex.Append(UCase(b.ToString("X2")) & separator$)
            Next
    
            Return Trim(strHex.ToString())
        End Function
    
    Add to a module:
       '**************************************************************************************************************************'
        '*                                              AES DECRYPTION FUNCTION                                                   *'
        '**************************************************************************************************************************'
        Public Function AES_Decrypt(ByVal bytes As Byte(), ByVal block_size As Long, ByVal key_size As Long, ByVal aes_iv As Byte(), ByVal aes_key As Byte()) As Byte()
            '--------------------------------------------------------------------------------------------------------------------------'
            ' AES Crypto Service Provider
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim AES As New AesCryptoServiceProvider()
            '--------------------------------------------------------------------------------------------------------------------------'
            ' AES Crypto Service Provider parameters
            '--------------------------------------------------------------------------------------------------------------------------'
            AES.BlockSize = block_size
            AES.KeySize = key_size
            AES.IV = aes_iv
            AES.Key = aes_key
            AES.Mode = CipherMode.CBC
            AES.Padding = PaddingMode.None
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Decrypt the bytes : AES 128 CBC mode
            '--------------------------------------------------------------------------------------------------------------------------'
            Using AES_Dec As ICryptoTransform = AES.CreateDecryptor()
                Dim dec_bytes As Byte() = AES_Dec.TransformFinalBlock(bytes, 0, bytes.Length)
                '--------------------------------------------------------------------------------------------------------------------------'
                ' Return the byte array of decrypted bytes
                '--------------------------------------------------------------------------------------------------------------------------'
                Return dec_bytes
            End Using
        End Function
    
    To test the code, add a ritch text box named txtHex to a blank form, and a command button. Add the following code to the click event handler of the command button:
     '**************************************************************************************************************************'
            '*                                             LOAD :: PARAM.PFD                                                          *'
            '**************************************************************************************************************************'
            Dim OFD As OpenFileDialog = New OpenFileDialog
            '--------------------------------------------------------------------------------------------------------------------------'
            ' String to hold the return value of the open file dialog
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim pfd_path$ = File_Dialog(OFD, "Open PARAM.PFD", "Playstation 3 - PARAM.PFD|*.pfd", "*.pfd")
    
            '**************************************************************************************************************************'
            '*                                            READ :: HEADER TABLE                                                        *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the entire header into a variable
            '--------------------------------------------------------------------------------------------------------------------------'
            PFD_HEADER_TABLE = Read_PFD(pfd_path, PFD_HEADER.OFFSET, PFD_HEADER.SIZE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read each section of the header into variables
            '--------------------------------------------------------------------------------------------------------------------------'
            PFD_HEADER_MAGIC = Read_PFD(pfd_path, PFD_HEADER.MAGIC_OFFSET, PFD_HEADER.MAGIC_SIZE)
            PFD_HEADER_VERSION = Read_PFD(pfd_path, PFD_HEADER.VERSION_OFFSET, PFD_HEADER.VERSION_SIZE)
            PFD_HEADER_TABLE_IV = Read_PFD(pfd_path, PFD_HEADER.IV_OFFSET, PFD_HEADER.IV_SIZE)
            PFD_HEADER_SIGNATURE = Read_PFD(pfd_path, PFD_HEADER.SIGNATURE_OFFSET, PFD_HEADER.SIGNATURE_SIZE)
    
            '**************************************************************************************************************************'
            '*                                            DECRYPT :: HEADER TABLE                                                     *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the header signature into a variable used for holding the decrypted header
            '--------------------------------------------------------------------------------------------------------------------------'
            PFD_HEADER_DECRYPTED = Read_PFD(pfd_path, PFD_HEADER.SIGNATURE_OFFSET, PFD_HEADER.SIGNATURE_SIZE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Pass the header signature to the AES_Decrypt function which will return the decrypted header
            '--------------------------------------------------------------------------------------------------------------------------'
            PFD_HEADER_DECRYPTED = AES_Decrypt(PFD_HEADER_DECRYPTED, 128, 128, PFD_HEADER_TABLE_IV, SYSCON_MANAGER_KEY)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the decrypted top hash
            '--------------------------------------------------------------------------------------------------------------------------'
            PFD_HEADER_DECRYPTED_TOP_HASH = Read_Decrypted_Header_Top_Hash(PFD_HEADER_DECRYPTED, PFD_HEADER.TOP_HASH_OFFSET)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the decrypted bottom hash
            '--------------------------------------------------------------------------------------------------------------------------'
            PFD_HEADER_DECRYPTED_BOTTOM_HASH = Read_Decrypted_Header_Bottom_Hash(PFD_HEADER_DECRYPTED, PFD_HEADER.BOTTOM_HASH_OFFSET)
    
    
    
    
            '**************************************************************************************************************************'
            '*                                             READ :: HASH TABLE                                                         *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the hash tables header into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            PFD_HASH_TABLE_HEADER = Read_PFD(pfd_path, Hash_Table.HEADER_OFFSET, Hash_Table.HEADER_SIZE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the hash table into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            PFD_HASH_TABLE = Read_PFD(pfd_path, Hash_Table.OFFSET, Hash_Table.SIZE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the hash table entries into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_HASH_TABLE_ENTRIES As List(Of Byte()) = Build_Hash_Table_Entries_Array(PFD_HASH_TABLE)
    
            '**************************************************************************************************************************'
            '*                                        READ :: PROTECTED FILES TABLE                                                   *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the protected files table into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            PFD_PROTECTED_FILES_TABLE = Read_PFD(pfd_path, PF_Table.OFFSET, PF_Table.SIZE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES As List(Of Byte()) = Build_Protected_Files_Table_Entries_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries indexes into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_INDEX As List(Of Byte()) = Build_Protected_Files_Table_Entries_Index_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries file names into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_NAME As List(Of Byte()) = Build_Protected_Files_Table_Entries_Name_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries garbage bytes into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_GARBAGE As List(Of Byte()) = Build_Protected_Files_Table_Entries_Garbage_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries data into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_DATA As List(Of Byte()) = Build_Protected_Files_Table_Entries_Data_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries entry key into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_KEY As List(Of Byte()) = Build_Protected_Files_Table_Entries_Key_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries hashes (all 4) into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_HASHES As List(Of Byte()) = Build_Protected_Files_Table_Entries_Hashes_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries first hash into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_1 As List(Of Byte()) = Build_Protected_Files_Table_Entries_Hashes_1_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries second hash into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_2 As List(Of Byte()) = Build_Protected_Files_Table_Entries_Hashes_2_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries third hash into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_3 As List(Of Byte()) = Build_Protected_Files_Table_Entries_Hashes_3_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries fourth hash into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_4 As List(Of Byte()) = Build_Protected_Files_Table_Entries_Hashes_4_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries padding into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_PADDING As List(Of Byte()) = Build_Protected_Files_Table_Entries_Padding_Array(PFD_PROTECTED_FILES_TABLE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the protected files table entries file size into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_PROTECTED_FILES_TABLE_ENTRIES_FILESIZE As List(Of Byte()) = Build_Protected_Files_Table_Entries_FileSize_Array(PFD_PROTECTED_FILES_TABLE)
    
            '**************************************************************************************************************************'
            '*                                              READ :: Y TABLE                                                           *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the entire Y table into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            PFD_Y_TABLE = Read_PFD(pfd_path, Y_Table.OFFSET, Y_Table.SIZE)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read all the Y table hashes into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim PFD_Y_TABLE_ENTRIES As List(Of Byte()) = Build_Y_Table_Entries_Array(PFD_Y_TABLE)
    
            '**************************************************************************************************************************'
            '*                                           READ :: BOTTOM PADDING                                                       *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the bottom padding (44 bytes) into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            PFD_BOTTOM_PADDING = Read_PFD(pfd_path, Bottom_Padding.OFFSET, Bottom_Padding.SIZE)
    
    
            txtHex.Text = Nothing
    
    
            '**************************************************************************************************************************'
            '*                                            OUTPUT :: HEADER TABLE                                                      *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the entire header table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(PFD_HEADER_TABLE, " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the individual parts of the header table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(PFD_HEADER_MAGIC, " ") & vbCrLf & vbCrLf)
            txtHex.AppendText(ByteArray_To_Hex(PFD_HEADER_VERSION, " ") & vbCrLf & vbCrLf)
            txtHex.AppendText(ByteArray_To_Hex(PFD_HEADER_TABLE_IV, " ") & vbCrLf & vbCrLf)
            txtHex.AppendText(ByteArray_To_Hex(PFD_HEADER_SIGNATURE, " ") & vbCrLf & vbCrLf)
    
            '**************************************************************************************************************************'
            '*                                        OUTPUT :: DECRYPTED HEADER TABLE                                                *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the decrypted header table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(PFD_HEADER_DECRYPTED, " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the decrypted top hash
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(PFD_HEADER_DECRYPTED_TOP_HASH, " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the decrypted bottom hash
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(PFD_HEADER_DECRYPTED_BOTTOM_HASH, " ") & vbCrLf & vbCrLf)
    
            '**************************************************************************************************************************'
            '*                                              OUTPUT :: HASH TABLE                                                      *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the header of the hash table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(PFD_HASH_TABLE_HEADER, " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the entire hash table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(PFD_HASH_TABLE, " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the individual hash table entries
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_HASH_TABLE_ENTRIES.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_HASH_TABLE_ENTRIES(i), " ") & vbCrLf)
    
                If i = PFD_HASH_TABLE_ENTRIES.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single hash table entry
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Hash_Table_Entry(PFD_HASH_TABLE, 28), " ") & vbCrLf & vbCrLf)
    
            '**************************************************************************************************************************'
            '*                                          OUTPUT :: PROTECTED FILES TABLE                                               *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the entire protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE, " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the entries in the protected files table 
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entry in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Entry(PFD_PROTECTED_FILES_TABLE, 1), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the indexes of the entries in the protected files table 
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_INDEX.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_INDEX(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_INDEX.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single index of an entry in the protected files table 
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Index(PFD_PROTECTED_FILES_TABLE, 113), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the file names of the entries in the protected files table 
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_NAME.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_NAME(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_NAME.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Ouput a single file name of an entry in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Name(PFD_PROTECTED_FILES_TABLE, 1), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the garbage bytes of the entries in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_GARBAGE.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_GARBAGE(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_GARBAGE.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entries garbage bytes in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Garbage(PFD_PROTECTED_FILES_TABLE, 1), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the data of the entries in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_DATA.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_DATA(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_DATA.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entries data in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Data(PFD_PROTECTED_FILES_TABLE, 1), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the keys for the entries in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_KEY.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_KEY(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_KEY.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entries key in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Key(PFD_PROTECTED_FILES_TABLE, 1), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the hashes for the entries in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_HASHES.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_HASHES(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_HASHES.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entries hashes in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Hashes(PFD_PROTECTED_FILES_TABLE, 1), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the first hashes for the entries in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_1.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_1(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_1.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entries first hash in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Hashes_1(PFD_PROTECTED_FILES_TABLE, 0), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the second hashes for the entries in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_2.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_2(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_2.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            txtHex.AppendText("--19--" & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entries second hash in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Hashes_2(PFD_PROTECTED_FILES_TABLE, 1), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the third hashes for the entries in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_3.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_3(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_3.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entries third hash in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Hashes_3(PFD_PROTECTED_FILES_TABLE, 1), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the fourth hashes for the entries in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_4.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_4(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_4.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entries fourth hash in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Hashes_4(PFD_PROTECTED_FILES_TABLE, 1), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the padding for the entries in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_PADDING.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_PADDING(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_PADDING.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entries padding in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_Padding(PFD_PROTECTED_FILES_TABLE, 0), " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the file sizes for the entries in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_PROTECTED_FILES_TABLE_ENTRIES_FILESIZE.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_FILESIZE(i), " ") & vbCrLf)
    
                If i = PFD_PROTECTED_FILES_TABLE_ENTRIES_FILESIZE.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entries file size in the protected files table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Protected_Files_Table_FileSize(PFD_PROTECTED_FILES_TABLE, 0), " ") & vbCrLf & vbCrLf)
    
            '**************************************************************************************************************************'
            '*                                               OUTPUT :: Y TABLE                                                        *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the entire Y table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(PFD_Y_TABLE, " ") & vbCrLf & vbCrLf)
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output all the hashes for the entries in the Y table
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PFD_Y_TABLE_ENTRIES.Count - 1
                txtHex.AppendText(ByteArray_To_Hex(PFD_Y_TABLE_ENTRIES(i), " ") & vbCrLf)
    
                If i = PFD_Y_TABLE_ENTRIES.Count - 1 Then txtHex.AppendText(vbCrLf)
            Next
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output a single entries hash in the Y table
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(Read_Y_Table_Entry(PFD_Y_TABLE, 56), " ") & vbCrLf & vbCrLf)
    
            '**************************************************************************************************************************'
            '*                                           OUTPUT :: BOTTOM PADDING                                                     *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the files bottom padding
            '--------------------------------------------------------------------------------------------------------------------------'
            txtHex.AppendText(ByteArray_To_Hex(PFD_BOTTOM_PADDING, " ") & vbCrLf & vbCrLf)
    C# Code
    Code:
    Add to a class:
    
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    
    public class clsGlobal
    {
        //**************************************************************************************************************************'
        //* GLOBAL KEYS *'
        //**************************************************************************************************************************'
        public static byte[] SYSCON_MANAGER_KEY = new byte[] {
            0xd4,
            0x13,
            0xb8,
            0x96,
            0x63,
            0xe1,
            0xfe,
            0x9f,
            0x75,
            0x14,
            0x3d,
            0x3b,
            0xb4,
            0x56,
            0x52,
            0x74
    
        };
        //**************************************************************************************************************************'
        //* GLOBAL HEADER TABLE VARIABLES *'
        //**************************************************************************************************************************'
        public struct PFD_HEADER
        {
            public const int OFFSET = 0x0;
            public const int SIZE = 96;
            public const int MAGIC_OFFSET = 0x0;
            public const int MAGIC_SIZE = 8;
            public const int VERSION_OFFSET = 0x8;
            public const int VERSION_SIZE = 8;
            public const int IV_OFFSET = 0x10;
            public const int IV_SIZE = 16;
            public const int SIGNATURE_OFFSET = 0x20;
            public const int SIGNATURE_SIZE = 64;
            public const int TOP_HASH_OFFSET = 0x0;
            public const int TOP_HASH_SIZE = 20;
            public const int BOTTOM_HASH_OFFSET = 0x14;
            public const int BOTTOM_HASH_SIZE = 20;
        }
        public static byte[] PFD_HEADER_TABLE = new byte[PFD_HEADER.SIGNATURE_SIZE + 1];
        public static byte[] PFD_HEADER_MAGIC = new byte[PFD_HEADER.MAGIC_SIZE + 1];
        public static byte[] PFD_HEADER_VERSION = new byte[PFD_HEADER.VERSION_SIZE + 1];
        public static byte[] PFD_HEADER_TABLE_IV = new byte[PFD_HEADER.IV_SIZE + 1];
        public static byte[] PFD_HEADER_SIGNATURE = new byte[PFD_HEADER.SIGNATURE_SIZE + 1];
        public static byte[] PFD_HEADER_DECRYPTED = new byte[PFD_HEADER.SIGNATURE_SIZE + 1];
        public static byte[] PFD_HEADER_DECRYPTED_TOP_HASH = new byte[PFD_HEADER.TOP_HASH_SIZE + 1];
        public static byte[] PFD_HEADER_DECRYPTED_BOTTOM_HASH = new byte[PFD_HEADER.BOTTOM_HASH_SIZE + 1];
        //**************************************************************************************************************************'
        //* GLOBAL HASH TABLE VARIABLES *'
        //**************************************************************************************************************************'
        public struct HASH_TABLE
        {
            public const int MAX_ENTRIES = 57;
            public const int HEADER_OFFSET = 0x60;
            public const int HEADER_SIZE = 24;
            public const int OFFSET = 0x78;
            public const int SIZE = 456;
            public const int TABLE_ENTRY_SIZE = 8;
        }
        public static byte[] PFD_HASH_TABLE_HEADER = new byte[HASH_TABLE.HEADER_SIZE + 1];
        public static byte[] PFD_HASH_TABLE = new byte[HASH_TABLE.SIZE + 1];
        public static byte[] PFD_HASH_TABLE_ALL_ENTRIES = new byte[HASH_TABLE.SIZE / HASH_TABLE.TABLE_ENTRY_SIZE + 1];
        //**************************************************************************************************************************'
        //* GLOBAL PROTECTED FILES TABLE VARIABLES *'
        //**************************************************************************************************************************'
        public struct PF_TABLE
        {
            public const int OFFSET = 0x240;
            public const int SIZE = 31008;
            public const int ENTRY_SIZE = 272;
            public const int ENTRY_INDEX_SIZE = 8;
            public const int ENTRY_NAME_SKIP_BYTES = 8;
            public const int ENTRY_NAME_SIZE = 65;
            public const int ENTRY_GARBAGE_SKIP_BYTES = 73;
            public const int ENTRY_GARBAGE_SIZE = 7;
            public const int ENTRY_DATA_SKIP_BYTES = 80;
            public const int ENTRY_DATA_SIZE = 192;
            public const int ENTRY_KEY_SKIP_BYTES = 80;
            public const int ENTRY_KEY_SIZE = 64;
            public const int ENTRY_HASHES_SKIP_BYTES = 144;
            public const int ENTRY_HASHES_SIZE = 80;
            public const int ENTRY_HASH1_SKIP_BYTES = 144;
            public const int ENTRY_HASH_SIZE = 20;
            public const int ENTRY_HASH2_SKIP_BYTES = 164;
            public const int ENTRY_HASH3_SKIP_BYTES = 184;
            public const int ENTRY_HASH4_SKIP_BYTES = 204;
            public const int ENTRY_PADDING_SKIP_BYTES = 224;
            public const int ENTRY_PADDING_SIZE = 40;
            public const int ENTRY_FILESIZE_SKIP_BYTES = 264;
            public const int ENTRY_FILESIZE_SIZE = 8;
        }
        public static byte[] PFD_PROTECTED_FILES_TABLE = new byte[PF_TABLE.SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY = new byte[PF_TABLE.ENTRY_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ALL_ENTRIES = new byte[PF_TABLE.SIZE / PF_TABLE.ENTRY_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_INDEX = new byte[PF_TABLE.ENTRY_INDEX_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_NAME = new byte[PF_TABLE.ENTRY_NAME_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_GARBAGE = new byte[PF_TABLE.ENTRY_GARBAGE_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_DATA = new byte[PF_TABLE.ENTRY_DATA_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_KEY = new byte[PF_TABLE.ENTRY_KEY_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_HASHES = new byte[PF_TABLE.ENTRY_HASHES_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_HASH1 = new byte[PF_TABLE.ENTRY_HASH_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_HASH2 = new byte[PF_TABLE.ENTRY_HASH_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_HASH3 = new byte[PF_TABLE.ENTRY_HASH_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_HASH4 = new byte[PF_TABLE.ENTRY_HASH_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_PADDING = new byte[PF_TABLE.ENTRY_PADDING_SIZE + 1];
        public static byte[] PFD_PROTECTED_FILES_TABLE_ENTRY_FILESIZE = new byte[PF_TABLE.ENTRY_FILESIZE_SIZE + 1];
        //**************************************************************************************************************************'
        //* GLOBAL Y TABLE VARIABLES *'
        //**************************************************************************************************************************'
        public struct Y_TABLE
        {
            public const int MAX_ENTRIES = 57;
            public const int OFFSET = 0x7b60;
            public const int SIZE = 1140;
            public const int TABLE_ENTRY_SIZE = 20;
        }
        public static byte[] PFD_Y_TABLE = new byte[Y_TABLE.SIZE + 1];
        public static byte[] PFD_Y_ALL_ENTRIES = new byte[Y_TABLE.SIZE / Y_TABLE.TABLE_ENTRY_SIZE + 1];
        //**************************************************************************************************************************'
        //* GLOBAL PADDING VARIABLES *'
        //**************************************************************************************************************************'
        public struct BOTTOM_PADDING
        {
            public const int OFFSET = 0x7fd4;
            public const int SIZE = 44;
        }
        public static byte[] PFD_BOTTOM_PADDING = new byte[BOTTOM_PADDING.SIZE + 1];
    }
    
    Add to a class:
    
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    using glb = clsGlobal;
    
    public class clsPFDTables
    {
        //**************************************************************************************************************************'
        //* READ THE TOP HASH FROM DECRYPTED HEADER IN AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Decrypted_Header_Top_Hash(byte[] decrypted_header_array, int offset)
        {
            
            byte[] output_array = new byte[glb.PFD_HEADER.TOP_HASH_SIZE];
    
            Buffer.BlockCopy(decrypted_header_array, offset, output_array, 0, glb.PFD_HEADER.TOP_HASH_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ THE BOTTOM HASH FROM DECRYPTED HEADER IN AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Decrypted_Header_Bottom_Hash(byte[] decrypted_header_array, int offset)
        {
            byte[] output_array = new byte[glb.PFD_HEADER.BOTTOM_HASH_SIZE];
    
            Buffer.BlockCopy(decrypted_header_array, offset, output_array, 0, glb.PFD_HEADER.BOTTOM_HASH_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL ENTRIES FROM HASH TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Hash_Table_Entries_Array(byte[] hash_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.HASH_TABLE.SIZE - 1; i += 8)
            {
                byte[] output_array = new byte[glb.HASH_TABLE.TABLE_ENTRY_SIZE];
                Buffer.BlockCopy(hash_table_array, i, output_array, 0, 8);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRY FROM HASH TABLE IN AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Hash_Table_Entry(byte[] hash_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.HASH_TABLE.TABLE_ENTRY_SIZE];
    
            Buffer.BlockCopy(hash_table_array, entry_index * 8, output_array, 0, 8);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL ENTRIES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i, output_array, 0, 272);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRY FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Entry(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272, output_array, 0, 272);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL INDEXES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Index_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_INDEX_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i, output_array, 0, glb.PF_TABLE.ENTRY_INDEX_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES INDEX FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Index(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_INDEX_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272, output_array, 0, glb.PF_TABLE.ENTRY_INDEX_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL FILE NAMES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Name_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_NAME_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i + glb.PF_TABLE.ENTRY_NAME_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_NAME_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES FILE NAME FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Name(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_NAME_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + glb.PF_TABLE.ENTRY_NAME_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_NAME_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL GARBAGE BYTES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Garbage_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_GARBAGE_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i + glb.PF_TABLE.ENTRY_GARBAGE_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_GARBAGE_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES GARBAGE BYTES FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Garbage(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_GARBAGE_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + glb.PF_TABLE.ENTRY_GARBAGE_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_GARBAGE_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL DATA FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Data_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_DATA_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i + glb.PF_TABLE.ENTRY_DATA_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_DATA_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES DATA FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Data(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_DATA_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272, output_array, 0, glb.PF_TABLE.ENTRY_DATA_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL ENTRY KEYS FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Key_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_KEY_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i + glb.PF_TABLE.ENTRY_KEY_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_KEY_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES KEY FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Key(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_KEY_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + glb.PF_TABLE.ENTRY_KEY_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_KEY_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL FILE HASHES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Hashes_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_HASHES_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i + glb.PF_TABLE.ENTRY_HASHES_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_HASHES_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES HASHES FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Hashes(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_HASHES_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + glb.PF_TABLE.ENTRY_HASHES_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_HASHES_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL THE FIRST HASHES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Hashes_1_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_HASH_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i + glb.PF_TABLE.ENTRY_HASH1_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_HASH_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES FIRST HASH FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Hashes_1(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_HASH_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + glb.PF_TABLE.ENTRY_HASH1_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_HASH_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL THE SECOND HASHES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Hashes_2_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_HASH_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i + glb.PF_TABLE.ENTRY_HASH2_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_HASH_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES SECOND HASH FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Hashes_2(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_HASH_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + glb.PF_TABLE.ENTRY_HASH2_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_HASH_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL THE THIRD HASHES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Hashes_3_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_HASH_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i + glb.PF_TABLE.ENTRY_HASH3_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_HASH_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES THIRD HASH FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Hashes_3(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_HASH_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + glb.PF_TABLE.ENTRY_HASH3_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_HASH_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL THE FOURTH HASHES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Hashes_4_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_HASH_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i + glb.PF_TABLE.ENTRY_HASH4_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_HASH_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES FOURTH HASH FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Hashes_4(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_HASH_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + glb.PF_TABLE.ENTRY_HASH4_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_HASH_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL THE PADDING BYTES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_Padding_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_PADDING_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i + glb.PF_TABLE.ENTRY_PADDING_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_PADDING_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES PADDING FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_Padding(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_PADDING_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + glb.PF_TABLE.ENTRY_PADDING_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_PADDING_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL THE FILE SIZES FROM PROTECTED FILES TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Protected_Files_Table_Entries_FileSize_Array(byte[] protected_files_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.PF_TABLE.SIZE - 1; i += 272)
            {
                byte[] output_array = new byte[glb.PF_TABLE.ENTRY_FILESIZE_SIZE];
                Buffer.BlockCopy(protected_files_table_array, i + glb.PF_TABLE.ENTRY_FILESIZE_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_FILESIZE_SIZE);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE ENTRIES FILE SIZE FROM PROTECTED FILES TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Protected_Files_Table_FileSize(byte[] protected_files_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.PF_TABLE.ENTRY_FILESIZE_SIZE];
    
            Buffer.BlockCopy(protected_files_table_array, entry_index * 272 + glb.PF_TABLE.ENTRY_FILESIZE_SKIP_BYTES, output_array, 0, glb.PF_TABLE.ENTRY_FILESIZE_SIZE);
    
            return output_array;
        }
        //**************************************************************************************************************************'
        //* READ ALL THE HASHES FROM THE Y TABLE TO A LIST OF ARRAYS *'
        //**************************************************************************************************************************'
        public static List<byte[]> Build_Y_Table_Entries_Array(byte[] y_table_array)
        {
            List<byte[]> output_bytes = new List<byte[]>();
    
            for (int i = 0; i <= glb.Y_TABLE.SIZE - 1; i += 20)
            {
                byte[] output_array = new byte[glb.Y_TABLE.TABLE_ENTRY_SIZE];
                Buffer.BlockCopy(y_table_array, i, output_array, 0, 20);
                output_bytes.Add(output_array);
            }
    
            return output_bytes;
        }
        //**************************************************************************************************************************'
        //* READ A SINGLE HASH FROM Y TABLE INTO AN ARRAY *'
        //**************************************************************************************************************************'
        public static byte[] Read_Y_Table_Entry(byte[] y_table_array, int entry_index)
        {
            byte[] output_array = new byte[glb.Y_TABLE.TABLE_ENTRY_SIZE];
    
            Buffer.BlockCopy(y_table_array, entry_index * 20, output_array, 0, 20);
    
            return output_array;
        }
    
    }
    
    Add to a class:
    
    using System;
    using System.Windows.Forms;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    
    static class clsFileAccess
    {
        //***************************************************************************************************************'
        //* OPEN FILE DIALOG BOX : RETURNS A STRING *'
        //***************************************************************************************************************'
        public static string File_Dialog(string sTitle, string sFilter, string sFileName)
        {
            OpenFileDialog OFD = new OpenFileDialog(); 
    
            String retval = string.Empty; 
    
            OFD.Filter = sFilter;
            OFD.InitialDirectory = Application.ExecutablePath;
            OFD.Title = sTitle;
            OFD.Filter = sFilter;
            OFD.FileName = sFileName;
    
            if (OFD.ShowDialog() == DialogResult.OK)
                {
                    retval =  OFD.FileName;
                }
            if (retval == String.Empty)
                {
                    return string.Empty;
                }
            else
                {
                    return retval;
                }
        }
        //***************************************************************************************************************'
        //* CONVERT A BYTE ARRAY TO A HEXADECIMAL STRING : FROM FILE IN SPECIFIED CHUNKS *'
        //***************************************************************************************************************'
        public static byte[] Read_PFD(string pfd_file, long start_offset, int chunk_size)
        {
            byte[] bytes = new byte[chunk_size];
    
            using (FileStream fs = new FileStream(pfd_file, FileMode.Open, FileAccess.Read)) {
                fs.Seek(start_offset, System.IO.SeekOrigin.Begin);
                fs.Read(bytes, 0, chunk_size);
                fs.Close();
                fs.Dispose();
            }
    
            return bytes;
        }
        //***************************************************************************************************************'
        //* CONVERT A BYTE ARRAY TO A HEXADECIMAL STRING : FROM BYTE ARRAY *'
        //***************************************************************************************************************'
        public static string ByteArray_To_Hex(byte[] bytes, string separator = null)
        {
            string retval = string.Empty;
            StringBuilder strHex = new StringBuilder(bytes.Length * 2);
    
            foreach (byte b in bytes) {
                strHex.Append((b.ToString("X2")) + separator);
            }
    
            retval = strHex.ToString().ToUpper();
    
            return retval.Trim();
        }
    }
    
    Add to a class:
    
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    using System.IO;
    using System.Security.Cryptography;
    
    static class clsEncDec
    {
        //**************************************************************************************************************************'
        //* AES DECRYPTION FUNCTION *'
        //**************************************************************************************************************************'
        public static byte[] AES_Decrypt(byte[] bytes, int block_size, int key_size, byte[] aes_iv, byte[] aes_key)
        {
            //--------------------------------------------------------------------------------------------------------------------------'
            // AES Crypto Service Provider
            //--------------------------------------------------------------------------------------------------------------------------'
            AesCryptoServiceProvider AES = new AesCryptoServiceProvider();
            //--------------------------------------------------------------------------------------------------------------------------'
            // AES Crypto Service Provider parameters
            //--------------------------------------------------------------------------------------------------------------------------'
            AES.BlockSize = block_size;
            AES.KeySize = key_size;
            AES.IV = aes_iv;
            AES.Key = aes_key;
            AES.Mode = CipherMode.CBC;
            AES.Padding = PaddingMode.None;
            //--------------------------------------------------------------------------------------------------------------------------'
            // Decrypt the bytes : AES 128 CBC mode
            //--------------------------------------------------------------------------------------------------------------------------'
            using (ICryptoTransform AES_Dec = AES.CreateDecryptor())
            {
                byte[] dec_bytes = AES_Dec.TransformFinalBlock(bytes, 0, bytes.Length);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Return the byte array of decrypted bytes
                //--------------------------------------------------------------------------------------------------------------------------'
                return dec_bytes;
            }
        }
    }
    
    To test the code, add a ritch text box named txtHex to a blank form, and a command button. Add the following code to the click event handler of the command button:
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using clsGlb = clsGlobal;
    using clsPFD = clsPFDTables;
    using clsFA = clsFileAccess;
    using clsAES = clsEncDec;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
                public Form1()
                {
                    InitializeComponent();
                }
    
                private void cmdReadPFD_Click(object sender, EventArgs e)
                {
                //**************************************************************************************************************************'
                //* LOAD :: PARAM.PFD *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // String to hold the return value of the open file dialog
                //--------------------------------------------------------------------------------------------------------------------------'
                string pfd_path = clsFA.File_Dialog("Open PARAM.PFD", "Playstation 3 - PARAM.PFD|*.pfd", "*.pfd");
    
                //**************************************************************************************************************************'
                //* READ :: HEADER TABLE *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the entire header into a variable
                //--------------------------------------------------------------------------------------------------------------------------'
                clsGlb.PFD_HEADER_TABLE = clsFA.Read_PFD(pfd_path, clsGlb.PFD_HEADER.OFFSET, clsGlb.PFD_HEADER.SIZE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read each section of the header into variables
                //--------------------------------------------------------------------------------------------------------------------------'
                clsGlb.PFD_HEADER_MAGIC = clsFA.Read_PFD(pfd_path, clsGlb.PFD_HEADER.MAGIC_OFFSET, clsGlb.PFD_HEADER.MAGIC_SIZE);
                clsGlb.PFD_HEADER_VERSION = clsFA.Read_PFD(pfd_path, clsGlb.PFD_HEADER.VERSION_OFFSET, clsGlb.PFD_HEADER.VERSION_SIZE);
                clsGlb.PFD_HEADER_TABLE_IV = clsFA.Read_PFD(pfd_path, clsGlb.PFD_HEADER.IV_OFFSET, clsGlb.PFD_HEADER.IV_SIZE);
                clsGlb.PFD_HEADER_SIGNATURE = clsFA.Read_PFD(pfd_path, clsGlb.PFD_HEADER.SIGNATURE_OFFSET, clsGlb.PFD_HEADER.SIGNATURE_SIZE);
    
                //**************************************************************************************************************************'
                //* DECRYPT :: HEADER TABLE *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the header signature into a variable used for holding the decrypted header
                //--------------------------------------------------------------------------------------------------------------------------'
                clsGlb.PFD_HEADER_DECRYPTED = clsFA.Read_PFD(pfd_path, clsGlb.PFD_HEADER.SIGNATURE_OFFSET, clsGlb.PFD_HEADER.SIGNATURE_SIZE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Pass the header signature to the AES_Decrypt function which will return the decrypted header
                //--------------------------------------------------------------------------------------------------------------------------'
                clsGlb.PFD_HEADER_DECRYPTED = clsAES.AES_Decrypt(clsGlb.PFD_HEADER_DECRYPTED, 128, 128, clsGlb.PFD_HEADER_TABLE_IV, clsGlb.SYSCON_MANAGER_KEY);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the decrypted top hash
                //--------------------------------------------------------------------------------------------------------------------------'
                clsGlb.PFD_HEADER_DECRYPTED_TOP_HASH = clsPFD.Read_Decrypted_Header_Top_Hash(clsGlb.PFD_HEADER_DECRYPTED, clsGlb.PFD_HEADER.TOP_HASH_OFFSET);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the decrypted bottom hash
                //--------------------------------------------------------------------------------------------------------------------------'
                clsGlb.PFD_HEADER_DECRYPTED_BOTTOM_HASH = clsPFD.Read_Decrypted_Header_Bottom_Hash(clsGlb.PFD_HEADER_DECRYPTED, clsGlb.PFD_HEADER.BOTTOM_HASH_OFFSET);
    
    
    
    
                //**************************************************************************************************************************'
                //* READ :: HASH TABLE *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the hash tables header into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                clsGlb.PFD_HASH_TABLE_HEADER = clsFA.Read_PFD(pfd_path, clsGlb.HASH_TABLE.HEADER_OFFSET, clsGlb.HASH_TABLE.HEADER_SIZE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the hash table into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                clsGlb.PFD_HASH_TABLE = clsFA.Read_PFD(pfd_path, clsGlb.HASH_TABLE.OFFSET, clsGlb.HASH_TABLE.SIZE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the hash table entries into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_HASH_TABLE_ALL_ENTRIES = clsPFD.Build_Hash_Table_Entries_Array(clsGlb.PFD_HASH_TABLE);
    
                //**************************************************************************************************************************'
                //* READ :: PROTECTED FILES TABLE *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the protected files table into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                clsGlb.PFD_PROTECTED_FILES_TABLE = clsFA.Read_PFD(pfd_path, clsGlb.PF_TABLE.OFFSET, clsGlb.PF_TABLE.SIZE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES = clsPFD.Build_Protected_Files_Table_Entries_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries indexes into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_INDEX = clsPFD.Build_Protected_Files_Table_Entries_Index_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries file names into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_NAME = clsPFD.Build_Protected_Files_Table_Entries_Name_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries garbage bytes into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_GARBAGE = clsPFD.Build_Protected_Files_Table_Entries_Garbage_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries data into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_DATA = clsPFD.Build_Protected_Files_Table_Entries_Data_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries entry key into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_KEY = clsPFD.Build_Protected_Files_Table_Entries_Key_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries hashes (all 4) into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_HASHES = clsPFD.Build_Protected_Files_Table_Entries_Hashes_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries first hash into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_1 = clsPFD.Build_Protected_Files_Table_Entries_Hashes_1_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries second hash into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_2 = clsPFD.Build_Protected_Files_Table_Entries_Hashes_2_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries third hash into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_3 = clsPFD.Build_Protected_Files_Table_Entries_Hashes_3_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries fourth hash into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_4 = clsPFD.Build_Protected_Files_Table_Entries_Hashes_4_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries padding into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_PADDING = clsPFD.Build_Protected_Files_Table_Entries_Padding_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the protected files table entries file size into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_PROTECTED_FILES_TABLE_ENTRIES_FILESIZE = clsPFD.Build_Protected_Files_Table_Entries_FileSize_Array(clsGlb.PFD_PROTECTED_FILES_TABLE);
    
                //**************************************************************************************************************************'
                //* READ :: Y TABLE *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the entire Y table into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                clsGlb.PFD_Y_TABLE = clsFA.Read_PFD(pfd_path, clsGlb.Y_TABLE.OFFSET, clsGlb.Y_TABLE.SIZE);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read all the Y table hashes into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                List<byte[]> PFD_Y_TABLE_ENTRIES = clsPFD.Build_Y_Table_Entries_Array(clsGlb.PFD_Y_TABLE);
    
                //**************************************************************************************************************************'
                //* READ :: BOTTOM PADDING *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the bottom padding (44 bytes) into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                clsGlb.PFD_BOTTOM_PADDING = clsFA.Read_PFD(pfd_path, clsGlb.BOTTOM_PADDING.OFFSET, clsGlb.BOTTOM_PADDING.SIZE);
    
    
                txtHex.Text = null;
    
    
                //**************************************************************************************************************************'
                //* OUTPUT :: HEADER TABLE *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the entire header table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_HEADER_TABLE, " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the individual parts of the header table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_HEADER_MAGIC, " ") + Environment.NewLine + Environment.NewLine);
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_HEADER_VERSION, " ") + Environment.NewLine + Environment.NewLine);
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_HEADER_TABLE_IV, " ") + Environment.NewLine + Environment.NewLine);
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_HEADER_SIGNATURE, " ") + Environment.NewLine + Environment.NewLine);
    
                //**************************************************************************************************************************'
                //* OUTPUT :: DECRYPTED HEADER TABLE *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the decrypted header table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_HEADER_DECRYPTED, " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the decrypted top hash
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_HEADER_DECRYPTED_TOP_HASH, " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the decrypted bottom hash
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_HEADER_DECRYPTED_BOTTOM_HASH, " ") + Environment.NewLine + Environment.NewLine);
    
                //**************************************************************************************************************************'
                //* OUTPUT :: HASH TABLE *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the header of the hash table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_HASH_TABLE_HEADER, " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the entire hash table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_HASH_TABLE, " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the individual hash table entries
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_HASH_TABLE_ALL_ENTRIES.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_HASH_TABLE_ALL_ENTRIES[i], " ") + Environment.NewLine);
    
                    if (i == PFD_HASH_TABLE_ALL_ENTRIES.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single hash table entry
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Hash_Table_Entry(clsGlb.PFD_HASH_TABLE, 28), " ") + Environment.NewLine + Environment.NewLine);
    
                //**************************************************************************************************************************'
                //* OUTPUT :: PROTECTED FILES TABLE *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the entire protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_PROTECTED_FILES_TABLE, " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entry in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Entry(clsGlb.PFD_PROTECTED_FILES_TABLE, 1), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the indexes of the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_INDEX.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_INDEX[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_INDEX.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single index of an entry in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Index(clsGlb.PFD_PROTECTED_FILES_TABLE, 113), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the file names of the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_NAME.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_NAME[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_NAME.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Ouput a single file name of an entry in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Name(clsGlb.PFD_PROTECTED_FILES_TABLE, 1), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the garbage bytes of the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_GARBAGE.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_GARBAGE[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_GARBAGE.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entries garbage bytes in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Garbage(clsGlb.PFD_PROTECTED_FILES_TABLE, 1), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the data of the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_DATA.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_DATA[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_DATA.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entries data in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Data(clsGlb.PFD_PROTECTED_FILES_TABLE, 1), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the keys for the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_KEY.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_KEY[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_KEY.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entries key in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Key(clsGlb.PFD_PROTECTED_FILES_TABLE, 1), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the hashes for the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_HASHES.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_HASHES[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_HASHES.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entries hashes in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Hashes(clsGlb.PFD_PROTECTED_FILES_TABLE, 1), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the first hashes for the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_1.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_1[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_1.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entries first hash in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Hashes_1(clsGlb.PFD_PROTECTED_FILES_TABLE, 0), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the second hashes for the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_2.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_2[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_2.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                txtHex.AppendText("--19--" + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entries second hash in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Hashes_2(clsGlb.PFD_PROTECTED_FILES_TABLE, 1), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the third hashes for the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_3.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_3[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_3.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entries third hash in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Hashes_3(clsGlb.PFD_PROTECTED_FILES_TABLE, 1), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the fourth hashes for the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_4.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_4[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_HASH_4.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entries fourth hash in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Hashes_4(clsGlb.PFD_PROTECTED_FILES_TABLE, 1), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the padding for the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_PADDING.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_PADDING[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_PADDING.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entries padding in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_Padding(clsGlb.PFD_PROTECTED_FILES_TABLE, 0), " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the file sizes for the entries in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_PROTECTED_FILES_TABLE_ENTRIES_FILESIZE.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_PROTECTED_FILES_TABLE_ENTRIES_FILESIZE[i], " ") + Environment.NewLine);
    
                    if (i == PFD_PROTECTED_FILES_TABLE_ENTRIES_FILESIZE.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entries file size in the protected files table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Protected_Files_Table_FileSize(clsGlb.PFD_PROTECTED_FILES_TABLE, 0), " ") + Environment.NewLine + Environment.NewLine);
    
                //**************************************************************************************************************************'
                //* OUTPUT :: Y TABLE *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the entire Y table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_Y_TABLE, " ") + Environment.NewLine + Environment.NewLine);
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output all the hashes for the entries in the Y table
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PFD_Y_TABLE_ENTRIES.Count - 1; i++)
                {
                    txtHex.AppendText(clsFA.ByteArray_To_Hex(PFD_Y_TABLE_ENTRIES[i], " ") + Environment.NewLine);
    
                    if (i == PFD_Y_TABLE_ENTRIES.Count - 1)
                        txtHex.AppendText(Environment.NewLine);
                }
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output a single entries hash in the Y table
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsPFD.Read_Y_Table_Entry(clsGlb.PFD_Y_TABLE, 56), " ") + Environment.NewLine + Environment.NewLine);
    
                //**************************************************************************************************************************'
                //* OUTPUT :: BOTTOM PADDING *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the files bottom padding
                //--------------------------------------------------------------------------------------------------------------------------'
                txtHex.AppendText(clsFA.ByteArray_To_Hex(clsGlb.PFD_BOTTOM_PADDING, " ") + Environment.NewLine + Environment.NewLine);
            }
        }
    }
    PS3 Save Game Tools Pack Updated by Flat_z, PFDTool v0.2.3 Out

    More PlayStation 3 News...
    Attached Files Attached Files

  5. #55
    Member BerserkLeon's Avatar
    Join Date
    Feb 2011
    Posts
    69
    Can anyone able to communicate with the devs ask them if they could include multicore support for bruteforcing? I've got a fairly crappy quad core and each core can't do much on its own, but pfdtool seems to be locked to a single core.

    Either that, or CUDA/OpenCL. one or both of those options should really speed up the bruteforcing.

    Update: From <GEEK>: I suppose I sort of used the wrong term when I said this code could be optimized, to be honest, since it is working with byte arrays, you cannot really get more speed out of it unless you are constantly reading/writing large sections of bytes (which if you are, feel free to hit me up for some optimization tips on your current code). However, like I said previously, the code could be shrunk way down to a few functions and I only wrote it the way I did for people to easily learn from. Here is all the above code complete in a few functions:

    VB.NET Code
    Code:
    Add to a module:
    
    Imports System.IO
    Imports System.Text
    Imports System.Security.Cryptography
    
    Module modFunctions
        '**************************************************************************************************************************'
        '*                                  OPEN FILE DIALOG BOX :: RETURNS FILE NAME IN A STRING                                 *'
        '**************************************************************************************************************************'
        Public Function File_Dialog(OFD As OpenFileDialog, ByVal sTitle$, ByVal sFilter$, ByVal sFileName$) As String
            Dim FileOpened As Boolean
    
            OFD.InitialDirectory = Application.ExecutablePath
            OFD.Title = sTitle$
            OFD.Filter = sFilter$
            OFD.FileName = sFileName$
            FileOpened = OFD.ShowDialog()
            File_Dialog = OFD.FileName
    
            If FileOpened = DialogResult.Cancel Then
                Return (Nothing)
            Else
                Return (File_Dialog)
            End If
        End Function
        '**************************************************************************************************************************'
        '*                                              AES DECRYPTION FUNCTION                                                   *'
        '**************************************************************************************************************************'
        Public Function AES_Decrypt(ByVal bytes As Byte(), ByVal block_size As Long, ByVal key_size As Long, ByVal aes_iv As Byte(), ByVal aes_key As Byte()) As Byte()
            '--------------------------------------------------------------------------------------------------------------------------'
            ' AES Crypto Service Provider
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim AES As New AesCryptoServiceProvider()
            '--------------------------------------------------------------------------------------------------------------------------'
            ' AES Crypto Service Provider parameters
            '--------------------------------------------------------------------------------------------------------------------------'
            AES.BlockSize = block_size
            AES.KeySize = key_size
            AES.IV = aes_iv
            AES.Key = aes_key
            AES.Mode = CipherMode.CBC
            AES.Padding = PaddingMode.None
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Decrypt the bytes : AES 128 CBC mode
            '--------------------------------------------------------------------------------------------------------------------------'
            Using AES_Dec As ICryptoTransform = AES.CreateDecryptor()
                Dim dec_bytes As Byte() = AES_Dec.TransformFinalBlock(bytes, 0, bytes.Length)
                '--------------------------------------------------------------------------------------------------------------------------'
                ' Return the byte array of decrypted bytes
                '--------------------------------------------------------------------------------------------------------------------------'
                Return dec_bytes
            End Using
        End Function
        '**************************************************************************************************************************'
        '*                          CONVERT A BYTE ARRAY TO A HEXADECIMAL STRING :: FOR VISUAL OUTPUT ONLY                        *'
        '**************************************************************************************************************************'
        Public Function ByteArray_To_Hex(bytes As Byte(), Optional ByVal separator$ = Nothing) As String
            Dim strHex As New StringBuilder(bytes.Length * 2)
    
            For Each b As Byte In bytes
                strHex.Append(UCase(b.ToString("X2")) & separator$)
            Next
    
            Return Trim(strHex.ToString())
        End Function
        '**************************************************************************************************************************'
        '*                               READ DATA FROM HASH TABLE :: OUTPUT = LIST OF BYTE ARRAYS                                *'
        '**************************************************************************************************************************'
        Public Function Read_Hash_Table(ByVal pfd_file$, ByVal start_offset As Integer, ByVal section_size As Integer) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
            Dim curr_offset As Long = start_offset
    
            For i As Integer = 0 To HASH_TABLE.MAX_ENTRIES
                Dim chunk_bytes As Byte() = New Byte(section_size - 1) {}
    
                Using fs As FileStream = New FileStream(pfd_file$, FileMode.Open, FileAccess.Read)
                    fs.Seek(curr_offset, IO.SeekOrigin.Begin)
                    fs.Read(chunk_bytes, 0, section_size)
                    fs.Close()
                    fs.Dispose()
                End Using
    
                output_bytes.Add(chunk_bytes)
    
                curr_offset = curr_offset + HASH_TABLE.ENTRY_SIZE
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                          READ DATA FROM PROTECTED FILES TABLE :: OUTPUT = LIST OF BYTE ARRAYS                          *'
        '**************************************************************************************************************************'
        Public Function Read_PF_Table(ByVal pfd_file$, ByVal start_offset As Integer, ByVal section_size As Integer) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
            Dim curr_offset As Long = PF_TABLE.OFFSET + start_offset
    
            For i As Integer = 0 To PF_TABLE.MAX_ENTRIES
                Dim chunk_bytes As Byte() = New Byte(section_size - 1) {}
    
                Using fs As FileStream = New FileStream(pfd_file$, FileMode.Open, FileAccess.Read)
                    fs.Seek(curr_offset, IO.SeekOrigin.Begin)
                    fs.Read(chunk_bytes, 0, section_size)
                    fs.Close()
                    fs.Dispose()
                End Using
    
                output_bytes.Add(chunk_bytes)
    
                curr_offset = curr_offset + PF_TABLE.ENTRY_SIZE
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                                  READ DATA FROM Y TABLE :: OUTPUT = LIST OF BYTE ARRAYS                                *'
        '**************************************************************************************************************************'
        Public Function Read_Y_Table(ByVal pfd_file$, ByVal start_offset As Integer, ByVal section_size As Integer) As List(Of Byte())
            Dim output_bytes As New List(Of Byte())
            Dim curr_offset As Long = start_offset
    
            For i As Integer = 0 To Y_TABLE.MAX_ENTRIES
                Dim chunk_bytes As Byte() = New Byte(section_size - 1) {}
    
                Using fs As FileStream = New FileStream(pfd_file$, FileMode.Open, FileAccess.Read)
                    fs.Seek(curr_offset, IO.SeekOrigin.Begin)
                    fs.Read(chunk_bytes, 0, section_size)
                    fs.Close()
                    fs.Dispose()
                End Using
    
                output_bytes.Add(chunk_bytes)
    
                curr_offset = curr_offset + Y_TABLE.ENTRY_SIZE
            Next
    
            Return output_bytes
        End Function
        '**************************************************************************************************************************'
        '*                          READ PFD FILE FROM OFFSET TO SPECIFIED BLOCK SIZE :: OUTPUT = BYTE ARRAY                      *'
        '**************************************************************************************************************************'
        Public Function Read_PFD_Block(ByVal pfd_file$, ByVal start_offset As Integer, ByVal section_size As Integer, Optional ByVal decrypt_output As Boolean = False, Optional ByVal IV As Byte() = Nothing) As Byte()
            Dim output_bytes As Byte() = New Byte(section_size - 1) {}
    
            Using fs As FileStream = New FileStream(pfd_file$, FileMode.Open, FileAccess.Read)
                fs.Seek(start_offset, IO.SeekOrigin.Begin)
                fs.Read(output_bytes, 0, section_size)
                fs.Close()
                fs.Dispose()
            End Using
    
            If decrypt_output = True Then
                If IV Is Nothing Then GoTo Err_IV
    
                output_bytes = AES_Decrypt(output_bytes, 128, 128, IV, SYSCON_MANAGER_KEY)
            End If
    
            Return output_bytes
    
    Err_IV:
            Return Nothing
        End Function
        '**************************************************************************************************************************'
        '*                          READ THE TOP/BOTTOM HASH FROM DECRYPTED HEADER :: OUTPUT = BYTE ARRAY                         *'
        '**************************************************************************************************************************'
        Public Function Read_Decrypted_Header_Hash(ByVal decrypted_header_array As Byte(), ByVal offset As Integer) As Byte()
            Dim output_array As Byte() = New Byte(PFD_HEADER_SECTION_SIZE.HASH_SIZE - 1) {}
    
            Buffer.BlockCopy(decrypted_header_array, offset, output_array, 0, PFD_HEADER_SECTION_SIZE.HASH_SIZE)
    
            Return output_array
        End Function
    End Module
    
    Add to a module:
    
    Option Explicit On
    
    Module modGlobal
        '**************************************************************************************************************************'
        '*                                             GLOBAL KEYS                                                                *'
        '**************************************************************************************************************************'
        Public SYSCON_MANAGER_KEY As Byte() = New Byte() {&HD4, &H13, &HB8, &H96, &H63, &HE1, &HFE, &H9F, &H75, &H14, &H3D, &H3B, &HB4, &H56, &H52, &H74}
        '**************************************************************************************************************************'
        '*                                      GLOBAL HEADER TABLE VARIABLES                                                     *'
        '**************************************************************************************************************************'
        Public Structure PFD_HEADER_SECTION
            Const MAGIC_OFFSET As Long = &H0
            Const VERSION_OFFSET As Long = &H8
            Const IV_OFFSET As Long = &H10
            Const SIGNATURE_OFFSET As Long = &H20
            Const TOP_HASH_OFFSET As Long = &H0
            Const BOTTOM_HASH_OFFSET As Long = &H14
        End Structure
        Public Structure PFD_HEADER_SECTION_SIZE
            Const MAGIC_SIZE As Integer = 8
            Const VERSION_SIZE As Integer = 8
            Const IV_SIZE As Integer = 16
            Const SIGNATURE_SIZE As Integer = 64
            Const HASH_SIZE As Integer = 20
        End Structure
        Public Structure PFD_HEADER
            Const OFFSET As Long = &H0
            Const SIZE As Integer = 96
        End Structure
        '**************************************************************************************************************************'
        '*                                      GLOBAL HASH TABLE VARIABLES                                                       *'
        '**************************************************************************************************************************'
        Public Structure HASH_TABLE
            Const OFFSET As Long = &H60
            Const SIZE As Integer = 456
            Const MAX_ENTRIES As Integer = 57
            Const HEADER_OFFSET As Long = &H60
            Const HEADER_SIZE As Integer = 24
            Const ENTRY_OFFSET As Long = &H78
            Const ENTRY_SIZE As Integer = 8
        End Structure
        '**************************************************************************************************************************'
        '*                                  GLOBAL PROTECTED FILES TABLE VARIABLES                                                *'
        '**************************************************************************************************************************'
        Public Structure PF_TABLE_SECTION
            Const INDEX As Integer = 0
            Const NAME As Integer = 8
            Const GARBAGE As Integer = 73
            Const DATA As Integer = 80
            Const ENTRY_KEY As Integer = 80
            Const HASHES As Integer = 144
            Const HASH1 As Integer = 144
            Const HASH2 As Integer = 164
            Const HASH3 As Integer = 184
            Const HASH4 As Integer = 204
            Const PADDING As Integer = 224
            Const FILE_SIZE As Integer = 264
        End Structure
        Public Structure PF_TABLE_SECTION_SIZE
            Const INDEX As Integer = 8
            Const NAME As Integer = 65
            Const GARBAGE As Integer = 7
            Const DATA As Integer = 192
            Const ENTRY_KEY As Integer = 64
            Const HASHES As Integer = 80
            Const HASH As Integer = 20
            Const PADDING As Integer = 40
            Const FILE_SIZE As Integer = 8
        End Structure
        Public Structure PF_TABLE
            Const OFFSET As Long = &H240
            Const SIZE As Integer = 31008
            Const MAX_ENTRIES As Integer = 113
            Const ENTRY_SIZE As Integer = 272
        End Structure
        '**************************************************************************************************************************'
        '*                                          GLOBAL Y TABLE VARIABLES                                                      *'
        '**************************************************************************************************************************'
        Public Structure Y_TABLE
            Const MAX_ENTRIES As Integer = 56
            Const OFFSET As Long = &H7B60
            Const SIZE As Integer = 1140
            Const ENTRY_SIZE As Integer = 20
        End Structure
        '**************************************************************************************************************************'
        '*                                          GLOBAL PADDING VARIABLES                                                      *'
        '**************************************************************************************************************************'
        Public Structure BOTTOM_PADDING
            Const OFFSET As Long = &H7FD4
            Const SIZE As Integer = 44
        End Structure
    End Module
    
    And to test add a ritch text box control to your form (name = rtbHex) and a button (name = cmdReadPFD):
    
    Public Class Form1
    
        Private Sub cmdReadPFD_Click(sender As Object, e As EventArgs) Handles cmdReadPFD.Click
            rtbHex.Text = Nothing
    
            '**************************************************************************************************************************'
            '*                                             LOAD :: PARAM.PFD                                                          *'
            '**************************************************************************************************************************'
            Dim OFD As OpenFileDialog = New OpenFileDialog
            '--------------------------------------------------------------------------------------------------------------------------'
            ' String to hold the return value of the open file dialog
            '--------------------------------------------------------------------------------------------------------------------------'
            Dim pfd_path$ = File_Dialog(OFD, "Open PARAM.PFD", "Playstation 3 - PARAM.PFD|*.pfd", "*.pfd")
    
            '**************************************************************************************************************************'
            '*                                                  READ PFD                                                              *'
            '**************************************************************************************************************************'
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the entire header into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[HEADER TABLE :: COMPLETE]" & vbCrLf)
            Dim PFD_HEADER_COMPLETE As Byte() = Read_PFD_Block(pfd_path, PFD_HEADER.OFFSET, PFD_HEADER.SIZE)
            rtbHex.AppendText(ByteArray_To_Hex(PFD_HEADER_COMPLETE, " ") & vbCrLf & vbCrLf)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the iv from the header into a byte array (used for decryption)
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[HEADER TABLE :: IV]" & vbCrLf)
            Dim PFD_HEADER_IV As Byte() = Read_PFD_Block(pfd_path, PFD_HEADER_SECTION.IV_OFFSET, PFD_HEADER_SECTION_SIZE.IV_SIZE)
            rtbHex.AppendText(ByteArray_To_Hex(PFD_HEADER_IV, " ") & vbCrLf & vbCrLf)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the signature from the header into a byte array (provides you with top/bottom hashes once decrypted)
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[HEADER TABLE :: SIGNATURE]" & vbCrLf)
            Dim PFD_HEADER_SIGNATURE As Byte() = Read_PFD_Block(pfd_path, PFD_HEADER_SECTION.SIGNATURE_OFFSET, PFD_HEADER_SECTION_SIZE.SIGNATURE_SIZE, True, PFD_HEADER_IV)
            rtbHex.AppendText(ByteArray_To_Hex(PFD_HEADER_SIGNATURE, " ") & vbCrLf & vbCrLf)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the decrypted top hash into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[HEADER TABLE :: DECRYPTED TOP HASH]" & vbCrLf)
            Dim PFD_HEADER_TOP_HASH As Byte() = Read_Decrypted_Header_Hash(PFD_HEADER_SIGNATURE, PFD_HEADER_SECTION.TOP_HASH_OFFSET)
            rtbHex.AppendText(ByteArray_To_Hex(PFD_HEADER_TOP_HASH, " ") & vbCrLf & vbCrLf)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the decrpted bottom hash into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[HEADER TABLE :: DECRYPTED BOTTOM HASH]" & vbCrLf)
            Dim PFD_HEADER_BOTTOM_HASH As Byte() = Read_Decrypted_Header_Hash(PFD_HEADER_SIGNATURE, PFD_HEADER_SECTION.BOTTOM_HASH_OFFSET)
            rtbHex.AppendText(ByteArray_To_Hex(PFD_HEADER_BOTTOM_HASH, " ") & vbCrLf & vbCrLf)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the entire hash table into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[HASH TABLE :: COMPLETE]" & vbCrLf)
            Dim HASH_TABLE_COMPLETE As Byte() = Read_PFD_Block(pfd_path, HASH_TABLE.OFFSET, HASH_TABLE.SIZE)
            rtbHex.AppendText(ByteArray_To_Hex(HASH_TABLE_COMPLETE, " ") & vbCrLf & vbCrLf)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the hash table header into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[HASH TABLE :: HEADER]" & vbCrLf)
            Dim HASH_TABLE_HEADER As Byte() = Read_PFD_Block(pfd_path, HASH_TABLE.HEADER_OFFSET, HASH_TABLE.HEADER_SIZE)
            rtbHex.AppendText(ByteArray_To_Hex(HASH_TABLE_HEADER, " ") & vbCrLf & vbCrLf)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read data from the hash table into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[HASH TABLE :: ENTRY]" & vbCrLf)
            Dim HASH_TABLE_DATA_CHUNK As List(Of Byte()) = Read_Hash_Table(pfd_path$, HASH_TABLE.ENTRY_OFFSET, HASH_TABLE.ENTRY_SIZE)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the hash table data
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To HASH_TABLE_DATA_CHUNK.Count - 1
                rtbHex.AppendText(ByteArray_To_Hex(HASH_TABLE_DATA_CHUNK(i), " ") & vbCrLf & vbCrLf)
    
                If i = HASH_TABLE_DATA_CHUNK.Count - 1 Then rtbHex.AppendText(vbCrLf)
            Next
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the entire protected files table into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[PROTECTED FILES TABLE :: COMPLETE]" & vbCrLf)
            Dim PF_TABLE_COMPLETE As Byte() = Read_PFD_Block(pfd_path, PF_TABLE.OFFSET, PF_TABLE.SIZE)
            rtbHex.AppendText(ByteArray_To_Hex(PF_TABLE_COMPLETE, " ") & vbCrLf & vbCrLf)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read data from the protected files table into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[PROTECTED FILES TABLE :: FILE NAME]" & vbCrLf)
            Dim PF_TABLE_DATA_CHUNK As List(Of Byte()) = Read_PF_Table(pfd_path$, PF_TABLE_SECTION.NAME, PF_TABLE_SECTION_SIZE.NAME)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the protected files table data
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To PF_TABLE_DATA_CHUNK.Count - 1
                rtbHex.AppendText(ByteArray_To_Hex(PF_TABLE_DATA_CHUNK(i), " ") & vbCrLf & vbCrLf)
    
                If i = PF_TABLE_DATA_CHUNK.Count - 1 Then rtbHex.AppendText(vbCrLf)
            Next
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the entire y table into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[Y TABLE :: COMPLETE]" & vbCrLf)
            Dim Y_TABLE_COMPLETE As Byte() = Read_PFD_Block(pfd_path, Y_TABLE.OFFSET, Y_TABLE.SIZE)
            rtbHex.AppendText(ByteArray_To_Hex(Y_TABLE_COMPLETE, " ") & vbCrLf & vbCrLf)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read data from the y table into a list of byte arrays
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[Y TABLE :: ENTRY]" & vbCrLf)
            Dim Y_TABLE_DATA_CHUNK As List(Of Byte()) = Read_Y_Table(pfd_path$, Y_TABLE.OFFSET, Y_TABLE.ENTRY_SIZE)
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Output the y table data
            '--------------------------------------------------------------------------------------------------------------------------'
            For i As Integer = 0 To Y_TABLE_DATA_CHUNK.Count - 1
                rtbHex.AppendText(ByteArray_To_Hex(Y_TABLE_DATA_CHUNK(i), " ") & vbCrLf & vbCrLf)
    
                If i = Y_TABLE_DATA_CHUNK.Count - 1 Then rtbHex.AppendText(vbCrLf)
            Next
    
            '--------------------------------------------------------------------------------------------------------------------------'
            ' Read the padding into a byte array
            '--------------------------------------------------------------------------------------------------------------------------'
            rtbHex.AppendText("[BOTTOM PADDING]" & vbCrLf)
            Dim PADDING As Byte() = Read_PFD_Block(pfd_path, BOTTOM_PADDING.OFFSET, BOTTOM_PADDING.SIZE)
            rtbHex.AppendText(ByteArray_To_Hex(PADDING, " ") & vbCrLf & vbCrLf)
        End Sub
    End Class
    C# Code
    Code:
    Add to a class:
    
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    
    static class clsGlobal
    {
        //**************************************************************************************************************************'
        //*                                             GLOBAL KEYS                                                                *'
        //**************************************************************************************************************************'
        public static byte[] SYSCON_MANAGER_KEY = new byte[] {
    		0xd4,
    		0x13,
    		0xb8,
    		0x96,
    		0x63,
    		0xe1,
    		0xfe,
    		0x9f,
    		0x75,
    		0x14,
    		0x3d,
    		0x3b,
    		0xb4,
    		0x56,
    		0x52,
    		0x74
    	};
        //**************************************************************************************************************************'
        //*                                      GLOBAL HEADER TABLE VARIABLES                                                     *'
        //**************************************************************************************************************************'
        public struct PFD_HEADER_SECTION
        {
            public const int MAGIC_OFFSET = 0x0;
            public const int VERSION_OFFSET = 0x8;
            public const int IV_OFFSET = 0x10;
            public const int SIGNATURE_OFFSET = 0x20;
            public const int TOP_HASH_OFFSET = 0x0;
            public const int BOTTOM_HASH_OFFSET = 0x14;
        }
        public struct PFD_HEADER_SECTION_SIZE
        {
            public const int MAGIC_SIZE = 8;
            public const int VERSION_SIZE = 8;
            public const int IV_SIZE = 16;
            public const int SIGNATURE_SIZE = 64;
            public const int HASH_SIZE = 20;
        }
        public struct PFD_HEADER
        {
            public const int OFFSET = 0x0;
            public const int SIZE = 96;
        }
        //**************************************************************************************************************************'
        //*                                      GLOBAL HASH TABLE VARIABLES                                                       *'
        //**************************************************************************************************************************'
        public struct HASH_TABLE
        {
            public const int OFFSET = 0x60;
            public const int SIZE = 456;
            public const int MAX_ENTRIES = 57;
            public const int HEADER_OFFSET = 0x60;
            public const int HEADER_SIZE = 24;
            public const int ENTRY_OFFSET = 0x78;
            public const int ENTRY_SIZE = 8;
        }
        //**************************************************************************************************************************'
        //*                                  GLOBAL PROTECTED FILES TABLE VARIABLES                                                *'
        //**************************************************************************************************************************'
        public struct PF_TABLE_SECTION
        {
            public const int INDEX = 0;
            public const int NAME = 8;
            public const int GARBAGE = 73;
            public const int DATA = 80;
            public const int ENTRY_KEY = 80;
            public const int HASHES = 144;
            public const int HASH1 = 144;
            public const int HASH2 = 164;
            public const int HASH3 = 184;
            public const int HASH4 = 204;
            public const int PADDING = 224;
            public const int FILE_SIZE = 264;
        }
        public struct PF_TABLE_SECTION_SIZE
        {
            public const int INDEX = 8;
            public const int NAME = 65;
            public const int GARBAGE = 7;
            public const int DATA = 192;
            public const int ENTRY_KEY = 64;
            public const int HASHES = 80;
            public const int HASH = 20;
            public const int PADDING = 40;
            public const int FILE_SIZE = 8;
        }
        public struct PF_TABLE
        {
            public const int OFFSET = 0x240;
            public const int SIZE = 31008;
            public const int MAX_ENTRIES = 113;
            public const int ENTRY_SIZE = 272;
        }
        //**************************************************************************************************************************'
        //*                                          GLOBAL Y TABLE VARIABLES                                                      *'
        //**************************************************************************************************************************'
        public struct Y_TABLE
        {
            public const int MAX_ENTRIES = 56;
            public const int OFFSET = 0x7b60;
            public const int SIZE = 1140;
            public const int ENTRY_SIZE = 20;
        }
        //**************************************************************************************************************************'
        //*                                          GLOBAL PADDING VARIABLES                                                      *'
        //**************************************************************************************************************************'
        public struct BOTTOM_PADDING
        {
            public const int OFFSET = 0x7fd4;
            public const int SIZE = 44;
        }
    }
    
    Add to a class:
    
    using System;
    using System.Windows.Forms;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    using System.Security.Cryptography;
    using glb = clsGlobal;
    
    static class clsClasses
    {
        //***************************************************************************************************************'
        //* OPEN FILE DIALOG BOX : RETURNS A STRING *'
        //***************************************************************************************************************'
        public static string File_Dialog(string sTitle, string sFilter, string sFileName)
        {
            OpenFileDialog OFD = new OpenFileDialog(); 
    
            String retval = string.Empty; 
    
            OFD.Filter = sFilter;
            OFD.InitialDirectory = Application.ExecutablePath;
            OFD.Title = sTitle;
            OFD.Filter = sFilter;
            OFD.FileName = sFileName;
    
            if (OFD.ShowDialog() == DialogResult.OK)
                {
                    retval =  OFD.FileName;
                }
            if (retval == String.Empty)
                {
                    return string.Empty;
                }
            else
                {
                    return retval;
                }
        }
    	//**************************************************************************************************************************'
    	//*                                              AES DECRYPTION FUNCTION                                                   *'
    	//**************************************************************************************************************************'
    	public static byte[] AES_Decrypt(byte[] bytes, int block_size, int key_size, byte[] aes_iv, byte[] aes_key)
    	{
    		//--------------------------------------------------------------------------------------------------------------------------'
    		// AES Crypto Service Provider
    		//--------------------------------------------------------------------------------------------------------------------------'
    		AesCryptoServiceProvider AES = new AesCryptoServiceProvider();
    		//--------------------------------------------------------------------------------------------------------------------------'
    		// AES Crypto Service Provider parameters
    		//--------------------------------------------------------------------------------------------------------------------------'
    		AES.BlockSize = block_size;
    		AES.KeySize = key_size;
    		AES.IV = aes_iv;
    		AES.Key = aes_key;
    		AES.Mode = CipherMode.CBC;
    		AES.Padding = PaddingMode.None;
    		//--------------------------------------------------------------------------------------------------------------------------'
    		// Decrypt the bytes : AES 128 CBC mode
    		//--------------------------------------------------------------------------------------------------------------------------'
    		using (ICryptoTransform AES_Dec = AES.CreateDecryptor()) {
    			byte[] dec_bytes = AES_Dec.TransformFinalBlock(bytes, 0, bytes.Length);
    			//--------------------------------------------------------------------------------------------------------------------------'
    			// Return the byte array of decrypted bytes
    			//--------------------------------------------------------------------------------------------------------------------------'
    			return dec_bytes;
    		}
    	}
        //***************************************************************************************************************'
        //*                              CONVERT A BYTE ARRAY TO A HEXADECIMAL STRING                                   *'
        //***************************************************************************************************************'
        public static string ByteArray_To_Hex(byte[] bytes, string separator = null)
        {
            string retval = string.Empty;
            StringBuilder strHex = new StringBuilder(bytes.Length * 2);
    
            foreach (byte b in bytes) {
                strHex.Append((b.ToString("X2")) + separator);
            }
    
            retval = strHex.ToString().ToUpper();
    
            return retval.Trim();
        }
    
    	//**************************************************************************************************************************'
    	//*                               READ DATA FROM HASH TABLE :: OUTPUT = LIST OF BYTE ARRAYS                                *'
    	//**************************************************************************************************************************'
    	public static List<byte[]> Read_Hash_Table(string pfd_file, int start_offset, int section_size)
    	{
    		List<byte[]> output_bytes = new List<byte[]>();
    		long curr_offset = start_offset;
    
            for (int i = 0; i <= glb.HASH_TABLE.MAX_ENTRIES; i++)
            {
    			byte[] chunk_bytes = new byte[section_size];
    
    			using (FileStream fs = new FileStream(pfd_file, FileMode.Open, FileAccess.Read)) {
    				fs.Seek(curr_offset, System.IO.SeekOrigin.Begin);
    				fs.Read(chunk_bytes, 0, section_size);
    				fs.Close();
    				fs.Dispose();
    			}
    
    			output_bytes.Add(chunk_bytes);
    
                curr_offset = curr_offset + glb.HASH_TABLE.ENTRY_SIZE;
    		}
    
    		return output_bytes;
    	}
    	//**************************************************************************************************************************'
    	//*                          READ DATA FROM PROTECTED FILES TABLE :: OUTPUT = LIST OF BYTE ARRAYS                          *'
    	//**************************************************************************************************************************'
    	public static List<byte[]> Read_PF_Table(string pfd_file, int start_offset, int section_size)
    	{
    		List<byte[]> output_bytes = new List<byte[]>();
    		long curr_offset = glb.PF_TABLE.OFFSET + start_offset;
    
    		for (int i = 0; i <= glb.PF_TABLE.MAX_ENTRIES; i++) {
    			byte[] chunk_bytes = new byte[section_size];
    
    			using (FileStream fs = new FileStream(pfd_file, FileMode.Open, FileAccess.Read)) {
    				fs.Seek(curr_offset, System.IO.SeekOrigin.Begin);
    				fs.Read(chunk_bytes, 0, section_size);
    				fs.Close();
    				fs.Dispose();
    			}
    
    			output_bytes.Add(chunk_bytes);
    
                curr_offset = curr_offset + glb.PF_TABLE.ENTRY_SIZE;
    		}
    
    		return output_bytes;
    	}
    	//**************************************************************************************************************************'
    	//*                                  READ DATA FROM Y TABLE :: OUTPUT = LIST OF BYTE ARRAYS                                *'
    	//**************************************************************************************************************************'
    	public static List<byte[]> Read_Y_Table(string pfd_file, int start_offset, int section_size)
    	{
    		List<byte[]> output_bytes = new List<byte[]>();
    		long curr_offset = start_offset;
    
    		for (int i = 0; i <= glb.Y_TABLE.MAX_ENTRIES; i++) {
    			byte[] chunk_bytes = new byte[section_size];
    
    			using (FileStream fs = new FileStream(pfd_file, FileMode.Open, FileAccess.Read)) {
    				fs.Seek(curr_offset, System.IO.SeekOrigin.Begin);
    				fs.Read(chunk_bytes, 0, section_size);
    				fs.Close();
    				fs.Dispose();
    			}
    
    			output_bytes.Add(chunk_bytes);
    
    			curr_offset = curr_offset + glb.Y_TABLE.ENTRY_SIZE;
    		}
    
    		return output_bytes;
    	}
    	//**************************************************************************************************************************'
    	//*                          READ PFD FILE FROM OFFSET TO SPECIFIED BLOCK SIZE :: OUTPUT = BYTE ARRAY                      *'
    	//**************************************************************************************************************************'
    	public static byte[] Read_PFD_Block(string pfd_file, int start_offset, int section_size, bool decrypt_output = false, byte[] IV = null)
    	{
    		byte[] output_bytes = new byte[section_size];
    
    		using (FileStream fs = new FileStream(pfd_file, FileMode.Open, FileAccess.Read)) {
    			fs.Seek(start_offset, System.IO.SeekOrigin.Begin);
    			fs.Read(output_bytes, 0, section_size);
    			fs.Close();
    			fs.Dispose();
    		}
    
    		if (decrypt_output == true) {
    			if (IV == null)
    				goto Err_IV;
    
                output_bytes = AES_Decrypt(output_bytes, 128, 128, IV, glb.SYSCON_MANAGER_KEY);
    		}
    
    		return output_bytes;
    		Err_IV:
    
    		return null;
    	}
    	//**************************************************************************************************************************'
    	//*                          READ THE TOP/BOTTOM HASH FROM DECRYPTED HEADER :: OUTPUT = BYTE ARRAY                         *'
    	//**************************************************************************************************************************'
    	public static byte[] Read_Decrypted_Header_Hash(byte[] decrypted_header_array, int offset)
    	{
            byte[] output_array = new byte[glb.PFD_HEADER_SECTION_SIZE.HASH_SIZE];
    
            Buffer.BlockCopy(decrypted_header_array, offset, output_array, 0, glb.PFD_HEADER_SECTION_SIZE.HASH_SIZE);
    
    		return output_array;
    	}
    
    }
    
    Add to a form with a ritch text box (name = rtbHex) and a button (name = cmdReadPFD):
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using clsGlb = clsGlobal;
    using clsClass = clsClasses;
    
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            private void cmdReadPFD_Click(object sender, EventArgs e)
            {
                rtbHex.Text = null;
    
                //**************************************************************************************************************************'
                //*                                             LOAD :: PARAM.PFD                                                          *'
                //**************************************************************************************************************************'
                OpenFileDialog OFD = new OpenFileDialog();
                //--------------------------------------------------------------------------------------------------------------------------'
                // String to hold the return value of the open file dialog
                //--------------------------------------------------------------------------------------------------------------------------'
                string pfd_path = clsClass.File_Dialog("Open PARAM.PFD", "Playstation 3 - PARAM.PFD|*.pfd", "*.pfd");
    
                //**************************************************************************************************************************'
                //*                                                  READ PFD                                                              *'
                //**************************************************************************************************************************'
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the entire header into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[HEADER TABLE :: COMPLETE]" + Environment.NewLine);
                byte[] PFD_HEADER_COMPLETE = clsClass.Read_PFD_Block(pfd_path, clsGlb.PFD_HEADER.OFFSET, clsGlb.PFD_HEADER.SIZE);
                rtbHex.AppendText(clsClass.ByteArray_To_Hex(PFD_HEADER_COMPLETE, " ") + Environment.NewLine + Environment.NewLine);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the iv from the header into a byte array (used for decryption)
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[HEADER TABLE :: IV]" + Environment.NewLine);
                byte[] PFD_HEADER_IV = clsClass.Read_PFD_Block(pfd_path, clsGlb.PFD_HEADER_SECTION.IV_OFFSET, clsGlb.PFD_HEADER_SECTION_SIZE.IV_SIZE);
                rtbHex.AppendText(clsClass.ByteArray_To_Hex(PFD_HEADER_IV, " ") + Environment.NewLine + Environment.NewLine);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the signature from the header into a byte array (provides you with top/bottom hashes once decrypted)
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[HEADER TABLE :: SIGNATURE]" + Environment.NewLine);
                byte[] PFD_HEADER_SIGNATURE = clsClass.Read_PFD_Block(pfd_path, clsGlb.PFD_HEADER_SECTION.SIGNATURE_OFFSET, clsGlb.PFD_HEADER_SECTION_SIZE.SIGNATURE_SIZE, true, PFD_HEADER_IV);
                rtbHex.AppendText(clsClass.ByteArray_To_Hex(PFD_HEADER_SIGNATURE, " ") + Environment.NewLine + Environment.NewLine);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the decrypted top hash into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[HEADER TABLE :: DECRYPTED TOP HASH]" + Environment.NewLine);
                byte[] PFD_HEADER_TOP_HASH = clsClass.Read_Decrypted_Header_Hash(PFD_HEADER_SIGNATURE, clsGlb.PFD_HEADER_SECTION.TOP_HASH_OFFSET);
                rtbHex.AppendText(clsClass.ByteArray_To_Hex(PFD_HEADER_TOP_HASH, " ") + Environment.NewLine + Environment.NewLine);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the decrpted bottom hash into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[HEADER TABLE :: DECRYPTED BOTTOM HASH]" + Environment.NewLine);
                byte[] PFD_HEADER_BOTTOM_HASH = clsClass.Read_Decrypted_Header_Hash(PFD_HEADER_SIGNATURE, clsGlb.PFD_HEADER_SECTION.BOTTOM_HASH_OFFSET);
                rtbHex.AppendText(clsClass.ByteArray_To_Hex(PFD_HEADER_BOTTOM_HASH, " ") + Environment.NewLine + Environment.NewLine);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the entire hash table into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[HASH TABLE :: COMPLETE]" + Environment.NewLine);
                byte[] HASH_TABLE_COMPLETE = clsClass.Read_PFD_Block(pfd_path, clsGlb.HASH_TABLE.OFFSET, clsGlb.HASH_TABLE.SIZE);
                rtbHex.AppendText(clsClass.ByteArray_To_Hex(HASH_TABLE_COMPLETE, " ") + Environment.NewLine + Environment.NewLine);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the hash table header into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[HASH TABLE :: HEADER]" + Environment.NewLine);
                byte[] HASH_TABLE_HEADER = clsClass.Read_PFD_Block(pfd_path, clsGlb.HASH_TABLE.HEADER_OFFSET, clsGlb.HASH_TABLE.HEADER_SIZE);
                rtbHex.AppendText(clsClass.ByteArray_To_Hex(HASH_TABLE_HEADER, " ") + Environment.NewLine + Environment.NewLine);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read data from the hash table into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[HASH TABLE :: ENTRY]" + Environment.NewLine);
                List<byte[]> HASH_TABLE_DATA_CHUNK = clsClass.Read_Hash_Table(pfd_path, clsGlb.HASH_TABLE.ENTRY_OFFSET, clsGlb.HASH_TABLE.ENTRY_SIZE);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the hash table data
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= HASH_TABLE_DATA_CHUNK.Count - 1; i++)
                {
                    rtbHex.AppendText(clsClass.ByteArray_To_Hex(HASH_TABLE_DATA_CHUNK[i], " ") + Environment.NewLine + Environment.NewLine);
    
                    if (i == HASH_TABLE_DATA_CHUNK.Count - 1)
                        rtbHex.AppendText(Environment.NewLine);
                }
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the entire protected files table into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[PROTECTED FILES TABLE :: COMPLETE]" + Environment.NewLine);
                byte[] PF_TABLE_COMPLETE = clsClass.Read_PFD_Block(pfd_path, clsGlb.PF_TABLE.OFFSET, clsGlb.PF_TABLE.SIZE);
                rtbHex.AppendText(clsClass.ByteArray_To_Hex(PF_TABLE_COMPLETE, " ") + Environment.NewLine + Environment.NewLine);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read data from the protected files table into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[PROTECTED FILES TABLE :: FILE NAME]" + Environment.NewLine);
                List<byte[]> PF_TABLE_DATA_CHUNK = clsClass.Read_PF_Table(pfd_path, clsGlb.PF_TABLE_SECTION.NAME, clsGlb.PF_TABLE_SECTION_SIZE.NAME);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the protected files table data
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= PF_TABLE_DATA_CHUNK.Count - 1; i++)
                {
                    rtbHex.AppendText(clsClass.ByteArray_To_Hex(PF_TABLE_DATA_CHUNK[i], " ") + Environment.NewLine + Environment.NewLine);
    
                    if (i == PF_TABLE_DATA_CHUNK.Count - 1)
                        rtbHex.AppendText(Environment.NewLine);
                }
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the entire y table into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[Y TABLE :: COMPLETE]" + Environment.NewLine);
                byte[] Y_TABLE_COMPLETE = clsClass.Read_PFD_Block(pfd_path, clsGlb.Y_TABLE.OFFSET, clsGlb.Y_TABLE.SIZE);
                rtbHex.AppendText(clsClass.ByteArray_To_Hex(Y_TABLE_COMPLETE, " ") + Environment.NewLine + Environment.NewLine);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read data from the y table into a list of byte arrays
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[Y TABLE :: ENTRY]" + Environment.NewLine);
                List<byte[]> Y_TABLE_DATA_CHUNK = clsClass.Read_Y_Table(pfd_path, clsGlb.Y_TABLE.OFFSET, clsGlb.Y_TABLE.ENTRY_SIZE);
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Output the y table data
                //--------------------------------------------------------------------------------------------------------------------------'
                for (int i = 0; i <= Y_TABLE_DATA_CHUNK.Count - 1; i++)
                {
                    rtbHex.AppendText(clsClass.ByteArray_To_Hex(Y_TABLE_DATA_CHUNK[i], " ") + Environment.NewLine + Environment.NewLine);
    
                    if (i == Y_TABLE_DATA_CHUNK.Count - 1)
                        rtbHex.AppendText(Environment.NewLine);
                }
    
                //--------------------------------------------------------------------------------------------------------------------------'
                // Read the padding into a byte array
                //--------------------------------------------------------------------------------------------------------------------------'
                rtbHex.AppendText("[BOTTOM PADDING]" + Environment.NewLine);
                byte[] PADDING = clsClass.Read_PFD_Block(pfd_path, clsGlb.BOTTOM_PADDING.OFFSET, clsGlb.BOTTOM_PADDING.SIZE);
                rtbHex.AppendText(clsClass.ByteArray_To_Hex(PADDING, " ") + Environment.NewLine + Environment.NewLine);
            }
        }
    }
    When reading the protected files table (Read_PF_Table function) you can specify what you want to read out of it by pointing to another value in the PF_TABLE_SECTION structure, just be sure to also point to the correct data size for the value in the PF_TABLE_SECTION_SIZE structure.

    Reads each file name (in hexadecimal, you could convert this to any encoding type you want for display purposes):
    Code:
    Dim PF_TABLE_DATA_CHUNK As List(Of Byte()) = Read_PF_Table(pfd_path$, PF_TABLE_SECTION.NAME, PF_TABLE_SECTION_SIZE.NAME)
    Reads all 4 file hashes:
    Code:
    Dim PF_TABLE_DATA_CHUNK As List(Of Byte()) = Read_PF_Table(pfd_path$, PF_TABLE_SECTION.HASHES, PF_TABLE_SECTION_SIZE.HASHES)
    Depending on what you are reading, data is either stored in a byte array, or a list of byte arrays. If the data is in a list of byte arrays and you want to simply read a specific item from the array, do not loop through the list just output the byte array at the index within the list that you want:
    Code:
    ByteArray_To_Hex(PF_TABLE_DATA_CHUNK(7), " ")
    In all reality, unless you are wanting to display the data, you should leave it in a byte array and work with it from there due to potential loss of data (encoding types), and speed. I have some other code some may find useful but it is on my other pc, I'll post it later on.

  6. #56
    Junior Member boxbundy's Avatar
    Join Date
    Aug 2012
    Posts
    29
    sorry for dumb questions. what do you use this for? how do we use/enter cheats for games. I have zero experience with this on PS3 can we enter cheats from ps3usercheat by using hex editing? or any other way? (I don't have a dongle)

    please can someone give me some detailed advice because I haven't seen much clear detailed info on this that I can actually understand
    how are you all doing this exactly? please enlighten me I'm using rebug 4.21

  7. #57
    Member BerserkLeon's Avatar
    Join Date
    Feb 2011
    Posts
    69
    well the only game i want to try to use it on, the save file id key is unknown. I've gotten as far as decrypting the eboot to try to find the key, but brute-forcing it is going rather slowly. BLES01396/BLES01765.

    the cheats that are applied directly to the eboot wouldn't be the same cheats that you could apply to the save game.

    Easiest things you can do with unprotected save data is: use someone else's save as your own. modify your save data with save editors.

    if there's not a save editor for the game you want to edit, you have to go in with a hex editor and look for what you want to change.

  8. #58
    Junior Member boxbundy's Avatar
    Join Date
    Aug 2012
    Posts
    29
    can someone please point me to a cheat tutorial or can someone at least help me with an answer?

  9. #59
    Forum Moderator PS3 News's Avatar
    Join Date
    Apr 2005
    Posts
    26,896

    Video: PS3 Save Resigner Homebrew Application by K.G 971 Out

    Following up on the PS3 Save Game Tools Pack by Flat_z, today PlayStation 3 developer K.G 971 has released a PS3 Save Resigner and updates below that allow the resigning of game save files for retail OFW or on CFW from any regions and any accounts.

    Download: PS3 Save Resigner Homebrew Application / PS3 Save Resigner Homebrew Application (Mirror) / PS3 Save Resigner v1.1 Homebrew Application / PS3 Save Resigner v1.3 Homebrew Application / PS3 Save Resigner v1.4 Homebrew Application / PS3 Save Resigner v1.4 Homebrew Application (Mirror) / .NET Framework 4 (Required)

    To quote: Hi guys this is a PS3 save resigner. Thanks to flat_z for his amazing work. The games.conf is from aldostool. This is just for people who needs an easier way to use flat_z's tool. Credit goes to flat_z for his pfdtool.

    You can resign any saves from any regions to any regions. From any accounts to any accounts. You can also remove the copy-protection.

    It's easy to use, and very user-friendly. It works for Retail PS3. All you have to do is search for the keys on Internet (watch the video).

    Updates: PS3 Save Resigner v1.1 homebrew application is now available (linked above) and includes the following updates:
    • added an option for modders: Decrypt the entire game save folder. It decrypts the game save folder for you, then it waits for you to mod what you want in it, and then it recrypts and resigns it.

    How it works:

    Follow the video exept that instead of clicking "resign", you will click decrypt. Then , once you are done modding, click "Encrypt & Resign". Done. You can still select the first way if you are not planning to mod the file, just hit "Resign".

    PS3 Save Resigner 1.3 Changelog:
    • Added some features
    • Added "Copy params of a specified game" option: To all those who were getting corruption errors (Tekken ect..), this version may fix them.
    • Make sure to select the "Copy params of a specified game" option, and load the PARAM.SFO of your version of the game that you try to resign a save to.
    • Decrypt option updated: When you decrypt a game save folder, it's now in the folder "Decrypted Save Folders".
    • Attempt to fix the XP problem.

    PS3 Save Resigner 1.4 Changelog:
    • Fixed Windows XP problems. Now it works for everyone. BIG thanks to RuiGR for his great help.

    Note: the games.conf is updated regularly by aldostools, so i will update the new file each times in the "dropbox folder". You will have to replace the old one by the updated one in the tool's folder.








    Public Keys:
    • syscon_manager_key=D413B89663E1FE9F75143D3BB456527 4
    • keygen_key=6B1ACEA246B745FD8F93763B920594CD53483B8 2
    • savegame_param_sfo_key=0C08000E090504040D010F00040 6020209060D03
    • fallback_disc_hash_key=D1C1E10B9C547E689B805DCD971 0CE8D








    How to Use Someone Else's PS3 Game Save Guide - Liberating Your PS3 Game Save from gingerbread:

    Method 1 - Pseudo Save Resigning

    Step 1: You have to be on CFW to perform these steps. Open PARAM.SFO in any Hex Editor (i.e HxD, Hex Workshop, Ultra Edit and etc.). It does not matter which hex editor you use because all can represent data in raw and have copy/paste/find options which are sufficient.

    Step 2: The "Account ID" which identifies Your user account and PSN. The Account ID always starts at (0x140) and always have 16 bytes and the length is 10.

    Step 3: Replace it with your values and you have to do it twice. First at 0x140. The second offset address is somewhere in the file. Use Search and use the original value to perform a search and replace it. The address of 2nd "Account ID" is constant only with the same game save title, it's different for different games.



    Step 4: The Second ID is "console id" which identifies Your console (don't mislead it with IDPS). It also have 16 bytes and also is not on constant offset.



    Step 5: Third ID is user number account (for example: for "dev_hdd0/home/00000001/" will be 01)). In the example above, it is 48. There are in two position that 48 is.

    Step 6: You can't simply copy back your save using XMB. It will most likely give you an error. You have to FTP back to your save folder and overwrite the files.

    Note: The method works most of the time but could result in corrupted saves. If the game is design to regenerate a new save, it usually creates a new working save.

    Method 2 - Fake Save Data Owner

    Info: Only available in Debug FW or Rebug's CFW.



    Info: Allows use of save data from other users and displays a warning message at every load/save during the game. Once a save data has been saved with this features activated, that save couldn't be read with this function deactivated.

    Off: deactivate the Fake Save Data Owner function.

    On: activate the Fake Save Data Owner function.

    Note: There is a notification of the "Caution: Fake Save Data Owner On" every-time when any game is saving. It can be very annoying.

    Method 3 - Changing Your PS3's Console ID. WARNING: May cause RSOD if done wrongly.

    Step 1: Use FTP to transfer a file name xRegistry.sys from your CFW PS3 to your PC (located at /dev_flash2/etc/)
    Step 2: Useing Hex Editor application to open a file named PARAM.SFO from any of your save data. Go to offset 140 you'll see your PSN account serial in a 16 digits format, copy that 16 digits and paste it somewhere (notepad or something). Look at Method 1.
    Step 3: Open xRegistry.sys with the xRegistry editor (I recommend you to BACKUP the file before you edit it)


    Step 4: Now you have to edit the following fields:
    Code:
    /setting/user/(account number)/npaccount/accountid === add your 16 digits PSN account serial here
    /setting/user/(account number)/npaccount/loginid === your PSN email here
    /setting/user/(account number)/npaccount/password === your PSN password here
    /setting/user/(account number)/ytaccount/password === your PSN password here
    /setting/user/(account number)/net/onlineFlag === if this value is 00000000, change it to 00000001
    Step 5: Save the file and FTP it back to your CFW PS3.

    Note: Now you suppose to be able to share your save data (that locked to PSN ID) between the 2 PS3s like they're the same machine. You can also hack the game with cheat PKG or other solutions on CFW PS3 and then transfer the save to OFW PS3 and continue collecting trophies with hacked saves.

    Method 4 - PS3 Save Resigner by K.G (100% Real Save Resigning)

    Download: PS3 Save Resigner Homebrew Application by K.G 971

    Method 5 - PS3 Bruteforce Save Data by Aldostools (100% Real Save Resigning)

    Download: aldostools.org/temp/BruteforceSaveData.rar

    For Resigning PS3 Save Data

    Step 1: Edit the global.conf and enter your console_id. (Ctrl+H)
    Step 2: Click "Set PARAM.SFO as Template" and Select "Configure Profiles" and Pick a Profile from 1 - 5
    Step 3: A Dialog Box will appear, Select "PARAM.SFO" from your save.
    Step 4: Give a Name For your Profile.
    Step 5: Bulit PARAM.SFO from template (Ctrl+B)

    For Decrypting/Encrypting PS3 Save Data

    Step 1: Edit the global.conf and enter your console_id. (Ctrl+H)
    Step 2: Copy a PARAM.SFO with your account_id as template.sfo in the folder of Bruteforce Save Data (Ctrl+T)
    Step 3: Scan the folder with the saves (the Key should be listed).
    Step 4: If the key is not available, double click on the save and select the EBOOT.ELF to bruteforce the key (use the scetool commands above to extract the ELF)
    Step 5: Once you have the secure_file_id for your game, select the following command in that order:
    Step 5a: Update Account ID and Copy Parameters
    Step 5b: Patch SFO: Remove Copy Protection
    Step 5c: Decrypt PFD
    Step 5d: Update PFD
    Step 5e: Encrypt PFD
    Step 5f: Verify PFD

    The buttons are placed in that order... so it is easy to select:

    Update Account ID -> Patch SFO -> Decrypt PFD -> Update PFD -> Encrypt PFD -> Verify PFD

    Method 6 - Game Genie: Save Editor for PS3 (100% Real Save Resigning)

    Commercial method: Game Genie for PS3 (thegamegenie.com/ps3/ -and- forum.thegamegenie.com/viewforum.php?f=8) is a save editor. The main function of this product is to modify your saves. There is also a secondary function to Resign your someone else's save and make it yours. It even works for copy-protected saves (You need CFW).

    Method 7 - Xploder PS3 Ultimate Cheats System

    Commercial method: xploder.net/playstation-3/products/244/Xploder-PS3-Ultimate-Cheats-System.htm

    From JeoWay comes a PS3 Save Resigner by K.G Tutorial, as follows:

    Hello! To start off, all tools and programs are linked at the end. REQUIRES .Net Framework 4 and msvr100.dll !!!

    1) Open up the Save Resigner.
    2) In the tabs, go to "Customized Profile Settings"
    3) Go the options to "Enter Public Keys"
    4) Enter in the Public Keys into the Correct Lines.

    PUBLIC KEYS
    Code:
    syscon_manager_key= D413B89663E1FE9F75143D3BB4565274
    keygen_key= 6B1ACEA246B745FD8F93763B920594CD53483B82
    savegame_param_sfo_key= 0C08000E090504040D010F000406020209060D03
    fallback_disc_hash_key= D1C1E10B9C547E689B805DCD9710CE8D
    5) Press "Save Keys" (So you don't have to enter on startup)
    6) Copy over *YOUR* save data from the PS3.
    7) Locate "Enter Private Keys".
    8) Either enter the values in yourself or load YOUR param.sfo from YOUR Save.
    9) Now click save Profile (As either 01, 02, or 03)
    10) On the tabs, go back to "Save Resigner"
    11) Go to File > Open > Locate Modded Save Data
    12) After mod save is loaded, you can change region by editing the Game ID.
    13) (Don't edit the Console, Account, or User ID's)
    14) Now select a profile to resign to.
    15) Either decrypt the save and then edit and re-encrypt and resign OR...
    16) Simply click "Resign" and use it.
    17) Sometimes it still says corrupt after resign so you need to copy params.

    FIXING CORRUPT ISSUES

    1) Check the box of copy params of a specific game.
    2) If you get an error, you need to install msvr100.dll (Link Below)
    3. Now select "Resign", and it MAY fix the corrupt issue.

    (I have had this problem with Sound Shapes Game Save)

    DOWNLOAD LINKS

    Finally, Flat_z has also Tweeted (twitter.com/flat_z/status/294371165760274432) that he has reversed the whole PS3 emu encryption, stating: ps2_netemu (config, .enc, virtual memory cards cryptography) pwned

    Video: PS3 Save Resigner Homebrew Application by K.G 971 Out

    Video: PS3 Save Resigner Homebrew Application by K.G 971 Out

    More PlayStation 3 News...
    Attached Images<br><br> Attached Images


  10. #60
    Senior Member smokyyuwe's Avatar
    Join Date
    Sep 2011
    Posts
    113
    Your saves on your PS3 are encrypted, this is meant to unencrypted them. There is not a whole lot of information on how to "cheat" with an unencrypted save because it is still a somewhat new area.

 


 
Page 6 of 10 FirstFirst ... 45678 ... LastLast