Example #1
0
        public int Open(string filename)
        {
            _stream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);

            var br = new BigEndianBinaryReader(_stream);
            Header.Read(br);

               /*     _stream.Position = 204410912;
            var br1 = new BinaryReader(_stream);
            int tocSize = 12320;

            byte[] tocData1 = br.ReadBytes(tocSize);
            System.IO.File.WriteAllBytes(@"C:\Users\Dageron\Desktop\test0.bin", tocData1);

            _stream.Position = 204410912;
            byte[] tocData2 = br.ReadBytes(tocSize);

            tocData2 = DataUtil.Decrypt(tocData2);
            System.IO.File.WriteAllBytes(@"C:\Users\Dageron\Desktop\test1.bin", tocData2); */

            if (!Enum.IsDefined(typeof(HeaderIDs), (int)Header.Identifier))
            {
                _stream.Close();
                return 0;
            }

            _stream.Seek(0x10, SeekOrigin.Begin);
            TOC.Read(br);
            return Header.EntryCount;
        }
Example #2
0
 public void Read(BigEndianBinaryReader br)
 {
     Identifier = (HeaderIDs)br.ReadInt32();
     EntryCount = br.ReadInt32();
     TOCSize = EntryCount * 20;
     Unknown1 = br.ReadInt32();
     EncryptedFlag = br.ReadInt32();
 }
Example #3
0
 public override void Read(BigEndianBinaryReader br, int extra = 0)
 {
     NameOffset = br.ReadInt32();
     Flags = br.ReadInt32();
     ContentEntryIndex = (int)(br.ReadUInt32() & 0x7fffffff);
     ContentEntryCount = br.ReadInt32() & 0x0fffffff;
     UNKNOWN = br.ReadInt32();
 }
Example #4
0
        internal static bool ReadAsDirectory(BigEndianBinaryReader br)
        {
            bool dir;

            br.BaseStream.Seek(8, SeekOrigin.Current);
            byte tocData = br.ReadByte();
            dir = tocData == 128;

            br.BaseStream.Seek(-9, SeekOrigin.Current);

            return dir;
        }
Example #5
0
 public int Open(string filename)
 {
     _stream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
     var br = new BigEndianBinaryReader(_stream);
     Header.Read(br);
     if (!Enum.IsDefined(typeof(HeaderIDs), (int)Header.Identifier))
     {
         _stream.Close();
         return 0;
     }
     _stream.Seek(0x10, SeekOrigin.Begin);
     TOC.Read(br);
     return Header.EntryCount;
 }
Example #6
0
        public void Read(BigEndianBinaryReader br)
        {
            Identifier = (HeaderIDs)br.ReadInt32();
            EntryCount = br.ReadInt32();
            TOCSize = EntryCount * 16;

            BitsStream stream = new BitsStream(br.BaseStream);
            stream.Position = 8;
            stream.ReadBits(1);
            nameShift = (int)stream.ReadBits(3);
            namesLength = (int)stream.ReadBits(28);
            br.BaseStream.Position = 12;

            EncryptedFlag = br.ReadInt32();
        }
Example #7
0
            public bool bUseExtSize; //: 1;

            public bool ReadHeader(BigEndianBinaryReader reader)
            {
                try
                {
                    this.m_dwMagic = reader.ReadInt32();
                    switch (m_dwMagic)
                    {
                        case -2059185326:
                            this.m_dwVersion = reader.ReadInt32();
                            this.m_dwFlags1 = reader.ReadInt32();
                            this.m_dwFlags2 = reader.ReadInt32();
                            dwExtVSize = (int)(m_dwFlags2 & 0x7FFF);
                            dwExtPSize = (int)((m_dwFlags2 & 0xFFF7000) >> 14);
                            _f14_30 = (int)(m_dwFlags2 & 0x70000000);
                            bUseExtSize = (m_dwFlags2 & 0x80000000) == 0x80000000 ? true : false;
                            return true;
                        case 88298322:
                            this.m_dwVersion = reader.ReadInt32();
                            this.m_dwFlags1 = reader.ReadInt32();
                            //dwExtVSize = (int)(m_dwFlags2 & 0x7FFF);
                            //dwExtPSize = (int)((m_dwFlags2 & 0xFFF7000) >> 14);
                            //_f14_30 = (int)(m_dwFlags2 & 0x70000000);
                            bUseExtSize = false;
                            return true;
                        default:
                            return false;
                    }
                }
                catch (Exception ex) { return false; }
            }
