private void decompressRPLRPXToolStripMenuItem_Click(object sender, EventArgs e) { if (FileELF is RPX && File.Exists(LastFile)) { string destination = Path.GetDirectoryName(LastFile) + "\\" + Path.GetFileNameWithoutExtension(LastFile) + "_decompressed" + Path.GetExtension(LastFile); RPX.Decompress(LastFile, destination); MessageBox.Show("Output: \"" + destination + "\"", "Decompressed!"); } else if (!(FileELF is RPX) && File.Exists(LastFile)) { MessageBox.Show("\"" + LastFile + "\" is not an RPX or RPL file.", "Warning!"); } else if (FileELF is RPX && !File.Exists(LastFile)) { MessageBox.Show("The file \"" + LastFile + "\" no longer exists. ", "Warning!"); } else { MessageBox.Show("Open an RPX or RPL file.", "Warning!"); } }
public static void Compress(string source, string destination) { RPX rpx = new RPX(source); int shSize = rpx.Header.e_shnum * 0x2C; // 0x2C = rpx.Header.e_shentsize + 4 bytes of CRC32 int sectionsOffset = GetPhysicalSectionSize(shSize) + 0x40; List <KeyValuePair <int, Elf32_Shdr> > shList = new List <KeyValuePair <int, Elf32_Shdr> >(); List <KeyValuePair <int, Elf32_Shdr> > shNew = new List <KeyValuePair <int, Elf32_Shdr> >(); for (int i = 0; i < rpx.SectionHeader.Length; i++) { shList.Add(new KeyValuePair <int, Elf32_Shdr>(i, rpx.SectionHeader[i])); } shList.Sort((pair1, pair2) => Elf32_Shdr.CompareByOffset(pair1.Value, pair2.Value)); FileStream src = File.Open(source, FileMode.Open); FileStream dest = File.Open(destination, FileMode.Create); byte[] srcBytes = new byte[sectionsOffset]; src.Read(srcBytes, 0, srcBytes.Length); dest.Write(srcBytes, 0, srcBytes.Length); for (int i = 0; i < shList.Count; i++) { int key = shList[i].Key; Elf32_Shdr shdr = new Elf32_Shdr(shList[i].Value); if (shList[i].Value.sh_offset >= sectionsOffset) { int padding = 0; if ((shList[i].Value.sh_type & (uint)SHT_RPL.FILEINFO) == (uint)SHT_RPL.FILEINFO || (shList[i].Value.sh_flags & (uint)SHF_RPL.ZLIB) == (uint)SHF_RPL.ZLIB) { shdr.sh_offset = (uint)dest.Position; srcBytes = new byte[shList[i].Value.sh_size]; src.Position = shList[i].Value.sh_offset; src.Read(srcBytes, 0, srcBytes.Length); if ((shList[i].Value.sh_type & (uint)SHT_RPL.FILEINFO) == (uint)SHT_RPL.FILEINFO) { rpx.CRC[shList[i].Key] = Security.ComputeCRC32(srcBytes, 0, srcBytes.Length); } padding = GetPhysicalSectionSize(srcBytes.Length) - srcBytes.Length; dest.Write(srcBytes, 0, srcBytes.Length); } else { shdr.sh_offset = (uint)dest.Position; srcBytes = new byte[shList[i].Value.sh_size]; src.Position = shList[i].Value.sh_offset; src.Read(srcBytes, 0, srcBytes.Length); byte[] compressBytes = Compress(srcBytes); rpx.CRC[shList[i].Key] = Security.ComputeCRC32(srcBytes, 0, srcBytes.Length); if (compressBytes.Length < srcBytes.Length) { shdr.sh_flags |= (uint)SHF_RPL.ZLIB; shdr.sh_size = (uint)compressBytes.Length; padding = GetPhysicalSectionSize(compressBytes.Length) - compressBytes.Length; dest.Write(compressBytes, 0, compressBytes.Length); } else { padding = GetPhysicalSectionSize(srcBytes.Length) - srcBytes.Length; dest.Write(srcBytes, 0, srcBytes.Length); } } byte[] paddingBytes = new byte[padding]; dest.Write(paddingBytes, 0, paddingBytes.Length); } shNew.Add(new KeyValuePair <int, Elf32_Shdr>(key, shdr)); } src.Close(); dest.Position = 0x40; shNew.Sort((pair1, pair2) => pair1.Key.CompareTo(pair2.Key)); for (int i = 0; i < shNew.Count; i++) { dest.Write(shNew[i].Value.ToArray(rpx.Header.e_ident[(byte)EI.DataEncoding]), 0, 0x28); } for (int i = 0; i < rpx.CRC.Length; i++) { dest.WriteByte((byte)(rpx.CRC[i] >> 24)); dest.WriteByte((byte)((rpx.CRC[i] >> 16) & 0xFF)); dest.WriteByte((byte)((rpx.CRC[i] >> 8) & 0xFF)); dest.WriteByte((byte)(rpx.CRC[i] & 0xFF)); } dest.Close(); }
public void Run(string[] args) { Console.WriteLine("ELF/RPL/RPX Reader v1.0"); if (args.Length == 1) { ELF file = ELF.Open(args[0]); if (file != null) { Console.Write("File: \"" + args[0] + "\"\n\n" + file.ToString()); } else { Console.WriteLine("File: \"" + args[0] + "\"\n\nIt is not an ELF, RPX or RPL file."); } } else if (args.Length == 2) { if (args[0] == "decompress") { ELF file = ELF.Open(args[1]); if (file != null) { Console.Write("File: \"" + args[1] + "\"\n\n" + file.ToString()); string destination = Path.GetDirectoryName(args[1]).Length > 0 ? Path.GetDirectoryName(args[1]) + "\\" : "" + Path.GetFileNameWithoutExtension(args[1]) + "_decompressed" + Path.GetExtension(args[1]); try { RPX.Decompress(args[1], destination); Console.WriteLine("\nDecompressed!"); Console.WriteLine("Output: \"" + destination + "\""); } catch { Console.WriteLine("\nIt is not an RPX or RPL file"); } } else { Console.WriteLine("File: \"" + args[1] + "\"\n\nIt is not an ELF, RPX or RPL file."); } } else if (args[0] == "compress") { ELF file = ELF.Open(args[1]); if (file != null) { Console.Write("File: \"" + args[1] + "\"\n\n" + file.ToString()); string destination = Path.GetDirectoryName(args[1]).Length > 0 ? Path.GetDirectoryName(args[1]) + "\\" : "" + Path.GetFileNameWithoutExtension(args[1]) + "_compressed" + Path.GetExtension(args[1]); try { RPX.Compress(args[1], destination); Console.WriteLine("\nCompressed!"); Console.WriteLine("Output: \"" + destination + "\""); } catch { Console.WriteLine("\nIt is not an RPX or RPL file"); } } else { Console.WriteLine("File: \"" + args[1] + "\"\n\nIt is not an ELF, RPX or RPL file."); } } else if (args[0] == "extractrom") { ELF file = ELF.Open(args[1]); if (file != null) { Console.Write("File: \"" + args[1] + "\"\n\n" + file.ToString()); if (file is RPXNES) { RPXNES vc = file as RPXNES; string filename = Path.GetDirectoryName(args[1]).Length > 0 ? Path.GetDirectoryName(args[1]) + "\\" : "" + vc.GetROMFileName(); FileStream fs = File.Open(filename, FileMode.Create); if (vc.ROM.IsFDS) { fs.Write(vc.ROM.Data, 0, vc.ROM.RawSize); } else { fs.Write(vc.ROM.Data, 0, vc.ROM.RawSize + 16); fs.Position = 3; fs.WriteByte(0x1A); } fs.Close(); Console.WriteLine("\nROM extracted!"); Console.WriteLine("Output: \"" + filename + "\""); } else if (file is RPXSNES) { RPXSNES vc = file as RPXSNES; string filename = Path.GetDirectoryName(args[1]) + "\\" + vc.GetROMFileName(); FileStream fs = File.Open(filename, FileMode.Create); fs.Write(vc.ROM.Data, 0, vc.ROM.Data.Length); fs.Close(); Console.WriteLine("\nROM extracted!"); Console.WriteLine("Output: \"" + filename + "\""); } else { Console.WriteLine("\nIt is not an VC NES RPX or VC SNES RPX file."); } } else { Console.WriteLine("File: \"" + args[1] + "\"\n\nIt is not an ELF, RPX or RPL file."); } } else { Console.WriteLine("Use: <file path>"); Console.WriteLine("Or: decompress <file path>"); Console.WriteLine("Or: compress <file path>"); Console.WriteLine("Or: extractrom <file path>"); } } else { Console.WriteLine("Use: <file path>"); Console.WriteLine("Or: decompress <file path>"); Console.WriteLine("Or: compress <file path>"); Console.WriteLine("Or: extractrom <file path>"); } }