示例#1
0
 public void TestReadBackLicenseDat()
 {
     using (var s = File.OpenRead(pkgFile.Path))
     {
         var pkg = new PkgReader(s).ReadPkg();
         Assert.IsNotNull(pkg.LicenseDat);
     }
 }
示例#2
0
        private void darkButton1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog savepath = new FolderBrowserDialog();

            if (savepath.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    var numbersAndWords = idEntryList.Zip(nameEntryList, (n, w) => new { id = n, name = w });
                    foreach (var nw in numbersAndWords)
                    {
                        var pkgPath = filenames;
                        var idx     = int.Parse(nw.id);
                        var name    = nw.name;
                        var outPath = savepath.SelectedPath + "\\" + name.Replace("_SHA", ".SHA").Replace("_DAT", ".DAT").Replace("_SFO", ".SFO").Replace("_XML", ".XML").Replace("_SIG", ".SIG").Replace("_PNG", ".PNG").Replace("_JSON", ".JSON").Replace("_DDS", ".DDS").Replace("_TRP", ".TRP").Replace("_AT9", ".AT9");;

                        using (var pkgFile = File.OpenRead(pkgPath))
                        {
                            var pkg = new PkgReader(pkgFile).ReadPkg();
                            if (idx < 0 || idx >= pkg.Metas.Metas.Count)
                            {
                                DarkMessageBox.ShowError("Error: entry number out of range", "PS4 PKG Tool");
                                return;
                            }
                            using (var outFile = File.Create(outPath))
                            {
                                var meta = pkg.Metas.Metas[idx];
                                outFile.SetLength(meta.DataSize);
                                if (meta.Encrypted)
                                {
                                    if (passcode == null)
                                    {
                                        DarkMessageBox.ShowWarning("Warning: Entry is encrypted but no passcode was provided! Saving encrypted bytes.", "PS4 PKG Tool");
                                    }
                                    else
                                    {
                                        var entry = new SubStream(pkgFile, meta.DataOffset, (meta.DataSize + 15) & ~15);
                                        var tmp   = new byte[entry.Length];
                                        entry.Read(tmp, 0, tmp.Length);
                                        tmp = LibOrbisPkg.PKG.Entry.Decrypt(tmp, pkg.Header.content_id, passcode, meta);
                                        outFile.Write(tmp, 0, (int)meta.DataSize);
                                        return;
                                    }
                                }
                                new SubStream(pkgFile, meta.DataOffset, meta.DataSize).CopyTo(outFile);
                            }
                        }
                    }

                    DarkMessageBox.ShowInformation("All entry item extracted", "PS4 PKG Tool");
                }
                catch (Exception a)
                {
                    DarkMessageBox.ShowError(a.Message, "PS4 PKG Tool");
                }
            }
        }
示例#3
0
        public void Validate()
        {
            using (var pkgFile = new MemoryStream())
            {
                new PkgBuilder(TestHelper.MakeProperties()).Write(pkgFile, s => { });

                var pkg = new PkgReader(pkgFile).ReadPkg();
                foreach (var v in new PkgValidator(pkg).Validate(pkgFile))
                {
                    Assert.IsTrue(v.Item2 == PkgValidator.ValidationResult.Ok, v.Item1.Name);
                }
            }
        }
示例#4
0
        public void Validate()
        {
            using (var pkgFile = new TempFile())
            {
                new PkgBuilder(MakeProperties()).Write(pkgFile.Path, s => { });

                using (var pkgStream = File.OpenRead(pkgFile.Path))
                {
                    var pkg = new PkgReader(pkgStream).ReadPkg();
                    foreach (var v in new PkgValidator(pkg).Validate(pkgStream))
                    {
                        Assert.IsTrue(v.Item2, v.Item1.Name);
                    }
                }
            }
        }
