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); }