Example #8
0
        private int disassembleCommand(BigEndianBinaryReader reader, int dwAddress, StringBuilder log)
        {
            if (dwAddress > m_dwCodeSize) // check we haven't gone over our code size
                return 0x7FFFFFFF;
            if ((dwAddress >> 14) > page) //Switch pages if needed
            {
                page++;
                reader.BaseStream.Position = m_ppCodePages[page];
            }

            byte op = reader.ReadByte();
            if (op > 155)
            {
                log.Append(string.Format("ERROR: invalid opcode {0:d}", op));
                return 0x7FFFFFFF;
            }

            if (op == 45)  // enter
                log.Append(string.Format("{0:X6}: === sub_{0:X6} ==========\n", dwAddress));
            //log.Append(string.Format("{0:X6}:\t{1:d3}\t{2:s}\t", dwAddress, op, ops[op].Name));
            log.Append(string.Format("{0:s}\t",ops[op].Name));
            int l = ops[op].Length;


            // prepare opcode parameter(s)
            scrArg arg;
            // set defaults to keep c# compiler quiet
            arg.bValue3 = 0;
            arg.bValue2 = 0;
            arg.bValue1 = 0;
            arg.bValue0 = 0;
            arg.dwValue = 0;
            arg.fValue = 0;
            arg.nValue = 0;
            arg.sValue = 0;
            arg.wValue = 0;
            switch (l)
            {
                case 5: // usually DWORD or float
                    arg.bValue3 = reader.ReadByte();
                    arg.bValue2 = reader.ReadByte();
                    arg.bValue1 = reader.ReadByte();
                    arg.bValue0 = reader.ReadByte();
                    break;
                case 4: // 3-byte int or 3 1-byte ints
                    arg.bValue3 = 0;
                    arg.bValue2 = reader.ReadByte();
                    arg.bValue1 = reader.ReadByte();
                    arg.bValue0 = reader.ReadByte();
                    break;
                case 3: // short or two 1-byte ints
                    arg.bValue3 = 0;
                    arg.bValue2 = 0;
                    arg.bValue1 = reader.ReadByte();
                    arg.bValue0 = reader.ReadByte();
                    break;
                case 2: // BYTE
                    arg.dwValue = 0;
                    arg.bValue0 = reader.ReadByte();
                    break;
            }

            // print 
            switch (op)
            {
                case 37:    // ipush1
                    log.Append(string.Format("ipush\t{0:d}", arg.bValue0));
                    break;
                case 38:
                    log.Append(string.Format("ipush\t{0:d}, {1:d}", arg.bValue1, arg.bValue0));
                    break;
                case 39:
                    log.Append(string.Format("ipush\t{0:d}, {1:d}, {2:d}", arg.bValue2, arg.bValue1, arg.bValue0));
                    break;
                case 40:    // ipush
                    log.Append(string.Format("ipush\t{0:d}", arg.nValue));
                    break;
                case 41:    // fpush
                    log.Append(string.Format("fpush\t{0:f}", arg.fValue));
                    break;
                case 44:
                    {
                        int index = ((arg.bValue1 << 2) & 0x300) | arg.bValue0;
                        log.Append(string.Format("native\t{0:X4} => {1:d}:${2:X8}, ({3:d}):{4:d}", arg.wValue, index, index < m_dwNativeSize ? m_ppNatives[index] : 0, (arg.bValue1 & 0x3E) >> 1, arg.bValue1 & 1));    // TODO: get hash from .native seg
                    }
                    break;
                case 45:
                    arg.bValue3 = reader.ReadByte();
                    arg.bValue2 = reader.ReadByte();
                    arg.bValue1 = reader.ReadByte();
                    arg.bValue0 = reader.ReadByte();
                    log.Append(string.Format("enter\t{0:d} 0x{1:X} {2:d} ", arg.bValue3, (arg.bValue2 << 8) | arg.bValue1, arg.bValue0));
                    if (arg.bValue0 > 0)
                    {
                        // printf (" WARNING: 'enter' last parameter != 0 " );
                        for (int i = 1; i < arg.bValue0; i++)
                            log.Append(string.Format("{0:d}", reader.ReadByte()));
                        //putc(dwPage[dwAddressLow + 5 + i], stdout);
                    }
                    l = 5 + arg.bValue0;
                    break;
                case 46:
                    log.Append(string.Format("ret  \t{0:d} {1:d}", arg.bValue1, arg.bValue0));
                    break;
                case 52:    // parray
                case 53:    // arrayget1
                case 54:    // arrayset1
                case 55:    // pframe1
                case 56:    // frameget
                case 57:    // frameset
                case 58:    // stackgetp
                case 59:    // stackget
                case 60:    // stackset
                case 61:    // iaddimm1
                case 62:    // pgetimm1
                case 63:    // psetimm1
                case 64:    // imulimm1
                    log.Append(string.Format("{0:d}", arg.bValue0));
                    break;
                case 65:    // ipush2
                case 66:    // iaddimm2
                    log.Append(string.Format("{0:d}", arg.wValue));
                    break;
                case 67:    // pgetimm2
                case 68:    // psetimm2
                    log.Append(string.Format("0x{0:X}", arg.wValue));
                    break;
                case 69:    // imilimm2
                    log.Append(string.Format("{0:d}", arg.wValue));
                    break;
                case 70:    // arraygetp2
                case 71:    // arrayget2
                case 72:    // arrayset2
                case 73:    // pframe2
                case 74:    // frameget2
                case 75:    // frameset2
                case 76:    // pstatic2
                case 77:    // staticget2
                case 78:    // staticset2
                case 79:    // pglobal2
                case 80:    // globalget2
                case 81:    // globalset2
                    log.Append(string.Format("0x{0:X}", arg.wValue));
                    break;
                case 82:    // call2h0
                case 83:
                case 84:
                case 85:
                case 86:
                case 87:
                case 88:
                case 89:
                case 90:
                case 91:
                case 92:
                case 93:
                case 94:
                case 95:
                case 96:
                case 97:    // call2hf
                    log.Append(string.Format("call \t#{0:X}", ((op - 82) << 16) | arg.wValue));
                    break;
                case 98:    // jr2
                case 99:    // jfr2
                case 100:   // jner2
                case 101:   // jeqr2
                case 102:   // jler2
                case 103:   // jltr2
                case 104:   // jger2:
                case 105:   // jgtr2
                    log.Append(string.Format("{0:d} => #{0:X}", arg.sValue, dwAddress + 3 + arg.sValue));  // TODO: calculate target
                    break;
                case 106:   // pglobal3
                    log.Append(string.Format("pglobal\t{0:X}", arg.dwValue));
                    break;
                case 107:   // globalget3
                    log.Append(string.Format("getg\t{0:X}", arg.dwValue));
                    break;
                case 108:   // globalget3
                    log.Append(string.Format("setg\t{0:X}", arg.dwValue));
                    break;
                case 109:   // ipush3
                    log.Append(string.Format("ipush\t{0:d}", arg.dwValue));
                    break;
                //    { "switchr2", 0 },  // 110  length = 2 + byte[1]*6
                case 110:   // TODO: calculate targets
                    {
                        arg.bValue0 = reader.ReadByte();
                        l = 2 + arg.bValue0 * 6;
                        log.Append(string.Format("[{0:d}]: ", arg.bValue0));
                        for (int i = 0; i < arg.bValue0; i++)
                        {
                            //int off = (int)reader.BaseStream.Position + (i * 6);
                            //reader.BaseStream.Position = off;
                            int value = (reader.ReadByte() << 24) + (reader.ReadByte() << 16) + (reader.ReadByte() << 8) + reader.ReadByte();
                            int target = (reader.ReadByte() << 8) + reader.ReadByte();
                            log.Append(string.Format("<{0:d}, {1:d} => #{2:X}>", value, target, target + reader.BaseStream.Position));
                        }
                    }
                    break;
                case 111:
                    arg.bValue0 = reader.ReadByte();
                    l = arg.bValue0 + 2;
                    log.Append(string.Format("spush\t[0x{0:X}] '{1}'", arg.bValue0, readString(reader, arg.bValue0)));
                    break;
                case 112:
                    arg.bValue3 = reader.ReadByte();
                    arg.bValue2 = reader.ReadByte();
                    arg.bValue1 = reader.ReadByte();
                    arg.bValue0 = reader.ReadByte();
                    l = (int)(arg.nValue + 5);
                    log.Append(string.Format("spush\t[0x{0:X}] '{1}'", arg.dwValue, readString(reader, arg.nValue)));
                    break;
                //    { "spush0", 1   },  // 113  push ""
                case 114:   // scpy
                case 115:   // itos
                case 116:   // sadd
                case 117:   // saddi
                    log.Append(string.Format("[{0:d}]", arg.bValue0));
                    break;
                case 122:
                case 123:
                case 124:
                case 125:
                case 126:
                case 127:
                case 128:
                case 129: // ret0r0 .. ret1r3
                case 130:
                case 131:
                case 132:
                case 133:
                case 134:
                case 135:
                case 136:
                case 137: // ret2r0 .. ret3r3
                    log.Append(string.Format("ret  \t{0:d} {1:d}", (op - 122) >> 2, (op - 122) & 3));
                    break;
                case 138:
                case 139:
                case 140:
                case 141:
                case 142:
                case 143:
                case 144:
                case 145:
                case 146:   // iimmn1 .. iimm7
                    log.Append(string.Format("ipush\t{0:d}", op - 139));
                    break;
                case 147:
                case 148:
                case 149:
                case 150:
                case 151:
                case 152:
                case 153:
                case 154:
                case 155:   // fimmn1 .. fimm7
                    log.Append(string.Format("fpush\t{0:f}", op - 148.0f));
                    break;
            }
            log.Append("\n");
            return dwAddress + l;
        }