示例#5
0
        public static void OpenPkgFilesystem(System.IO.Stream pkgStream, Action <PfsReader> innerPfsAction)
        {
            Pkg pkg;

            pkg = new PkgReader(pkgStream).ReadPkg();
            var ekpfs          = LibOrbisPkg.Util.Crypto.ComputeKeys(pkg.Header.content_id, "00000000000000000000000000000000", 1);
            var outerPfsOffset = (long)pkg.Header.pfs_image_offset;

            using (var acc = new LibOrbisPkg.Util.StreamReader(pkgStream, outerPfsOffset))
            {
                var outerPfs = new PfsReader(acc, pkg.Header.pfs_flags, ekpfs);
                var inner    = new PfsReader(new PFSCReader(outerPfs.GetFile("pfs_image.dat").GetView()));
                // Check that the sce_sys directory exists
                innerPfsAction(inner);
            }
        }
示例#6
0
        public void ValidateGD_LargeSc0()
        {
            using (var pkgFile = new MemoryStream())
            {
                const int size       = 0x1023456;
                var       properties = TestHelper.MakeProperties(
                    VolumeType: VolumeType.pkg_ps4_app,
                    sc0Files: new[] { new FSFile(s => s.Position += size, "save_data.png", size) });
                new PkgBuilder(properties).Write(pkgFile, s => { });

                var pkg = new PkgReader(pkgFile).ReadPkg();
                foreach (var v in new PkgValidator(pkg).Validate(pkgFile))
                {
                    Assert.IsTrue(v.Item2 == PkgValidator.ValidationResult.Ok, v.Item1.Name);
                }
            }
        }
示例#7
0
 private void setPKGPFSFileMetadataToolStripMenuItem_Click(object sender, EventArgs e)
 {
     using (var ofd = new OpenFileDialog()
     {
         Title = "Select files",
         Filter = "PKG/PFS Files (*.pkg, *.dat)|*.pkg;*.dat",
         Multiselect = true
     })
     {
         if (ofd.ShowDialog() != DialogResult.OK)
         {
             return;
         }
         foreach (var filename in ofd.FileNames)
         {
             DateTime creationTime = File.GetCreationTimeUtc(filename);
             DateTime modifiedTime = File.GetLastWriteTime(filename);
             using (var f = File.OpenRead(filename))
             {
                 if (filename.ToLowerInvariant().EndsWith(".dat"))
                 {
                     var header = PfsHeader.ReadFromStream(f);
                     creationTime = modifiedTime =
                         new DateTime(1970, 1, 1)
                         .AddSeconds(header.InodeBlockSig.Time1_sec);
                 }
                 else if (filename.ToLowerInvariant().EndsWith(".pkg"))
                 {
                     var pkgHeader = new PkgReader(f).ReadHeader();
                     f.Position = (long)pkgHeader.pfs_image_offset;
                     var header = PfsHeader.ReadFromStream(f);
                     creationTime = modifiedTime =
                         new DateTime(1970, 1, 1)
                         .AddSeconds(header.InodeBlockSig.Time1_sec);
                 }
             }
             File.SetCreationTimeUtc(filename, creationTime);
             File.SetLastWriteTimeUtc(filename, modifiedTime);
         }
     }
 }
示例#8
0
        // Helper for checking the internal files of a PKG
        private static void OpenPkgFilesystem(string pkgPath, Action <PfsReader> innerPfsAction)
        {
            Pkg pkg;

            using (var mmf = MemoryMappedFile.CreateFromFile(pkgPath))
            {
                using (var s = mmf.CreateViewStream())
                {
                    pkg = new PkgReader(s).ReadPkg();
                }
                var ekpfs          = LibOrbisPkg.Util.Crypto.ComputeKeys(pkg.Header.content_id, "00000000000000000000000000000000", 1);
                var outerPfsOffset = (long)pkg.Header.pfs_image_offset;
                using (var acc = mmf.CreateViewAccessor(outerPfsOffset, (long)pkg.Header.pfs_image_size))
                {
                    var outerPfs = new PfsReader(acc, ekpfs);
                    var inner    = new PfsReader(new PFSCReader(outerPfs.GetFile("pfs_image.dat").GetView()));
                    // Check that the sce_sys directory exists
                    innerPfsAction(inner);
                }
            }
        }
