Exemple #1
0
        public static void Main(string[] args)
        {
            bool showHelp = false;

            var options = new OptionSet()
            {
                { "h|help", "show this message and exit", v => showHelp = v != null },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (extras.Count < 1 ||
                extras.Count > 2 ||
                showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ input_drm [output_drm]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            string inputPath  = extras[0];
            string outputPath = extras.Count > 1 ? extras[1] : inputPath;

            Stream data;

            using (var input = File.OpenRead(inputPath))
            {
                var magic        = input.ReadValueU32(Endian.Big);
                var isCompressed = magic == CompressedDrmFile.Signature;
                input.Seek(-4, SeekOrigin.Current);

                if (isCompressed == true)
                {
                    data = CompressedDrmFile.Decompress(input);
                }
                else
                {
                    data = input.ReadToMemoryStream((int)(input.Length - input.Position));
                }

                data.Position = 0;
            }

            using (var output = File.Create(outputPath))
            {
                output.WriteFromStream(data, data.Length);
            }
        }
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Big);

            input.Seek(-4, SeekOrigin.Current);

            if (magic == CompressedDrmFile.Signature)
            {
                input = CompressedDrmFile.Decompress(input);
            }

            if (input.Position + 32 > input.Length)
            {
                throw new FormatException("not enough data for header");
            }

            var version = input.ReadValueU32(Endian.Little);

            if (version != 19 && version.Swap() != 19 &&
                version != 21 && version.Swap() != 21)
            {
                throw new FormatException();
            }

            var endian = version == 19 || version == 21 ? Endian.Little : Endian.Big;

            this.Endian  = endian;
            this.Version = version == 19 || version == 21 ? version : version.Swap();

            if (this.Version == 19)
            {
                throw new NotSupportedException();
            }

            var unknown04_Size = input.ReadValueU32(endian);
            var unknown08_Size = input.ReadValueU32(endian);
            var unknown0C      = input.ReadValueU32(endian); // extra data after first block?
            var unknown10      = input.ReadValueU32(endian);

            this.Flags = input.ReadValueU32(endian);
            var sectionCount    = input.ReadValueU32(endian);
            var unknown1C_Count = input.ReadValueU32(endian);

            if (unknown0C != 0)
            {
                throw new FormatException();

                if ((this.Flags & 1) != 0)
                {
                    input.Seek(input.Position.Align(16), SeekOrigin.Begin);
                }
            }

            var sectionHeaders = new DRM.SectionHeader[sectionCount];

            for (uint i = 0; i < sectionCount; i++)
            {
                sectionHeaders[i] = new DRM.SectionHeader();
                sectionHeaders[i].Deserialize(input, endian);
            }

            this.Unknown08s.Clear();
            using (var unknown08_Data = input.ReadToMemoryStream((int)unknown08_Size))
            {
                while (unknown08_Data.Position < unknown08_Data.Length)
                {
                    this.Unknown08s.Add(unknown08_Data.ReadStringZ(Encoding.ASCII));
                }
            }

            this.Unknown04s.Clear();
            using (var unknown04_Data = input.ReadToMemoryStream((int)unknown04_Size))
            {
                while (unknown04_Data.Position < unknown04_Data.Length)
                {
                    this.Unknown04s.Add(unknown04_Data.ReadStringZ(Encoding.ASCII));
                }
            }

            if ((this.Flags & 1) != 0)
            {
                input.Seek(input.Position.Align(16), SeekOrigin.Begin);
            }

            var sections = new DRM.Section[sectionCount];

            for (int i = 0; i < sectionCount; i++)
            {
                var sectionHeader = sectionHeaders[i];

                var section = new DRM.Section();
                section.Id        = sectionHeader.Id;
                section.Type      = sectionHeader.Type;
                section.Flags     = (byte)(sectionHeader.Flags & 0xFF);
                section.Unknown05 = sectionHeader.Unknown05;
                section.Unknown06 = sectionHeader.Unknown06;
                section.Unknown10 = sectionHeader.Unknown10;

                if ((sectionHeader.Unknown05 & 1) != 0)
                {
                    throw new NotImplementedException();
                }

                if (sectionHeader.HeaderSize > 0)
                {
                    using (var buffer = input.ReadToMemoryStream((int)sectionHeader.HeaderSize))
                    {
                        var resolver = new DRM.Resolver();
                        resolver.Deserialize(buffer, endian);
                        section.Resolver = resolver;
                    }
                }

                if ((this.Flags & 1) != 0)
                {
                    input.Seek(input.Position.Align(16), SeekOrigin.Begin);
                }

                if (sectionHeader.DataSize > 0)
                {
                    section.Data = input.ReadToMemoryStream((int)sectionHeader.DataSize);
                }
                else
                {
                    section.Data = null;
                }

                if ((this.Flags & 1) != 0)
                {
                    input.Seek(input.Position.Align(16), SeekOrigin.Begin);
                }

                sections[i] = section;
            }

            this.Sections.Clear();
            this.Sections.AddRange(sections);
        }