Editing Package Files

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

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

Latest revision Your text
Line 7: Line 7:


   typedef struct {
   typedef struct {
     uint32_t pkg_magic;                     // 0x000 - 0x7F434E54
     uint32_t pkg_magic;         // 0x000
     uint32_t pkg_type;                       // 0x004
     uint16_t pkg_revision;      // 0x004
     uint32_t pkg_0x008;                     // 0x008 - unknown field
    uint16_t pkg_type;           // 0x006
     uint32_t pkg_file_count;                 // 0x00C
     uint32_t pkg_unk;           // 0x008 - unknown field
     uint32_t pkg_entry_count;               // 0x010
     uint32_t pkg_file_count;     // 0x00C
     uint16_t pkg_sc_entry_count;             // 0x014
     uint32_t pkg_table_ents;     // 0x010
     uint16_t pkg_entry_count_2;             // 0x016 - same as pkg_entry_count
     uint16_t pkg_sys_ents;       // 0x014
     uint32_t pkg_table_offset;               // 0x018 - file table offset
     uint16_t pkg_unk;           // 0x016 - unknown field
     uint32_t pkg_entry_data_size;            // 0x01C
     uint32_t pkg_table_offset;   // 0x018 - file table offset
     uint64_t pkg_body_offset;               // 0x020 - offset of PKG entries
     uint32_t pkg_ent_data_size;  // 0x01C
     uint64_t pkg_body_size;                 // 0x028 - length of all PKG entries
    uint32_t pkg_unk;            // 0x020 - unknown field
     uint64_t pkg_content_offset;             // 0x030
     uint32_t pkg_body_offset;   // 0x024 - seems to always be 0x200
     uint64_t pkg_content_size;               // 0x038
     uint32_t pkg_body_unk;       // 0x028 - unknown field
     uint32_t pkg_body_size;     // 0x02C<br>
     unsigned char pkg_padding[0x10];         // 0x030 - 16 bytes padding
     unsigned char pkg_content_id[0x24];      // 0x040 - packages' content ID as a 36-byte string
     unsigned char pkg_content_id[0x24];      // 0x040 - packages' content ID as a 36-byte string
     unsigned char pkg_padding[0xC];         // 0x064 - padding
     unsigned char pkg_padding[0x10];         // 0x064 - 16 bytes padding
     uint32_t pkg_drm_type;                  // 0x070 - DRM type
     unsigned char pkg_unknown[0x8C];         // 0x074 - unknown data<br>
    uint32_t pkg_content_type;               // 0x074 - Content type
    uint32_t pkg_content_flags;              // 0x078 - Content flags
    uint32_t pkg_promote_size;              // 0x07C
    uint32_t pkg_version_date;              // 0x080
    uint32_t pkg_version_hash;              // 0x084
    uint32_t pkg_0x088;                      // 0x088
    uint32_t pkg_0x08C;                      // 0x08C
    uint32_t pkg_0x090;                      // 0x090
    uint32_t pkg_0x094;                      // 0x094
    uint32_t pkg_iro_tag;                    // 0x098
    uint32_t pkg_drm_type_version;          // 0x09C
    <br>
     /* Digest table */
     /* Digest table */
     unsigned char digest_entries1[0x20];    // 0x100 - sha256 digest for main entry 1
     unsigned char digest_entries1[0x20];    // 0x100 - sha256 digest for main entry 1
Line 40: Line 30:
     unsigned char digest_table_digest[0x20]; // 0x140 - sha256 digest for digest table
     unsigned char digest_table_digest[0x20]; // 0x140 - sha256 digest for digest table
     unsigned char digest_body_digest[0x20];  // 0x160 - sha256 digest for main table
     unsigned char digest_body_digest[0x20];  // 0x160 - sha256 digest for main table
    // ...
   }
    uint32_t pfs_image_count;                // 0x404 - count of PFS images
    uint64_t pfs_image_flags;                // 0x408 - PFS flags
    uint64_t pfs_image_offset;              // 0x410 - offset to start of external PFS image
    uint64_t pfs_image_size;                // 0x418 - size of external PFS image
    uint64_t mount_image_offset;            // 0x420
    uint64_t mount_image_size;              // 0x428
    uint64_t pkg_size;                      // 0x430
    uint32_t pfs_signed_size;                // 0x438
    uint32_t pfs_cache_size;                // 0x43C
    unsigned char pfs_image_digest[0x20];    // 0x440
    unsigned char pfs_signed_digest[0x20];  // 0x460
    uint64_t pfs_split_size_nth_0;          // 0x480
    uint64_t pfs_split_size_nth_1;          // 0x488
    // ...
    unsigned char pkg_digest[0x20];          // 0xFE0
   } pkg_header;                              // 0x1000


=== Files ===
=== Files ===
The file table is a list of file entries:
The file table contains a pointer to a list of files in a package file when the package is of "CNT" magic, this pointer can be found as a 32-bit unsigned integer at 0x2B30. File names are separated by null bytes, and packages typically contain the following files:
 
  typedef struct {
    uint32_t id;              // File ID, useful for files without a filename entry
    uint32_t filename_offset;  // Offset into the filenames table (ID 0x200) where this file's name is located
    uint32_t flags1;          // Flags including encrypted flag, etc
    uint32_t flags2;          // Flags including encryption key index, etc
    uint32_t offset;          // Offset into PKG to find the file
    uint32_t size;            // Size of the file
    uint64_t padding;          // blank padding
  } pkg_table_entry;
 
Some of the files listed in the table with filenames include:


  param.sfo - contains information critical to the app / game
  param.sfo - contains information critical to the app / game
Line 83: Line 45:
  icon0.png - small icon
  icon0.png - small icon
  icon1.png - large icon
  icon1.png - large icon
There are also files without plaintext filenames. These are identified by their ID in the file entry table.
== PFS ==
Main article: [[PFS]] ''(only explains un-encrypted, un-signed PFS)''
The main portion of a PKG file is its signed and encrypted PFS image. It is encrypted with XTS-AES with a block size of 0x1000. The key is derived from the HMAC-SHA256 of the concatenation of "0x01 0x00 0x00 0x00" in and the EKPFS. The HMAC key is the "crypt seed" which is at offset 0x370 in the PFS itself. The tweak key is the first 16 bytes of the HMAC result, while the data key is the second 16 bytes.
The PFS image in a PKG is different from the decrypted image exposed by the system in <code>/mnt/sandbox/pfsmnt/CUSA00001-app0-nest/pfs_image.dat</code>. This image uses <code>dinode_s32</code>, the signed inode variant, which includes a 32-byte signature for every direct and indirect block. Additionally, the indirect block blocks also have a 32-byte signature for each block within.
Inside the PFS image in a PKG is a single file: <code>pfs_image.dat</code> which is a special type of compressed PFS image with a <code>PFSC</code> header. Inside <code>pfs_image.dat</code> is where the actual game/theme/DLC data lives.


== Delivery ==
== Delivery ==
Line 170: Line 121:
'''Source:''' https://boerse.to/thema/datenbank-fuer-ps4-psn-links.1979635/
'''Source:''' https://boerse.to/thema/datenbank-fuer-ps4-psn-links.1979635/


See also: [[Package Files/Raw List 1]], [[Package Files/Raw List 2]]
See also: [[PKG_files/rawlist1]], [[PKG_files/rawlist2]]


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

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

Cancel Editing help (opens in new window)