示例#9
0
        public static void CreateProjectFromPKG(string outputDir, MemoryMappedFile pkgFile, string passcode = null)
        {
            Directory.CreateDirectory(outputDir);
            Pkg pkg;

            using (var f = pkgFile.CreateViewStream(0, 0, MemoryMappedFileAccess.Read))
                pkg = new PkgReader(f).ReadPkg();

            passcode = passcode ?? "00000000000000000000000000000000";

            // Initialize project parameters
            var project = Gp4Project.Create(ContentTypeToVolumeType(pkg.Header.content_type));

            project.volume.Package.Passcode    = passcode;
            project.volume.Package.ContentId   = pkg.Header.content_id;
            project.volume.Package.AppType     = project.volume.Type == VolumeType.pkg_ps4_app ? "full" : null;
            project.volume.Package.StorageType = project.volume.Type == VolumeType.pkg_ps4_app ? "digital50" : null;

            if (pkg.Header.content_type == ContentType.AC || pkg.Header.content_type == ContentType.AL)
            {
                pkg.LicenseDat.DecryptSecretWithDebugKey();
                var entitlementKey = new byte[16];
                Buffer.BlockCopy(pkg.LicenseDat.Secret, 0x70, entitlementKey, 0, 16);
                pkg.LicenseDat.EncryptSecretWithDebugKey();
                project.volume.Package.EntitlementKey = entitlementKey.ToHexCompact();
            }

            // Extract entry filesystem
            var sys_dir     = Path.Combine(outputDir, "sce_sys");
            var sys_projdir = project.AddDir(null, "sce_sys");

            Directory.CreateDirectory(sys_dir);
            foreach (var meta in pkg.Metas.Metas)
            {
                // Skip entries that are auto-generated or that we don't know the filenames for
                if (GeneratedEntries.Contains(meta.id))
                {
                    continue;
                }
                if (!EntryNames.IdToName.ContainsKey(meta.id))
                {
                    continue;
                }

                var entryName = EntryNames.IdToName[meta.id];
                var filename  = Path.Combine(sys_dir, entryName);

                // Create directories for entries within directories
                if (entryName.Contains('/'))
                {
                    var entryDir = entryName.Substring(0, entryName.LastIndexOf('/'));
                    Directory.CreateDirectory(Path.Combine(sys_dir, entryDir));
                    Dir d = sys_projdir;
                    foreach (var breadcrumb in entryDir.Split('/'))
                    {
                        d = project.AddDir(d, breadcrumb);
                    }
                }

                // Add the entry to the project
                project.files.Items.Add(new Gp4File()
                {
                    OrigPath   = "sce_sys/" + entryName,
                    TargetPath = "sce_sys/" + entryName
                });

                // Save to the filesystem
                using (var s = pkgFile.CreateViewStream(meta.DataOffset, meta.DataSize, MemoryMappedFileAccess.Read))
                    using (var entryFile = File.Create(filename))
                    {
                        s.CopyTo(entryFile);
                    }
            }

            // Fixup the param.sfo
            using (var f = File.Open(Path.Combine(outputDir, "sce_sys/param.sfo"), FileMode.Open))
            {
                var sfo         = SFO.ParamSfo.FromStream(f);
                var pubtoolinfo = (sfo["PUBTOOLINFO"] as SFO.Utf8Value).Value;
                var c_date      = "";
                var c_time      = "";
                foreach (var info in pubtoolinfo.Split(','))
                {
                    var info2 = info.Split('=');
                    switch (info2[0])
                    {
                    case "c_date":
                        c_date =
                            info2[1].Substring(0, 4) + "-" +
                            info2[1].Substring(4, 2) + "-" +
                            info2[1].Substring(6, 2);
                        break;

                    case "c_time":
                        c_time = " " +
                                 info2[1].Substring(0, 2) + ":" +
                                 info2[1].Substring(2, 2) + ":" +
                                 info2[1].Substring(4, 2);
                        break;
                    }
                }
                project.volume.Package.CreationDate = c_date + c_time;
                sfo["PUBTOOLVER"]  = null;
                sfo["PUBTOOLINFO"] = null;
                sfo.Write(f);
            }

            // Extract files from the PFS filesystem
            byte[] ekpfs;
            if (pkg.CheckPasscode(passcode))
            {
                ekpfs = Crypto.ComputeKeys(pkg.Header.content_id, passcode, 1);
            }
            else
            {
                ekpfs = pkg.GetEkpfs();
            }
            using (var va = pkgFile.CreateViewAccessor((long)pkg.Header.pfs_image_offset, (long)pkg.Header.pfs_image_size, MemoryMappedFileAccess.Read))
            {
                var outerPfs = new PfsReader(va, pkg.Header.pfs_flags, ekpfs);
                var inner    = new PfsReader(new PFSCReader(outerPfs.GetFile("pfs_image.dat").GetView()));
                // Convert PFS image timestamp from UNIX time and save it in the project
                project.volume.TimeStamp = new DateTime(1970, 1, 1)
                                           .AddSeconds(inner.Header.InodeBlockSig.Time1_sec);
                var uroot       = inner.GetURoot();
                Dir dir         = null;
                var projectDirs = new Queue <Dir>();
                var pfsDirs     = new Queue <PfsReader.Dir>();
                pfsDirs.Enqueue(uroot);
                projectDirs.Enqueue(dir);
                while (pfsDirs.Count > 0)
                {
                    dir = projectDirs.Dequeue();
                    if (dir != null)
                    {
                        Directory.CreateDirectory(Path.Combine(outputDir, dir.Path));
                    }
                    foreach (var f in pfsDirs.Dequeue().children)
                    {
                        if (f is PfsReader.Dir d)
                        {
                            pfsDirs.Enqueue(d);
                            projectDirs.Enqueue(project.AddDir(dir, d.name));
                        }
                        else if (f is PfsReader.File file)
                        {
                            // Remove "/uroot/"
                            var path = file.FullName.Substring(7);
                            project.files.Items.Add(new Gp4File()
                            {
                                OrigPath   = path,
                                TargetPath = path
                            });
                            file.Save(Path.Combine(outputDir, path));
                        }
                    }
                }
            }

            // Last step: save the project file
            using (var f = File.Create(Path.Combine(outputDir, "Project.gp4")))
            {
                Gp4Project.WriteTo(project, f);
            }
        }
