예제 #1
0
        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();
        }
예제 #2
0
        protected void Edit(string rom, string destination,
                            byte speed, byte players, byte soundVolume, byte romType,
                            short widthTv, short widthDrc, short heightTv, short heightDrc)
        {
            FileStream fs = File.Open(FileName, FileMode.Open);

            byte[] rodata = new byte[SectionHeader[RodataSectionIndex].sh_size];
            fs.Position = SectionHeader[RodataSectionIndex].sh_offset;
            fs.Read(rodata, 0, rodata.Length);
            byte[] textSection = new byte[SectionHeader[TextSectionIndex].sh_size];
            fs.Position = SectionHeader[TextSectionIndex].sh_offset;
            fs.Read(textSection, 0, textSection.Length);
            fs.Close();

            if (rom != null)
            {
                if ((SectionHeader[RodataSectionIndex].sh_flags & 0x08000000) == 0x08000000)//Section Header Flag RPL ZLIB
                {
                    rodata = Decompress(rodata);
                }
                rodata = GetNewRodata(CRCsSum, rodata, rom, speed, players, soundVolume, romType);
                CRC[RodataSectionIndex] = Cll.Security.ComputeCRC32(rodata, 0, rodata.Length);
                if ((SectionHeader[RodataSectionIndex].sh_flags & 0x08000000) == 0x08000000)//Section Header Flag RPL ZLIB
                {
                    rodata = Compress(rodata);
                }
            }

            if ((SectionHeader[TextSectionIndex].sh_flags & 0x08000000) == 0x08000000)//Section Header Flag RPL ZLIB
            {
                textSection = Decompress(textSection);
            }
            int aspectRatioOffset = GetAspectRatioOffset(CRCsSum);

            if (aspectRatioOffset != 0)
            {
                textSection[aspectRatioOffset]        = (byte)(heightTv >> 8);
                textSection[aspectRatioOffset + 0x01] = (byte)(heightTv & 0xFF);
                textSection[aspectRatioOffset + 0x04] = (byte)(widthTv >> 8);
                textSection[aspectRatioOffset + 0x05] = (byte)(widthTv & 0xFF);
                textSection[aspectRatioOffset + 0x30] = (byte)(heightDrc >> 8);
                textSection[aspectRatioOffset + 0x31] = (byte)(heightDrc & 0xFF);
                textSection[aspectRatioOffset + 0x34] = (byte)(widthDrc >> 8);
                textSection[aspectRatioOffset + 0x35] = (byte)(widthDrc & 0xFF);
            }
            CRC[TextSectionIndex] = Cll.Security.ComputeCRC32(textSection, 0, textSection.Length);
            if ((SectionHeader[TextSectionIndex].sh_flags & 0x08000000) == 0x08000000)//Section Header Flag RPL ZLIB
            {
                textSection = Compress(textSection);
            }

            int shSize         = Header.e_shnum * 0x2C; // 0x2C = 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 < SectionHeader.Length; i++)
            {
                shList.Add(new KeyValuePair <int, Elf32_Shdr>(i, SectionHeader[i]));
            }
            shList.Sort((pair1, pair2) => Elf32_Shdr.CompareByOffset(pair1.Value, pair2.Value));

            FileStream src  = File.Open(FileName, 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;
                    shdr.sh_offset = (uint)dest.Position;
                    if (shList[i].Value.sh_offset == SectionHeader[TextSectionIndex].sh_offset)
                    {
                        shdr.sh_size = (uint)textSection.Length;
                        padding      = GetPhysicalSectionSize(textSection.Length) - textSection.Length;
                        dest.Write(textSection, 0, textSection.Length);
                    }
                    else if (shList[i].Value.sh_offset == SectionHeader[RodataSectionIndex].sh_offset)
                    {
                        shdr.sh_size = (uint)rodata.Length;
                        padding      = GetPhysicalSectionSize(rodata.Length) - rodata.Length;
                        dest.Write(rodata, 0, rodata.Length);
                    }
                    else
                    {
                        srcBytes     = new byte[shList[i].Value.sh_size];
                        src.Position = shList[i].Value.sh_offset;
                        src.Read(srcBytes, 0, srcBytes.Length);
                        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(), 0, 0x28);
            }

            for (int i = 0; i < CRC.Length; i++)
            {
                dest.WriteByte((byte)(CRC[i] >> 24));
                dest.WriteByte((byte)((CRC[i] >> 16) & 0xFF));
                dest.WriteByte((byte)((CRC[i] >> 8) & 0xFF));
                dest.WriteByte((byte)(CRC[i] & 0xFF));
            }

            dest.Close();
        }