Example #9
0
 private ArrayList getStatics(BigEndianBinaryReader reader)
 {
     long returnpos = reader.BaseStream.Position + 4;
     reader.BaseStream.Position = (reader.ReadInt32() & 0xFFFFFF);
     ArrayList statics = new ArrayList();
     for (int i = 0; i < m_dwStaticSize; i++)
     {
         statics.Add(reader.ReadInt32());
     }
     reader.BaseStream.Position = returnpos;
     return statics;
 }
Example #10
0
 private ArrayList getNatives(BigEndianBinaryReader reader)
 {
     long returnpos = reader.BaseStream.Position + 4;
     reader.BaseStream.Position = (reader.ReadInt32() & 0xFFFFFF);
     ArrayList Natives = new ArrayList();
     for (int i = 0; i < m_dwNativeSize; i++)
     {
         Natives.Add(reader.ReadInt32());
     }
     reader.BaseStream.Position = returnpos;
     return Natives;
 }
Example #11
0
 private int readPPByte(BigEndianBinaryReader reader)
 {
     long returnpos = reader.BaseStream.Position + 4;
     reader.BaseStream.Position = (reader.ReadInt32() & 0xFFFFFF);
     reader.BaseStream.Position = (reader.ReadInt32() & 0xFFFFFF);
     int val = reader.ReadByte();
     reader.BaseStream.Position = returnpos;
     return val;
 }