示例#10
0
        private void Trophy_Load(object sender, EventArgs e)
        {
            //extract all entry
            //add entry to array
            using (var file = File.OpenRead(filenames))
            {
                var pkg = new PkgReader(file).ReadPkg();
                var i   = 0;



                foreach (var meta in pkg.Metas.Metas)
                {
                    idEntryList.Add($"{i++,-6}");
                    nameEntryList.Add($"{meta.id}");
                }

                idEntryList.ToArray();
                nameEntryList.ToArray();
            }

            //extract each entry from array
            PS4_Tools.PKG.SceneRelated.Unprotected_PKG PS4_PKG = PS4_Tools.PKG.SceneRelated.Read_PKG(filenames);
            string game_title         = PS4_PKG.Param.Title;
            string filter             = game_title.Replace(":", " -");
            string title_filter_final = filter.Replace("  -", " -");

            string path = tempPath + @"Trophy\";

            try
            {
                Directory.CreateDirectory(path + title_filter_final);

                var numbersAndWords = idEntryList.Zip(nameEntryList, (n, w) => new { id = n, name = w });
                foreach (var nw in numbersAndWords)
                {
                    var pkgPath = filenames;
                    var idx     = int.Parse(nw.id);
                    var name    = nw.name;
                    var outPath = path + title_filter_final + "\\" + name.Replace("_SHA", ".SHA").Replace("_DAT", ".DAT").Replace("_SFO", ".SFO").Replace("_XML", ".XML").Replace("_SIG", ".SIG").Replace("_PNG", ".PNG").Replace("_JSON", ".JSON").Replace("_DDS", ".DDS").Replace("_TRP", ".TRP").Replace("_AT9", ".AT9");;

                    using (var pkgFile = File.OpenRead(pkgPath))
                    {
                        var pkg = new PkgReader(pkgFile).ReadPkg();
                        if (idx < 0 || idx >= pkg.Metas.Metas.Count)
                        {
                            DarkMessageBox.ShowError("Error: entry number out of range", "PS4 PKG Tool");
                            return;
                        }
                        using (var outFile = File.Create(outPath))
                        {
                            var meta = pkg.Metas.Metas[idx];
                            outFile.SetLength(meta.DataSize);
                            if (meta.Encrypted)
                            {
                                if (passcode == null)
                                {
                                    //MessageBox.Show("Warning: Entry is encrypted but no passcode was provided! Saving encrypted bytes.");
                                }
                                else
                                {
                                    var entry = new SubStream(pkgFile, meta.DataOffset, (meta.DataSize + 15) & ~15);
                                    var tmp   = new byte[entry.Length];
                                    entry.Read(tmp, 0, tmp.Length);
                                    tmp = LibOrbisPkg.PKG.Entry.Decrypt(tmp, pkg.Header.content_id, passcode, meta);
                                    outFile.Write(tmp, 0, (int)meta.DataSize);
                                    return;
                                }
                            }
                            new SubStream(pkgFile, meta.DataOffset, meta.DataSize).CopyTo(outFile);
                        }
                    }
                }

                //MessageBox.Show("All entry item extracted", "PS4 PKG Tool");
            }
            catch (Exception a)
            {
                DarkMessageBox.ShowError(a.Message, "PS4 PKG Tool");
            }



            //done exract, now open trp
            if (File.Exists(path + title_filter_final + "\\TROPHY__TROPHY00.TRP"))
            {
                trophy = new TRPReader();
                trophy.Load(path + title_filter_final + "\\TROPHY__TROPHY00.TRP");

                if (!trophy.IsError)
                {
                    List <Archiver> .Enumerator enumerator = new List <Archiver> .Enumerator();

                    enumerator = trophy.TrophyList.GetEnumerator();



                    try
                    {
                        //listView1.Columns.Add("Icon");
                        //listView1.Columns.Add("Name");
                        //listView1.Columns.Add("Size");
                        //listView1.Columns.Add("Offset");

                        //listView1.View = View.Details;

                        //_ImageListIcons.ImageSize = new Size(96, 96);
                        //listView1.SmallImageList = _ImageListIcons;

                        while (enumerator.MoveNext())
                        {
                            Archiver current = enumerator.Current;
                            if (current.Name.ToUpper().EndsWith(".PNG"))
                            {
                                imgList.Add(Utilities.BytesToImage(trophy.ExtractFileToMemory(current.Name)));
                                ImageListIcons.Images.Add(imgList[checked (imgList.Count - 1)]);

                                imageToExtract.Add(Utilities.BytesToImage(trophy.ExtractFileToMemory(current.Name)));
                                NameToExtract.Add(current.Name);

                                var image  = Utilities.BytesToImage(trophy.ExtractFileToMemory(current.Name));
                                var resize = ResizeImage(image, image.Width / 2, image.Height / 2);
                                darkDataGridView1.Rows.Add(resize, current.Name, Utilities.RoundBytes(current.Size), "0x" + current.Offset);

                                //              listView1.Items.Add(new ListViewItem()
                                //              {
                                //                  SubItems = {
                                //  current.Name, Utilities.RoundBytes(current.Size)
                                //},
                                //                  ImageIndex = checked(ImageListIcons.Images.Count - 1),
                                //                  Tag = (object)imgList.Count
                                //              });
                            }
                            //dataGridView1.DataSource = dt;
                            Application.DoEvents();
                        }

                        NameToExtract.ToArray();

                        //listView1.Columns[0].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
                        //listView1.Columns[1].AutoResize(ColumnHeaderAutoResizeStyle.None);
                        //listView1.Columns[1].Width = 347;
                        //listView1.Columns[2].AutoResize(ColumnHeaderAutoResizeStyle.None);
                        //listView1.Columns[2].Width = 103;
                    }
                    finally
                    {
                        enumerator.Dispose();
                    }
                    if (!issaved)
                    {
                        if (Operators.CompareString(trophy.SHA1, trophy.CalculateSHA1Hash(), false) != 0)
                        {
                            DarkMessageBox.ShowError("This file is corrupted, mismatched SHA1 hash!", "PS4 PKG Tool");
                        }
                        //else
                        //MessageBox.Show("Loaded successfully.");
                    }
                    else
                    {
                        label1.Text = "Saved successfully.";
                    }
                    label1.Enabled = trophy.Version > 1;
                    //this.Text = "[ Trophy v" + Conversions.ToString(trophy.Version > 1) + " - Files count: " + listView1.Items.Count + " ]";
                    try
                    {
                        string input  = Encoding.UTF8.GetString(trophy.ExtractFileToMemory("TROP.SFM"));
                        Match  match1 = new Regex("(?<start>[<]title[-]name[>])(?<titlename>.+)(?<end>[<][/]title[-]name[>])").Match(input);
                        if (match1.Success)
                        {
                            trophy.TitleName = match1.Groups["titlename"].Value;
                            Text             = "TRPViewer - " + trophy.TitleName;
                        }
                        Match match2 = new Regex("(?<start>[<]npcommid[>])(?<npcommid>.+)(?<end>[<][/]npcommid[>])").Match(input);
                        if (match2.Success)
                        {
                            trophy.NPCommId = match2.Groups["npcommid"].Value;
                        }
                    }
                    catch (Exception ex)
                    {
                        ProjectData.SetProjectError(ex);
                        ProjectData.ClearProjectError();
                    }
                }
                ctrophy.SetVersion = trophy.Version;
            }

            this.Text += PS4_PKG.PS4_Title;



            /*
             * PS4_Tools.PKG.SceneRelated.Unprotected_PKG PS4_PKG = PS4_Tools.PKG.SceneRelated.Read_PKG(this.filenames);
             * this.Text = "Trophy List : " + PS4_PKG.PS4_Title;
             *
             * DataTable dttemp = new DataTable();
             * dttemp.Columns.Add("Index");
             * dttemp.Columns.Add("Trophy File");
             * dttemp.Columns.Add("Offset");
             * dttemp.Columns.Add("Size");
             *
             * try
             * {
             * for (int i = 0; i < PS4_PKG.Trophy_File.trophyItemList.Count; i++)
             * {
             *  dttemp.Rows.Add(PS4_PKG.Trophy_File.trophyItemList[i].Index, PS4_PKG.Trophy_File.trophyItemList[i].Name, PS4_PKG.Trophy_File.trophyItemList[i].Offset, PS4_PKG.Trophy_File.trophyItemList[i].Size);
             *  //dttemp.Rows.Add(PS4_PKG.Param.Tables[i].Name, PS4_PKG.Param.Tables[i].Value);
             *
             * }
             *
             *
             * }
             * catch (Exception ex)
             * {
             *
             * }
             * dataGridView1.DataSource = dttemp;
             * filenames = "";
             */
        }