Beispiel #1
0
 private void ReopenFileView()
 {
     if (!pkg.CheckEkpfs(ekpfs))
     {
         return;
     }
     if (va != null)
     {
         return;
     }
     try
     {
         va = pkgFile.CreateViewAccessor((long)pkg.Header.pfs_image_offset, (long)pkg.Header.pfs_image_size);
         var outerPfs = new PfsReader(va, pkg.Header.pfs_flags, ekpfs);
         var inner    = new PfsReader(new PFSCReader(outerPfs.GetFile("pfs_image.dat").GetView()));
         var view     = new FileView(inner);
         view.Dock = DockStyle.Fill;
         filesTab.Controls.Clear();
         filesTab.Controls.Add(view);
     }
     catch (Exception)
     {
         va?.Dispose();
         va = null;
     }
 }
Beispiel #2
0
 private static void ExtractInParallel(PfsReader inner, string outPath, bool verbose)
 {
     Console.WriteLine("Extracting in parallel...");
     Parallel.ForEach(
         inner.GetAllFiles(),
         () => new byte[0x10000],
         (f, _, buf) =>
     {
         var size     = f.size;
         var pos      = 0;
         var view     = f.GetView();
         var fullName = f.FullName;
         var path     = Path.Combine(outPath, fullName.Replace('/', Path.DirectorySeparatorChar).Substring(1));
         var dir      = path.Substring(0, path.LastIndexOf(Path.DirectorySeparatorChar));
         if (verbose)
         {
             Console.WriteLine($"{fullName} -> {path}");
         }
         Directory.CreateDirectory(dir);
         using (var file = File.OpenWrite(path))
         {
             file.SetLength(size);
             while (size > 0)
             {
                 var toRead = (int)Math.Min(size, buf.Length);
                 view.Read(pos, buf, 0, toRead);
                 file.Write(buf, 0, toRead);
                 pos  += toRead;
                 size -= toRead;
             }
         }
         return(buf);
     },
         x => { });
 }
Beispiel #3
0
        public void AddRoot(PfsReader p, string name)
        {
            var superroot = p.GetSuperRoot();
            var root      = new TreeNode(name)
            {
                Tag = superroot
            };

            directoryTreeView.Nodes.Add(root);
            root.Nodes.Add("Loading", "Loading...", 0);
            ExpandNode(root);
            directoryTreeView.SelectedNode = root.Nodes[0];
        }
Beispiel #4
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);
            }
        }
Beispiel #5
0
 public PFSView(string filename)
 {
     InitializeComponent();
     pfsFile = MemoryMappedFile.CreateFromFile(filename, System.IO.FileMode.Open, "pfsFile" + idx++, 0, MemoryMappedFileAccess.Read);
     va      = pfsFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read);
     va.Read(0, out int val);
     if (val == PFSCReader.Magic)
     {
         reader = new PfsReader(new PFSCReader(va));
     }
     else
     {
         reader = new PfsReader(va);
     }
     fileView1.AddRoot(reader, filename);
 }
Beispiel #6
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);
                }
            }
        }
Beispiel #7
0
        public void TestTweakDataKeys()
        {
            var pfsProperties = new PfsProperties
            {
                BlockSize = 0x10000,
                EKPFS     = new byte[32],
                Encrypt   = true,
                FileTime  = 1,
                root      = TestHelper.MakeRoot(),
                Seed      = new byte[16],
                Sign      = true,
            };

            using (var pfsImg = new MemoryStream())
            {
                new PfsBuilder(pfsProperties).WriteImage(pfsImg);
                var streamReader = new LibOrbisPkg.Util.StreamReader(pfsImg);
                var reader1      = new PfsReader(streamReader, 0, ekpfs: new byte[32]);
                var(tweak, data) = Crypto.PfsGenEncKey(new byte[32], new byte[16]);
                var reader2 = new PfsReader(streamReader, 0, data: data, tweak: tweak);
            }
        }
Beispiel #8
0
        public PFSView(string filename)
        {
            InitializeComponent();
            pfsFile = MemoryMappedFile.CreateFromFile(filename, System.IO.FileMode.Open, mapName: null, 0, MemoryMappedFileAccess.Read);
            va      = pfsFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read);
            va.Read(0, out int val);
            if (val == PFSCReader.Magic)
            {
                reader = new PfsReader(new PFSCReader(va));
            }
            else
            {
                PfsHeader header;
                using (var h = pfsFile.CreateViewStream(0, 0x600, MemoryMappedFileAccess.Read))
                {
                    header = PfsHeader.ReadFromStream(h);
                }
                byte[] tweak = null, data = null;
                if (header.Mode.HasFlag(PfsMode.Encrypted))
                {
                    var passcode = new PasscodeEntry("Please enter data key", 32);
                    passcode.Text = "PFS is encrypted";
                    passcode.ShowDialog();
                    data = passcode.Passcode.FromHexCompact();

                    passcode      = new PasscodeEntry("Please enter tweak key", 32);
                    passcode.Text = "PFS is encrypted";
                    passcode.ShowDialog();
                    data   = passcode.Passcode.FromHexCompact();
                    reader = new PfsReader(va, data: data, tweak: tweak);
                }
                else
                {
                    reader = new PfsReader(va);
                }
            }
            fileView1.AddRoot(reader, filename);
        }
Beispiel #9
0
 public FileView(PfsReader p = null)
 {
     reader = p;
     InitializeComponent();
     InitializeTree();
 }
Beispiel #10
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);
            }
        }