Example #12
0
 private int[] getPages(BigEndianBinaryReader reader, int offset)
 {
     reader.BaseStream.Position = offset;
     int[] pages = new int[(m_dwCodeSize + (1 << 14) - 1) >> 14];
     for (int i = 0; i < pages.Length; i++)
     {
         pages[i] = reader.ReadInt32() & 0xFFFFFF;
     }
     return pages;
 }
Example #13
0
 private string readString(BigEndianBinaryReader reader, int length)
 {
     byte[] stringarray = new byte[length];
     for (int i = 0; i < length; i++)
     {
         stringarray[i] = reader.ReadByte();
     }
     return System.Text.Encoding.UTF8.GetString(stringarray).Substring(0, length-1);
 }
Example #14
0
        public StringBuilder Decode()
        {
            StringBuilder log = new StringBuilder();
            MemoryStream ms = new MemoryStream(data);
            using (BigEndianBinaryReader reader = new BigEndianBinaryReader(ms))
            {
                try
                {
                    ////////////////////
                    //Find Header
                    ////////////////////
                    bool valid;
                    try
                    {
                        valid = false;
                        dwClassOffset = 0;
                        reader.BaseStream.Position = 0;
                        while (dwClassOffset < reader.BaseStream.Length)
                        {
                            if (reader.ReadInt32() == -1462287616) //0x43D7A8
                            {
                                valid = true;
                                break;
                            }
                            dwClassOffset += 4096;
                            reader.BaseStream.Position = dwClassOffset;
                        }
                        reader.BaseStream.Position = 0;
                    }
                    catch (System.Exception ex)
                    {
                        log.AppendLine("Error: Failed to Find Header");
                        return log;
                    }
                    log.AppendLine(string.Format("TRACE: length = {0}, valid = {1}, offset = 0x{2:X}\n", reader.BaseStream.Length, valid ? "true" : "false", dwClassOffset));
                    if (!valid)
                    {
                        log.AppendLine("Error: Invalid XSC File");
                        return log;
                    }

                    ////////////////////
                    //Read Header
                    ////////////////////
                    try
                    {
                        reader.BaseStream.Position = dwClassOffset + 4;
                        this.m_pPageMap = reader.ReadInt32();
                        int temp_codePagesOffset = (reader.ReadInt32() & 0xFFFFFF); // Just get pages offset until we have code size
                        this.m_dwCodeSize = reader.ReadInt32();
                        this._f10 = reader.ReadInt32();
                        this.m_dwStaticSize = reader.ReadInt32();
                        this.m_pStatic = getStatics(reader);
                        this.m_dwGlobalsVersion = reader.ReadInt32();
                        this.m_dwNativeSize = reader.ReadInt32();
                        this.m_ppNatives = getNatives(reader);

                        this.m_ppCodePages = getPages(reader, temp_codePagesOffset); // go back and get pages
                        for (int i = 0; i < m_ppCodePages.Length; i++)
                        {
                            log.AppendLine(string.Format("TRACE: page {0:d}: offset = {1:X}\n", i, m_ppCodePages[i]));
                        }
                        lb_natives.Items.AddRange(this.m_ppNatives.ToArray());
                        lb_locals.Items.AddRange(this.m_pStatic.ToArray());
                    }
                    catch
                    {
                        log.AppendLine("Error: Failed reading Header");
                        return log;
                    }

                    ////////////////////
                    //Read opcodes
                    ////////////////////
                    try
                    {
                        page = 0;
                        reader.BaseStream.Position = m_ppCodePages[0];
                        StringBuilder script = new StringBuilder();
                        for (int i = 0; i < m_dwCodeSize; i = disassembleCommand(reader, i, script)) ;
                        codeBox.Text = script.ToString();
                    }
                    catch
                    {
                        log.AppendLine("Error: Failed reading opcodes");
                        return log;
                    }
                }
                catch
                {
                    log.AppendLine("Error: Failed reading XSC file");
                    return log;
                }
                return log;
            }
        }
