Exemplo n.º 1
0
        /// <summary>
        /// Save as pure MDF
        /// </summary>
        /// <param name="psb"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static byte[] SaveAsMdf(this PSB psb, uint?key = null)
        {
            psb.Merge();
            var     bytes    = psb.Build();
            Adler32 adler    = new Adler32();
            uint    checksum = 0;

            if (key == null)
            {
                adler.Update(bytes);
                checksum = (uint)adler.Checksum;
            }

            MemoryStream ms = new MemoryStream(bytes);

            using (MemoryStream fs = new MemoryStream())
            {
                if (key != null)
                {
                    MemoryStream nms = new MemoryStream((int)ms.Length);
                    PsbFile.Encode(key.Value, EncodeMode.Encrypt, EncodePosition.Auto, ms, nms);
                    ms.Dispose();
                    ms = nms;
                    var pos = ms.Position;
                    adler.Update(ms);
                    checksum    = (uint)adler.Checksum;
                    ms.Position = pos;
                }

                BinaryWriter bw = new BinaryWriter(fs);
                bw.WriteStringZeroTrim(MdfFile.Signature);
                bw.Write((uint)ms.Length);
                //bw.Write(ZlibCompress.Compress(ms));
                ZlibCompress.CompressToBinaryWriter(bw, ms);
                bw.WriteBE(checksum);
                ms.Dispose();
                bw.Flush();
                return(fs.ToArray());
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Save PSB as MDF file
        /// </summary>
        /// <param name="psb"></param>
        /// <param name="path"></param>
        /// <param name="key"></param>
        public static void SaveAsMdfFile(this PSB psb, string path, uint?key = null)
        {
            psb.Merge();
            var     bytes      = psb.Build();
            Adler32 checksumer = new Adler32();
            uint    checksum   = 0;

            if (key == null)
            {
                checksumer.Update(bytes);
                checksum = (uint)checksumer.Checksum;
            }
            MemoryStream ms = new MemoryStream(bytes);

            using (Stream fs = new FileStream(path, FileMode.Create))
            {
                if (key != null)
                {
                    MemoryStream nms = new MemoryStream((int)ms.Length);
                    PsbFile.Encode(key.Value, EncodeMode.Encrypt, EncodePosition.Auto, ms, nms);
                    ms.Dispose();
                    ms = nms;
                    var pos = ms.Position;
                    checksumer.Update(ms);
                    checksum    = (uint)checksumer.Checksum;
                    ms.Position = pos;
                }

                BinaryWriter bw = new BinaryWriter(fs);
                bw.WriteStringZeroTrim(MdfFile.Signature);
                bw.Write((uint)ms.Length);
                bw.Write(ZlibCompress.Compress(ms));
                bw.WriteBE(checksum);
                ms.Dispose();
                bw.Flush();
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Decompile Pure PSB as Json
        /// </summary>
        /// <param name="path"></param>
        /// <param name="psb"></param>
        /// <param name="context"></param>
        /// <param name="psbType"></param>
        /// <returns></returns>
        public static string Decompile(string path, out PSB psb, Dictionary <string, object> context = null, PsbType psbType = PsbType.PSB)
        {
            using var fs = File.OpenRead(path);
            var    ctx    = FreeMount.CreateContext(context);
            string type   = null;
            Stream stream = fs;

            using var ms = ctx.OpenFromShell(fs, ref type);
            if (ms != null)
            {
                ctx.Context[Consts.Context_PsbShellType] = type;
                fs.Dispose();
                stream = ms;
            }

            try
            {
                psb = new PSB(stream, false);
            }
            catch (PsbBadFormatException e) when(e.Reason == PsbBadFormatReason.Header ||
                                                 e.Reason == PsbBadFormatReason.Array ||
                                                 e.Reason == PsbBadFormatReason.Body)  //maybe encrypted
            {
                stream.Position = 0;
                uint?key = null;

                if (ctx.Context.ContainsKey(Consts.Context_CryptKey))
                {
                    key = ctx.Context[Consts.Context_CryptKey] as uint?;
                }
                else
                {
                    key = ctx.GetKey(stream);
                }

                stream.Position = 0;
                if (key != null) //try use key
                {
                    try
                    {
                        using (var mms = new MemoryStream((int)stream.Length))
                        {
                            PsbFile.Encode(key.Value, EncodeMode.Decrypt, EncodePosition.Auto, stream, mms);
                            stream.Dispose();
                            psb = new PSB(mms);
                            ctx.Context[Consts.Context_CryptKey] = key;
                        }
                    }
                    catch
                    {
                        throw e;
                    }
                }
                else //key = null
                {
                    if (e.Reason == PsbBadFormatReason.Header || e.Reason == PsbBadFormatReason.Array) //now try Dullahan loading
                    {
                        psb = PSB.DullahanLoad(stream);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            if (psbType != PsbType.PSB)
            {
                psb.Type = psbType;
            }

            return(Decompile(psb));
        }
Exemplo n.º 4
0
        static bool Convert(uint?key, string path)
        {
            if (!File.Exists(path))
            {
                Console.WriteLine($"File:{path} not exists.");
                return(false);
            }

            try
            {
                using (var fs = new FileStream(path, FileMode.Open))
                {
                    Stream stream   = fs;
                    string type     = null;
                    var    ms       = FreeMount.CreateContext().OpenFromShell(fs, ref type);
                    bool   hasShell = false;
                    if (ms != null)
                    {
                        Console.WriteLine($"Shell type: {type}");
                        stream   = ms;
                        hasShell = true;
                    }

                    BinaryReader br = new BinaryReader(stream, Encoding.UTF8);
                    if (!key.HasValue)
                    {
                        var k = FreeMount.CreateContext().GetKey(stream);
                        if (k != null)
                        {
                            key = k;
                            Console.WriteLine($"Using key: {key}");
                        }
                        else if (hasShell)
                        {
                            File.WriteAllBytes(Path.ChangeExtension(path, ".decompressed.psb"), ms.ToArray());
                            return(true);
                        }
                        else
                        {
                            Console.WriteLine("No Key and No Shell.");
                            return(false);
                        }
                    }

                    var header = PsbHeader.Load(br);

                    using (var outMs = new MemoryStream((int)stream.Length))
                    {
                        if (header.Version > 2)
                        {
                            if (PsbFile.TestHeaderEncrypted(stream, header)) //Decrypt
                            {
                                //psb.EncodeToFile(key.Value, path + ".decrypted", EncodeMode.Decrypt);
                                PsbFile.Encode(key.Value, EncodeMode.Decrypt, EncodePosition.Auto, stream, outMs);
                                File.WriteAllBytes(Path.ChangeExtension(path, ".pure.psb"), outMs.ToArray());
                            }
                            else
                            {
                                //psb.EncodeToFile(key.Value, path + ".encrypted", EncodeMode.Encrypt);
                                PsbFile.Encode(key.Value, EncodeMode.Encrypt, EncodePosition.Auto, stream, outMs);
                                File.WriteAllBytes(Path.ChangeExtension(path, ".encrypted.psb"), outMs.ToArray());
                            }
                        }
                        else
                        {
                            if (PsbFile.TestBodyEncrypted(br, header)) //Decrypt
                            {
                                PsbFile.Encode(key.Value, EncodeMode.Decrypt, EncodePosition.Auto, stream, outMs);
                                File.WriteAllBytes(Path.ChangeExtension(path, ".pure.psb"), outMs.ToArray());
                            }
                            else
                            {
                                PsbFile.Encode(key.Value, EncodeMode.Encrypt, EncodePosition.Auto, stream, outMs);
                                File.WriteAllBytes(Path.ChangeExtension(path, ".encrypted.psb"), outMs.ToArray());
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: This file is not valid.");
                Console.WriteLine(e);
                return(false);
            }

            return(true);
        }