From bbe33581c782d1bf80c6ecbe2d56b9381583178a Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Tue, 31 Jan 2023 11:44:05 +0200 Subject: [PATCH] pkgextract toll : print partially pkg header --- .gitignore | 2 + tools/pkg extractor/PKG.cpp | 3 +- tools/pkg extractor/PKG.h | 77 +++++++++++++++++++++++++++++- tools/pkg extractor/pkgextract.cpp | 37 ++++++++------ 4 files changed, 101 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 824716cf..ba8935de 100644 --- a/.gitignore +++ b/.gitignore @@ -398,3 +398,5 @@ FodyWeavers.xsd *.sln.iml /shadPS4/game/* /shadPS4/psf.txt +/tools/pkg extractor/game/* +/tools/pkg extractor/*.pkg diff --git a/tools/pkg extractor/PKG.cpp b/tools/pkg extractor/PKG.cpp index 3b439b93..a55d92b6 100644 --- a/tools/pkg extractor/PKG.cpp +++ b/tools/pkg extractor/PKG.cpp @@ -18,7 +18,6 @@ bool PKG::open(const std::string& filepath) { return false; } pkgSize = file.getFileSize(); - PKGHeader pkgheader; file.ReadBE(pkgheader); //we have already checked magic should be ok @@ -39,7 +38,7 @@ bool PKG::extract(const std::string& filepath, const std::string& extractPath, s return false; } pkgSize = file.getFileSize(); - PKGHeader pkgheader; + file.ReadBE(pkgheader); if (pkgheader.pkg_size > pkgSize) diff --git a/tools/pkg extractor/PKG.h b/tools/pkg extractor/PKG.h index ea8f810f..d0faf765 100644 --- a/tools/pkg extractor/PKG.h +++ b/tools/pkg extractor/PKG.h @@ -4,6 +4,7 @@ #include #include #include +#include struct PKGHeader { /*BE*/U32 magic;// Magic @@ -69,10 +70,19 @@ struct PKGHeader { inline void ReadBE(PKGHeader& s) { ReadBE(s.magic); - ReadBE(s.pkg_table_entry_offset); + ReadBE(s.pkg_type); + ReadBE(s.pkg_0x8); + ReadBE(s.pkg_file_count); ReadBE(s.pkg_table_entry_count); + ReadBE(s.pkg_sc_entry_count); + ReadBE(s.pkg_table_entry_count_2); + ReadBE(s.pkg_table_entry_offset); + ReadBE(s.pkg_sc_entry_data_size); + ReadBE(s.pkg_body_offset); + ReadBE(s.pkg_body_size); ReadBE(s.pkg_content_offset); ReadBE(s.pkg_content_size); + ReadBE(s.pfs_image_offset); ReadBE(s.pfs_image_size); ReadBE(s.pkg_size); @@ -106,6 +116,7 @@ private: U64 pkgSize = 0; S08 pkgTitleID[9]; std::string extractPath; + PKGHeader pkgheader; public: PKG(); @@ -197,5 +208,69 @@ public: return entry_name; } + void printPkgHeader() + { + printf("PS4 PKG header:\n"); + printf("- PKG magic: 0x%X\n", pkgheader.magic); + printf("- PKG type: 0x%X\n", pkgheader.pkg_type); + printf("- PKG 0x8: 0x%X\n", pkgheader.pkg_0x8); + printf("- PKG file count: 0x%X\n", pkgheader.pkg_file_count); + printf("- PKG table entries: 0x%X\n", pkgheader.pkg_table_entry_count); + printf("- PKG system entries: 0x%X\n", pkgheader.pkg_sc_entry_count); + printf("- PKG table entries2: 0x%X\n", pkgheader.pkg_table_entry_count_2); + printf("- PKG table offset: 0x%X\n", pkgheader.pkg_table_entry_offset); + printf("- PKG table entry data size: 0x%X\n", pkgheader.pkg_sc_entry_data_size); + printf("- PKG body offset: 0x%" PRIx64 "\n", pkgheader.pkg_body_offset); + printf("- PKG body size: 0x%" PRIx64 "\n", pkgheader.pkg_body_size); + printf("- PKG content offset: 0x%" PRIx64 "\n", pkgheader.pkg_content_offset); + printf("- PKG conteít size: 0x%" PRIx64 "\n", pkgheader.pkg_content_offset); + printf("- PKG pkg_content_id: %s\n", pkgheader.pkg_content_id); + printf("\n\n"); + +// U08 pkg_content_id[0x24];//packages' content ID as a 36-byte string +// U08 pkg_padding[0xC];//padding +// /*BE*/U32 pkg_drm_type;//DRM type +// /*BE*/U32 pkg_content_type;//Content type +// /*BE*/U32 pkg_content_flags;//Content flags +// /*BE*/U32 pkg_promote_size; +// /*BE*/U32 pkg_version_date; +// /*BE*/U32 pkg_version_hash; +// /*BE*/U32 pkg_0x088; +// /*BE*/U32 pkg_0x08C; +// /*BE*/U32 pkg_0x090; +// /*BE*/U32 pkg_0x094; +// /*BE*/U32 pkg_iro_tag; +// /*BE*/U32 pkg_drm_type_version; + +// U08 pkg_zeroes_1[0x60]; + + /* Digest table */ +// U08 digest_entries1[0x20]; // sha256 digest for main entry 1 +// U08 digest_entries2[0x20]; // sha256 digest for main entry 2 +// U08 digest_table_digest[0x20]; // sha256 digest for digest table +// U08 digest_body_digest[0x20]; // sha256 digest for main table + +// U08 pkg_zeroes_2[0x280]; + +// U32 pkg_0x400; + +// U32 pfs_image_count; // count of PFS images +// U64 pfs_image_flags; // PFS flags +// U64 pfs_image_offset; // offset to start of external PFS image +// U64 pfs_image_size; // size of external PFS image +// U64 mount_image_offset; +// U64 mount_image_size; +// U64 pkg_size; +// U32 pfs_signed_size; +// U32 pfs_cache_size; +// U08 pfs_image_digest[0x20]; +// U08 pfs_signed_digest[0x20]; +// U64 pfs_split_size_nth_0; +// U64 pfs_split_size_nth_1; + +// U08 pkg_zeroes_3[0xB50]; + +// U08 pkg_digest[0x20]; */ + } }; diff --git a/tools/pkg extractor/pkgextract.cpp b/tools/pkg extractor/pkgextract.cpp index 17a2481f..84bf3a18 100644 --- a/tools/pkg extractor/pkgextract.cpp +++ b/tools/pkg extractor/pkgextract.cpp @@ -1,20 +1,27 @@ -// pkgextract.cpp : This file contains the 'main' function. Program execution begins and ends there. -// - #include - +#include +#include +#include "PKG.h" int main() { - std::cout << "Hello World!\n"; + PKG pkg; + if (!pkg.open("test.pkg")) + { + std::cout << "Error reading test.pkg\n"; + return 0; + } + pkg.printPkgHeader(); + std::string gamedir = "game/" + pkg.getTitleID(); + struct stat sb; + if (stat(gamedir.c_str(), &sb) != 0) + { + _mkdir(gamedir.c_str()); + } + std::string extractpath = "game/" + pkg.getTitleID() + "/"; + std::string failreason; + if (!pkg.extract("test.pkg", extractpath, failreason)) + { + std::cout << "Error extraction " << failreason; + } } -// Run program: Ctrl + F5 or Debug > Start Without Debugging menu -// Debug program: F5 or Debug > Start Debugging menu - -// Tips for Getting Started: -// 1. Use the Solution Explorer window to add/manage files -// 2. Use the Team Explorer window to connect to source control -// 3. Use the Output window to see build output and other messages -// 4. Use the Error List window to view errors -// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project -// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file