Exemplo n.º 1
0
 /// <summary>
 /// Sets up the PKG header, body, and PFS images
 /// </summary>
 private void InitPkg()
 {
     // Write PFS first, to get stream length
     Logger("Preparing inner PFS...");
     innerPfs = new PFS.PfsBuilder(PFS.PfsProperties.MakeInnerPFSProps(project), x => Logger($" [innerpfs] {x}"));
     Logger("Preparing outer PFS...");
     outerPfs = new PFS.PfsBuilder(PFS.PfsProperties.MakeOuterPFSProps(project, innerPfs, EKPFS), x => Logger($" [outerpfs] {x}"));
     Logger("Preparing PKG header and body...");
     BuildPkg(outerPfs.CalculatePfsSize());
 }
Exemplo n.º 2
0
 /// <summary>
 /// Sets up the PKG header, body, and PFS images
 /// </summary>
 private void InitPkg()
 {
     if (project.VolumeType == GP4.VolumeType.pkg_ps4_ac_nodata)
     {
         Logger("Preparing PKG header and body...");
         BuildPkg(0);
     }
     else
     {
         // Write PFS first, to get stream length
         Logger("Preparing inner PFS...");
         innerPfs = new PFS.PfsBuilder(PFS.PfsProperties.MakeInnerPFSProps(project), x => Logger($" [innerpfs] {x}"));
         Logger("Preparing outer PFS...");
         outerPfs = new PFS.PfsBuilder(PFS.PfsProperties.MakeOuterPFSProps(project, innerPfs, EKPFS), x => Logger($" [outerpfs] {x}"));
         Logger("Preparing PKG header and body...");
         BuildPkg(outerPfs.CalculatePfsSize());
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// Writes your PKG to the given stream.
        /// Assumes exclusive use of the stream (writes are absolute, relative to 0)
        /// </summary>
        /// <param name="s"></param>
        /// <returns>Completed Pkg structure</returns>
        public Pkg Write(Stream s)
        {
            var pkg    = BuildPkg();
            var writer = new PkgWriter(s);

            // Write PFS first, to get stream length
            s.Position = (long)pkg.Header.pfs_image_offset;
            var EKPFS     = Crypto.ComputeKeys(project.volume.Package.ContentId, project.volume.Package.Passcode, 1);
            var pfsStream = new OffsetStream(s, s.Position);

            Console.WriteLine("Preparing inner PFS...");
            var innerPfs = new PFS.PfsBuilder(PFS.PfsProperties.MakeInnerPFSProps(project, projectDir), x => Console.WriteLine($"[innerpfs] {x}"));

            Console.WriteLine("Preparing outer PFS...");
            var outerPfs = new PFS.PfsBuilder(PFS.PfsProperties.MakeOuterPFSProps(project, innerPfs, EKPFS), x => Console.WriteLine($"[outerpfs] {x}"));

            outerPfs.WriteImage(pfsStream);

            // Update header sizes now that we know how big things are...
            UpdateHeaderInfo(pkg, s.Length, pfsStream.Length);
            pkg.Header.body_size = pkg.Header.pfs_image_offset - pkg.Header.body_offset;

            // Set PFS Image 1st block and full SHA256 hashes (mount image)
            pkg.Header.pfs_signed_digest = Crypto.Sha256(s, (long)pkg.Header.pfs_image_offset, 0x10000);
            pkg.Header.pfs_image_digest  = Crypto.Sha256(s, (long)pkg.Header.pfs_image_offset, (long)pkg.Header.pfs_image_size);

            if (pkg.ParamSfo.ParamSfo.GetValueByName("PUBTOOLINFO") is SFO.Utf8Value v)
            {
                v.Value +=
                    $",img0_l0_size={pfsStream.Length / (1000 * 1000)}" +
                    $",img0_l1_size=0" +
                    $",img0_sc_ksize=512" +
                    $",img0_pc_ksize=832";
            }
            // TODO: Generate hashes in Entries (body)
            var majorParamString =
                "ATTRIBUTE" + pkg.ParamSfo.ParamSfo.GetValueByName("ATTRIBUTE") +
                "CATEGORY" + pkg.ParamSfo.ParamSfo.GetValueByName("CATEGORY") +
                "FORMAT" + pkg.ParamSfo.ParamSfo.GetValueByName("FORMAT") +
                "PUBTOOLVER" + pkg.ParamSfo.ParamSfo.GetValueByName("PUBTOOLVER");

            pkg.GeneralDigests.Set(GeneralDigest.MajorParamDigest,
                                   Crypto.Sha256(Encoding.ASCII.GetBytes(majorParamString)));
            using (var ms = new MemoryStream())
            {
                ms.Write(Encoding.ASCII.GetBytes(pkg.Header.content_id), 0, 36);
                ms.Write(new byte[12], 0, 12);
                ms.WriteInt32BE((int)pkg.Header.drm_type);
                ms.WriteInt32BE((int)pkg.Header.content_type);

                if (pkg.Header.content_type == ContentType.AC ||
                    pkg.Header.content_type == ContentType.GD ||
                    pkg.Header.content_flags.HasFlag(ContentFlags.GD_AC))
                {
                    ms.Write(pkg.Header.pfs_image_digest, 0, 32);
                }
                ms.Write(pkg.GeneralDigests.Digests[GeneralDigest.MajorParamDigest], 0, 32);
                pkg.GeneralDigests.Set(GeneralDigest.ContentDigest, Crypto.Sha256(ms));
            }
            pkg.GeneralDigests.Set(GeneralDigest.GameDigest, pkg.Header.pfs_image_digest);
            using (var ms = new MemoryStream())
            {
                new PkgWriter(ms).WriteHeader(pkg.Header);
                using (var hash = System.Security.Cryptography.SHA256.Create())
                {
                    ms.Position = 0;
                    hash.TransformBlock(ms.ReadBytes(64), 0, 64, null, 0);
                    ms.Position = 0x400;
                    hash.TransformFinalBlock(ms.ReadBytes(128), 0, 128);
                    pkg.GeneralDigests.Set(GeneralDigest.HeaderDigest, hash.Hash);
                }
            }
            pkg.GeneralDigests.Set(GeneralDigest.ParamDigest, Crypto.Sha256(pkg.ParamSfo.ParamSfo.Serialize()));
            pkg.ImageKey.FileData = Crypto.RSA2048EncryptKey(RSAKeyset.FakeKeyset.Modulus, EKPFS);

            // Write body now because it will make calculating hashes easier.
            writer.WriteBody(pkg, project.volume.Package.ContentId, project.volume.Package.Passcode);

            CalcHeaderHashes(pkg, s);

            // Now write header
            s.Position = 0;
            writer.WritePkg(pkg);

            // Pkg Signature
            byte[] header_sha256 = Crypto.Sha256(s, 0, 0x1000);
            s.Position = 0x1000;
            s.Write(Crypto.RSA2048EncryptKey(Keys.PkgSignKey, header_sha256), 0, 256);

            return(pkg);
        }