Example #15
0
        public RSCFile(Stream input)
        {
            this.xscStream = input;
            using (BigEndianBinaryReader reader = new BigEndianBinaryReader(this.xscStream))
            {
                string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\xcompress32.dll";
                if (!System.IO.File.Exists(path))
                {
                    MessageBox.Show("xcompress32.dll not found the RPFTool directory.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    fileData = null;
                    return;
                }
                hdr.ReadHeader(reader);
                byte[] buffer;
                switch (hdr.m_dwMagic)
                {
                    case -2059185326:
                        if (hdr.m_dwVersion == 2)
                        {
                            reader.BaseStream.Position = 16;
                            buffer = reader.ReadBytes((int)reader.BaseStream.Length - 16);
                            buffer = DataUtil.Decrypt(buffer);
                            using (BigEndianBinaryReader readerFile = new BigEndianBinaryReader(new MemoryStream(buffer)))
                            {
                                fileData = new byte[hdr.getSizeV() + hdr.getSizeP()];
                                readerFile.BaseStream.Position = 8;
                                if (Decompress(readerFile.ReadBytes((int)readerFile.BaseStream.Length), fileData) == -1)
                                {
                                    MessageBox.Show("Failed to decompress file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                    fileData = null;
                                }
                            }
                        }
                        else
                        {
                            reader.BaseStream.Position = 16;
                            buffer = reader.ReadBytes((int)reader.BaseStream.Length - 16);
                            using (BigEndianBinaryReader readerFile = new BigEndianBinaryReader(new MemoryStream(buffer)))
                            {
                                fileData = new byte[hdr.getSizeV() + hdr.getSizeP()];
                                readerFile.BaseStream.Position = 8;
                                if (Decompress(readerFile.ReadBytes((int)readerFile.BaseStream.Length), fileData) == -1)
                                {
                                    MessageBox.Show("Failed to decompress file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                                    fileData = null;
                                }
                            }
                        }
                        break;
                    case 88298322:
                        reader.BaseStream.Position = 20;
                        buffer = reader.ReadBytes((int)reader.BaseStream.Length - 20);
                        fileData = new byte[hdr.getSizeV() + hdr.getSizeP()];
                        if (Decompress(buffer, fileData) == -1)
                        {
                            MessageBox.Show("Failed to decompress file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            fileData = null;
                        }
                        //System.IO.File.WriteAllBytes(@"Z:\D\Downloads\gms\RDR", fileData);
                        break;
                    default:
                        MessageBox.Show("Unrecognised header", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        fileData = null;
                        break;

                }
            }
        }
Example #16
0
        public override void Read(BigEndianBinaryReader br, int extra = 0)
        {
            try
            {
                NameOffset = br.ReadInt32();
                SizeInArchive = br.ReadInt32();
                Offset = br.ReadInt32();
                Flags1 = br.ReadInt32();
                Flags2 = br.ReadInt32();
                //int test = (int)(Flags1 & 0x80000000);
                //string bits1 = GetIntBinaryString(Flags1);
                IsResourceFile = (Flags1 & 0x80000000) == 0x80000000;
                IsCompressed = (Flags1 & 0x40000000) == 0x40000000;
                DecompressedSize = (int)(Flags1 & 0xbfffffff);

                if (IsResourceFile)
                {
                    //Flags2 = (int)swap32(Flags2);
                    ResourceType = (byte)(Offset & 0xFF);
                    Offset = (Offset & 0x7fffff00) * 8;
                    dwExtVSize = (int)(Flags2 & 0x7FFF);
                    dwExtPSize = (int)((Flags2 & 0xFFF7000) >> 14);
                    _f14_30 = (int)(Flags2 & 0x70000000);
                    bUseExtSize = (Flags2 & 0x80000000) == 0x80000000 ? true : false;
                    DecompressedSize = (int)(getSizeV() + getSizeP());
                    if (Offset % 2048 != 0)
                    {
                        Debug.Print("Invalid Resource Offset");
                    }
                }
                else
                    Offset = Offset * 8;

                /////////////////////////
                // Couple of debug checks
                /////////////////////////
                /*
                #if DEBUG
                {
                    if (IsResourceFile)
                    {
                        if (Offset % 2048 != 0)
                        {
                            Debug.Print("Invalid Resource Offset");
                        }
                        string bits = GetIntBinaryString(Flags2);
                        int SizeV = getSizeV();
                        int SizeP = getSizeP();
                        int objectStart = getObjectStart();
                    }
                    else
                    {
                        if (Offset % 8 != 0)
                        {
                            Debug.Print("Invalid File Offset");
                        }
                    }
                }
                #endif
                 */

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Example #17
0
 public abstract void Read(BigEndianBinaryReader br, int extra = 0);