PKG files

From PS3 Developer wiki
Jump to navigation Jump to search

See also Discussion page

Firmware Packages

File Header

All values are in big endian format.

 typedef struct {
   u32 0x00, 0x53434500// magic
   u32 0x04, 2		// version
   u16 0x08, 0		// sdk type?
   u16 0x0a, 3		// SCE header type; pkg
   u32 0x0c, 0		// meta offset
   u64 0x10,           // size of sce_hdr + sizeof meta_hdr
   u64 0x18, 0x80      // + content_size_real
 }

Game Packages

All game packages are signed with the ECDSA signature. The public key for it can be found in download_plugin.prx or in nas_plugin.prx (this also applies to NPDRM SELFs). Usually game packages are signed with two signatures - one for the header and the other for the entry table.

File Header

Example from a retail PS3 .pkg

  • Example: Scott Pilgrim VS. The World Unlock .pkg file:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000  7F 50 4B 47 80 00 00 01 00 00 00 C0 00 00 00 08  .PKGЂ......А....
00000010  00 00 00 C0 00 00 00 02 00 00 00 00 00 00 17 C0  ...А...........А
00000020  00 00 00 00 00 00 01 80 00 00 00 00 00 00 15 E0  .......Ђ.......а
00000030  55 50 30 30 30 31 2D 4E 50 55 42 33 30 31 36 32  UP0001-NPUB30162
00000040  5F 30 30 2D 53 43 4F 54 54 50 49 4C 47 52 49 4D  _00-SCOTTPILGRIM
00000050  30 30 30 32 00 00 00 00 00 00 00 00 00 00 00 00  0002............
00000060  09 8B A2 CA 2D 30 30 1F 8B 5B 82 79 C6 70 35 F3  .‹ўК-00.‹[‚yЖp5у
00000070  D5 FA 15 9E 7F AC 82 70 BB 3E 0C EB 97 3D 30 11  Хъ.ћ.¬‚p»>.л—=0.
00000080  48 0D 86 60 9F 26 8E 7F 4F B4 DA A4 33 1E 9A A1  H.†`џ&Ћ.OґЪ¤3.љЎ
00000090  0C 85 45 95 A8 D4 A3 9B 62 44 68 C1 38 CE D7 63  .…E•ЁФЈ›bDhБ8ОЧc
000000A0  0D FF 0C C5 3A 77 C6 E6 E4 62 AD 05 F3 93 D0 7A  .я.Е:wЖждb..у“Рz
000000B0  CC 02 B4 35 2B 70 47 D6 EC 61 40 39 A6 5B DC BD  М.ґ5+pGЦмa@9¦[ЬЅ

PKG header

Name Offset Size Example Remark
magic 0x00 0x04 7F 50 4B 47 '.PKG'
pkg_revision 0x04 0x02 80 00 80 00 for retail (finalized), 00 00 for debug (non finalized)
pkg_type 0x06 0x02 00 01 00 01 for PS3, 00 02 for PSP and PSVita
pkg_metadata_offset 0x08 0x04 00 00 00 C0 0xC0, usually 0x280 for PSP and PSVita
pkg_metadata_count 0x0C 0x04 00 00 00 08 item count
pkg_metadata_size 0x10 0x04 00 00 00 C0 usually 0xC0 for PSP and PS3, usually 0x160 for PSVita
item_count 0x14 0x04 00 00 00 02 files and folders into the encrypted data
total_size 0x18 0x08 00 00 00 00 00 00 17 C0 0x17C0 - total pkg file size
data_offset 0x20 0x08 00 00 00 00 00 00 01 80 0x0180 - encrypted data offset
data_size 0x28 0x08 00 00 00 00 00 00 15 E0 0x15E0 - encrypted data size
contentid 0x30 0x24 "UP0001-NPUB30162_00-SCOTTPILGRIM0002" PKG Content ID
padding 0x54 0x0C 00 00 00 00 00 00 00 00 00 00 00 00 0x0C bytes padding
digest 0x60 0x10 09 8B A2 CA 2D 30 30 1F 8B 5B 82 79 C6 70 35 F3 sha1 from debug files and attributes together merged in one block
pkg_data_riv 0x70 0x10 D5 FA 15 9E 7F AC 82 70 BB 3E 0C EB 97 3D 30 11 aes-128-ctr iv. Used with gpkg_key to decrypt data.
header_cmac_hash 0x80 0x10 48 0D 86 60 9F 26 8E 7F 4F B4 DA A4 33 1E 9A A1 CMAC OMAC hash from 0x00-0x7F. PS3 gpkg_key used as key.
header_npdrm_signature 0x90 0x28 PKG header NPDRM ECDSA (R_sig, S_sig)
header_sha1_hash 0xB8 0x08 EC 61 40 39 A6 5B DC BD last 8 bytes of sha1 hash of 0x00-0x7F


All values are in big endian format.

 typedef struct {
   u32 magic;
   u16 pkg_revision;
   u16 pkg_type;
   u32 pkg_metadata_offset;
   u32 pkg_metadata_count;
   u32 pkg_metadata_size;
   u32 item_count;
   u64 total_size;
   u64 data_offset;
   u64 data_size;
   u8 contentid[0x30];
   u8 digest[0x10];
   u8 pkg_data_riv[0x10];
   u8 header_cmac_hash[0x10];
   u8 header_npdrm_signature[0x28];
   u8 header_sha1_hash[0x8];
 } PKG_HEADER;

PKG Metadata

 typedef struct {
  union{
   u32 packet_identifier; // 0-0x12
   u32 data_size;
   {
    data
   }
  } ...
  // u8 padding[variable];
  u8 unknown[0x40];
 } PKG_METADATA;
Identifier category name Possible size Possible values
0x1 DRM Type 4 0/5/6/7/8/9/0xA/0xB/0xC (unknown), 0x1 (network), 0x2 (local), 0x3 (DRMfree no license), 0x4 (PSP), 0xD (DRMfree with license), 0xE (PSM)
0x2 Content Type 4 00 00 00 07
0x3 PKG_files#PackageType / PKG_files#PackageFlag / PKG_files#StorageType (PSVita) 4
0x4 Package Size 8 00 00 00 00 0E 77 40 00
0x5 make_package_npdrm Revision (2 bytes) + Package Version (2 bytes) 4 09 60 00 00 (960, 0.00), 12 03 00 00 (1203, 0.00), 12 12 00 00 (1212, 0.00), 12 73 01 01 (1273, 1.01), 19 53 01 00 (1953, 1.00), 19 63 01 00, 19 66 01 00, 19 72 01 02 (1972, 1.02)
0x6 Version + App Version / TitleID (on size 0xC) 0xC "NPEG00005\0\0\0"
0x7 QA Digest (described as "This is a digest of packaged files and attributes.") 0x18 00 00 00 00 00 00 00 00 B5 76 E1 D9 00 EE 9B BC 8E 24 17 91 5D BC 5A CB
0x8 unk (1 byte) + PS3/PSP/PSP2 System Version (3 bytes) + Package Version + App Version 8 00 00 00 00 00 00 00 00, 00 00 00 00 01 00 01 00, 44 01 70 00 01 01 00 00, 81 01 90 00 01 00 01 00, 81 04 75 00 01 02 01 00 (4.7500, 1.02, 1.00) --> 44 maybe PSP and 80/81 PS3
0x9 unk 8 either 00 00 00 00 00 00 00 00 or 00 00 00 00 00 24 00 00
0xA InstallDirectory 0x28 8 zeroed bytes + directory: ........UCES01264_FANTASY...............
0xB unk seen in PSP cumulative patch 0x8 00 00 00 00 00 00 00 01
0xC unk
0xD ?ECDSA sig (or hash)? 0x28 always 6 zeroed chars at the beginning

00 00 00 00 00 00 05 A0 18 8B B1 8A E5 E8 40 FD EE 71 E2 27 60 55 E6 39 06 94 5B 65 89 04 B2 88 61 DA BB A3 B2 55 C5 C1

0xE PARAM.SFO Info 0x38 00 00 0C 10 00 00 05 0C 00 00 00 14 01 67 00 00 00 00 00 00 00 00 00 00 FC 3D 1E 32 FA F7 A6 11 90 46 A6 34 BE 98 9A 78 65 A8 92 25 3C 49 D7 69 73 53 32 E7 8E 06 1E 60
0xF unknown_data0_info 0x48 00 00 05 60 00 00 03 20 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 0F 26 BD 5C 2F 13 95 EB 16 E6 62 07 8D 9A E3 DC 0B AC 25 11 1C 19 39 B9 40 06 4E 82 AF 1E C3

00 00 06 10 00 00 03 20 00 00 01 F4 00 00 01 F7 00 00 00 00 01 01 01 01 A5 74 D5 71 00 03 00 01 00 00 00 00 00 00 00 00 79 52 B2 3F 78 3B 9D F4 C0 BB 26 C0 EC 14 1B 37 8B 9B 69 71 1C 22 C3 49 57 97 B6 DE 78 0A D0 00

0x10 Entirety Info 0x38 00 00 0A 00 00 00 00 A0 D3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 4D AD EB 44 67 51 C1 2D 69 95 46 8C 82 A9 3D 74 AD F4 62 49 90 BD EE F0 75 97 A3 B6 5B 17 48

00 00 0A B0 00 00 01 60 FF D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D2 7F 9E EF 38 F7 61 6E C1 C5 CC B1 E1 83 12 0C 6F 38 4C 8C 22 84 8B A4 3B 7B 47 57 77 C9 F9 C9

0x11 PublishingTools version (4 Bytes) + PFSBuilder version (4 Bytes) + padding (0x20 Bytes) 0x28 01 60 00 00 00 06 23 47 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

02 07 00 00 00 07 60 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0x12 unknown_data2_info (points to a 0x10 bytes buffer) 0x38 00 00 11 20 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CF 74 D5 30 04 99 F0 57 E8 65 20 5C 3D 71 12 36 F1 E4 EF BC 98 EA 52 F1 F0 60 E8 7C 8A 53 B8 A4

ContentType

content type type name install path (on ps3) notes
0x00000001
0x00000002
0x00000003
0x00000004 GameData (also patches) /dev_hdd0/game/
0x00000005 GameExec /dev_hdd0/game/
0x00000006 PS1emu /dev_hdd0/game/
0x00000007 PSP & PCEngine /dev_hdd0/game/
0x00000008
0x00000009 Theme /dev_hdd0/theme
0x0000000A Widget /dev_hdd0/widget
0x0000000B License /dev_hdd0/home/<current user>/exdata
0x0000000C VSHModule /dev_hdd0/vsh/modules/
0x0000000D PSN Avatar /dev_hdd0/home/<current user>/psn_avatar
0x0000000E PSPgo /dev_hdd0/game/ Displayed as Unknown Album: Corrupted Data
0x0000000F minis /dev_hdd0/game/
0x00000010 NEOGEO /dev_hdd0/game/
0x00000011 VMC /dev_hdd0/tmp/vmc/
0x00000012 ?PS2Classic? Seen on PS2 classic /dev_hdd0/game/
0x00000013
0x00000014 Seen on PSP remastered /dev_hdd0/game/
0x00000015 PSP2GD (PSVita Game Data)
0x00000016 PSP2AC (PSVita Additional Content)
0x00000017 PSP2LA (PSVita LiveArea)
0x00000018 ?PSM? (PSVita PSM)
0x00000019 WT (Web TV?) /dev_hdd0/game/
0x0000001D ?PSM? (PSVita PSM)
0x0000001F PSP2Theme (PSVita Theme)

PackageType

Identifier type name usage notes
unk Patch for PSP game updates, to use with CumulativePatch, IncrementalPatch, HybridPatch
unk DiscGamePatch for PS3 BD games
unk HDDGamePatch for PS3 HDD games (NPDRM)
unk NoEBOOTBIN
unk Demo
unk Key
unk Upgradable

To class : DiscBinded, NonGame

PackageFlag

Identifier type name usage notes
unk RenameDirectory
unk NoRenameDirectory
unk Finalized
unk CumulativePatch Embeds the previous patches to use with Patch StorageType
unk IncrementalPatch Requires the previous patches to be installed first to use with Patch StorageType
unk HybridPatch to use with Patch StorageType

StorageType

Seams to be PSVita only.

Identifier type name usage notes
unk VC-MC
unk VC-VC

package.conf

Config name usage expected value example
ContentID needed XXYYYY-XXXXYYYYY_00-XXXXXXXXXXXXXXXX EP4153-NPEZ00314_00-0000111122223333
Klicensee needed (can be set to 0x00000...) 0x00000000000000000000000000000000 0x1234567899876543210123456789CE4D
DRMType needed Network / Free / Local Free
ContentType needed See PKG_files#ContentType minis
PackageType See PKG_files#PackageType DiscGamePatch
PackageFlag See PKG_files#PackageFlag RenameDirectory
StorageType needed for PSVita gamedata See PKG_files#StorageType VC-MC
PackageVersion X.XX 1.02
TitleID used only for PSP and PS1 games XXXXYYYYY NPEZ00314
LimitedTimeStart YYYY-MM-DDThh:mmTZD 2018-10-30T11:55T32
LimitedTimeEnd YYYY-MM-DDThh:mmTZD 2019-10-30T11:55T32
InstallDirectory used in PSP patches ? UCUS98744_LBPPDLCSONYPA002
ForcedInstallTo Allows installing packages to any hdd directory (and even flash memory if it's mounted RW).

PARAM_SFO_info

 typedef struct { // size is 0x38
   u32 param_offset;
   u16 param_size;
   u32 unk_int; // ex: 0x2, 0x14, 0x4, 0x9
   u32 PSP2_DISP_VER; // or may be PSP2_SYSTEM_VER
   u8 unk[0x8];
   u8 param_digest[0x20]; // SHA256 of param_data. Called ParamDigest: This is sha256 digest of param.sfo.
 } PARAM_SFO_info;

unknown_data0_info

 typedef struct { // size is 0x48
   u32 unknown_data_offset;
   u16 unknown_data_size; // ex: 0x320
   u8 unk[0x20];
   u8 unknown_data_sha256[0x20];
 } unknown_data0_info;

entirety_info

 typedef struct { // size is 0x38
   u32 entirety_data_offset; // located just before SFO
   u32 entirety_data_size; // ex: 0x160, 0x100 in SDK
   u32 unk_int1; // ex: FE 10 00 00, FF D0 00 00, maybe ELF flag or PKG header size + 0xE
   u32 unk_int2; // ex: 1, 0
   u8 unk[0x8];
   u8 entirety_digest[0x20]; // SHA256 of entirety_data. Called EntiretyDigest: This is a digest of above digests.
 } entirety_info;
 typedef struct { // size is 0x100
   u8 unk_digest[0x20]; // ????
   u8 game_digest[0x20]; // ?SHA256? of ??. Called GameDigest: This is a digest of Header/Program/System/MajorParam Digests.
   u8 program_digest[0x20]; // ?SHA256? of ??. Called ProgramDigest: This is a digest of contents except sce_sys files.
   u8 system_digest[0x20]; // ?SHA256? of ??. Called SystemDigest: This is a digest of sce_sys files except param.sfo.
   u8 majorparam_digest[0x20]; // ?SHA256? of ??. Called MajorParamDigest: This is a digest of param.sfo that affect behavior.
   u8 param_digest[0x20]; // SHA256 of param.sfo. Called ParamDigest: This is sha256 digest of param.sfo.
   u8 header_digest[0x20]; // ?SHA256? of ??. Called HeaderDigest: This is a digest of package header.
   u8 others_digest[0x20]; // ?SHA256? of ??. Called OthersDigest: This is a digest of sce_sys files except above files.
 } entirety_data_100;
 typedef struct { // size is 0x160
   u8 unk_digest[0x20]; // ???? May be an encrypted form of the not found: # ContentDigest: This is a digest of content unique value.
   u8 game_digest[0x20]; // SHA256 of a buffer embedding Program/System/MajorParam/Header Digests in this order. Called GameDigest: This is a digest of Header/Program/System/MajorParam Digests.
   u8 program_digest[0x20]; // ?SHA256? of ??. Called ProgramDigest: This is a digest of contents except sce_sys files.
   u8 system_digest[0x20]; // ?SHA256? of ??. Called SystemDigest: This is a digest of sce_sys files except param.sfo.
   u8 majorparam_digest[0x20]; // ?SHA256? of ??. Called MajorParamDigest: This is a digest of param.sfo that affect behavior.
   u8 param_digest[0x20]; // SHA256 of param.sfo. Called ParamDigest: This is sha256 digest of param.sfo.
   u8 header_digest[0x20]; // ?SHA256? of ??. Called HeaderDigest: This is a digest of package header.
   u8 livearea_digest[0x20]; // ?SHA256? of ??. Called LiveareaDigest: This is a digest of sce_sys/livearea(&retail) files.
   u8 manual_digest[0x20]; // ?SHA256? of ??. Called ManualDigest: This is a digest of sce_sys/manual files.
   u8 trophy_digest[0x20]; // ?SHA256? of ??. Called TrophyDigest: This is a digest of sce_sys/trophy files.
   u8 others_digest[0x20]; // ?SHA256? of ??. Called OthersDigest: This is a digest of sce_sys files except above files.
 } entirety_data_160;

unknown_data2_info

 typedef struct { // size is 0x38
   u32 unknown_data_offset;
   u32 unknown_data_size; // usually 0x10
   u8 unk[0x10];
   u8 unknown_data_sha256[0x20];
 } unknown_data2_info;

File Entry

All values are in big endian format.

 typedef struct {
   u32 filename_offset;
   u32 filename_size;
   u64 data_offset;
   u64 data_size;
   u32 flags;
   u32 padding;
 } PKG_FILE_HEADER;
field offset type notes
filename_offset 0x0 u32
filename_size 0x4 u32
data_offset 0x8 u64
data_size 0x10 u64
flags 0x18 u32 The file type
padding 0x1C u32 zero

Misc/Note

From FW 4.00, install PKG from root device (but not as "bubble") for PS1 classic if not containing .EDAT files license type Free will abort or install directly as bubble according to the cfw.

File Footer

PackageDigest

This is SHA1 digest of package without last 32 bytes.

The last 0x20 bytes of the package contains a hash (sha1sum) of the package (sha1 of the whole file minus the last 0x20 bytes). Or in other words... to verify the integrity of a package is needed to crop the 0x20 bytes at the end, then calculate the SHA1 of the resulting file, then compare with the SHA1 that was cropped.

It is also used as part of the package identification info inside the TITLE_ID-ver.xml files in PSN servers that lists the available game patches for each game. See: Game Updating Procedure page and the sha1sum in the .xml examples

  • Notes
    • This footer area is considered part of the package and is included when counting the total_size of the package (in the header at offset 0x18), and the header is hashed too by header_sha1_hash (at offset 0xB8), this is important in the sequence of actions needed when building the package and updating/adding the sha1 footer at the end
    • Homebrew packages (at least some of them) doesnt includes this footer

Package Tools

PKG builder / infos / extractor

PSVita SDK official tool : make_pkg (2011-2015)

  • latest version: rev 1972 from 3.55 PSVita SDK

PS3 SDK official tool : make_package_npdrm (2006-2017)

  • latest version: rev 1972 from 4.75 PS3 SDK
  • common version: rev 1732 from 3.40 PS3 SDK (also found under patched form)

Make Package Npdrm Patcher (revision 1732) by SubZero Dezigns (2012)

A tool that patches official make_package_npdrm.exe (revision 1732) in order to remove its protections to build packages that embeds NPDRM already encrypted SELFs.

Make Edata/Package NPDRM GUI by SubZero Dezigns (2012)

A GUI program for Windows that patches on-the-fly official make_package_npdrm.exe (revision 1732) and allows to configure package.conf.

Force Package NPDRM by DEL1GHT Team (2010)

FORCE_PACKAGE_NPDRM is a modded version of SONY's "MAKE_PACKAGE_NPDRM".

It enables the repackaging of DRM'ed games into a .PKG file.

Howto :

First create the following structure :

* PARAM.SFO

* ICON0.PNG

* ...

* TROPDIR

* USRDIR

* Original EBOOT.BIN renamed to whatever you want (ie. GAME.BIN)

* YOUR EBOOT.BIN (SELF file)

* ...

Your EBOOT.BIN must launch the original EBOOT.BIN (ie. GAME.BIN)

Usage : force_package_npdrm [options] config-file target-directory

11/08/10 - V1.00 - Initial Release

- Based on SONY's "MAKE_PACKAGE_NPDRM Rev. 1203"

- "Extended" help with "--help" option

- Packaging of your SELF EBOOT.BIN

- Repackaging of SELF/SPRX/EDATA DRM'ed files

11/11/10 - V1.50 - Updates

- Based on SONY's "MAKE_PACKAGE_NPDRM Rev. 1732"

- Repackaging of SDATA DRM'ed files

- Repackaging of TROPHY directory

PSN Package NPDRM by DEL1GHT Team (2010)

PSN_PACKAGE_NPDRM is a fork of FORCE_PACKAGE_NPDRM.

It rebuilds PSN DRM'ed games into a .PKG file.

Original DRM'ed EBOOT.BIN is packaged as "raw data" ;-)

Still the problem of licence (act.dat) to run the game on another PS3.

Howto :

Download the PSN game directory from your HDD0 to your PC.

Create a "config-file" (a lot of explanations on internet).

Usage : psn_package_npdrm [options] config-file target-directory

11/11/10 - V1.00 - Initial Release

- Based (fork) on FORCE_PACKAGE_NPDRM V1.50

- Full repackaging of PSN games

PKG extractor

ungpkg by failoverflow (2010)

PS3/PSP .pkg

PkgView by Ifcaro (2012-2013)

PS3/PSP .pkg

PkgDecrypt by St4rk (2017)

PSVita .pkg

Package links

  • sqlite3 db of .pkg files (pkg links, file infos, signatures, etc): pkg_harvester_db.7z 6.7 MB (includes PS3, PSP) - uncompressed pkg_harvester.db: 24.5 MB

several constants used in pkg_harvester.db:

enum class ProductEnvironment
{
	kUnknown = 0,
	kNP      = 1,
	kPQA     = 2,
	kPMGMT   = 3,
	kSPINT   = 4,
};

enum class PackageType
{
	kUnknown = 0,
	kPS3     = 1,
	kPSP     = 2,
};

enum class FileType
{
	kUnknown = 0,
	kSelf    = 1,
	kSprx    = 2,
	kEdata   = 3,
	kSdata   = 4,
};

enum class DRMLicenseType
{
	kUnknown = 0,
	kNetwork = 1,
	kLocal   = 2,
	kFree    = 3,
};