Пример #1
0
        public void ReWriteOpcodes(ParsedContent parsedContent)
        {
            using (MemoryStream memoryStream = new MemoryStream(Contents))
            {
                using (BinaryWriter writer = new BinaryWriter(memoryStream))
                {
                    writer.BaseStream.Position = 268;
                    writer.Write(parsedContent.BaseAddress);

                    //make sure we are at start of opcodes
                    writer.BaseStream.Position = parsedContent.StartOfOpCodes;

                    foreach (Operation op in parsedContent.OpCodeList)
                    {
                        //write the
                        writer.Write((byte)op.OpCode);

                        if (op.DataIndex != null)
                        {
                            writer.Write((Int16)op.DataIndex.Value);
                        }
                    }
                }
            }
        }
Пример #2
0
        public ParsedContent Parse()
        {
            ParsedContent parsedContent = new ParsedContent();

            parsedContent.OriginalFile = this;

            using (MemoryStream memoryStream = new MemoryStream(Contents))
            {
                using (BinaryReader reader = new BinaryReader(memoryStream, Encoding.GetEncoding(1252)))
                {
                    parsedContent.ScriptName = this.ReadString(reader);
                    //Console.Write("Decompiling {0}...", parsedContent.ScriptName);

                    reader.BaseStream.Position = 256;

                    parsedContent.LengthOfOpCodes = reader.ReadInt32();
                    //Console.Write("LengthOfOpCodes: {0}", parsedContent.LengthOfOpCodes);

                    parsedContent.StartOfOpCodes = reader.ReadInt32();
                    //Console.Write(", StartOfOpCodes: {0}", parsedContent.StartOfOpCodes);

                    parsedContent.NumberOfValues = reader.ReadInt32();
                    //Console.Write(", NumberOfValues: {0}", parsedContent.NumberOfValues);

                    parsedContent.BaseAddress = (Int16)reader.ReadInt32();
                    //Console.Write(", BaseAddress: {0}", parsedContent.BaseAddress);
                    if (parsedContent.BaseAddress == 430)
                    {
                        parsedContent.IsOldFile = true;
                    }

                    parsedContent.StartOfValues = reader.ReadInt32();
                    //Console.WriteLine(", StartOfValues in file: {0}", parsedContent.StartOfValues);

                    //make sure we are at start of opcodes
                    //reader.BaseStream.Position = parsedContent.StartOfOpCodes;
                    //parsedContent.OpCodeList = new List<Operation>();
                    //read through NumberOfSomething
                    //for (int i = 0; i < (parsedContent.LengthOfOpCodes / 4); i++)
                    //{
                    //    Unknown1 unknown1 = new Unknown1();
                    //    unknown1.PossibleAddress = reader.ReadInt16();
                    //    unknown1.UnknownByte1 = reader.ReadByte();
                    //    unknown1.UnknownByte2 = reader.ReadByte();

                    //    parsedContent.Unknown1List.Add(unknown1);
                    //}



                    ParseValues(parsedContent, reader);

                    ParseOpCodes(parsedContent, reader);

                    //Console.WriteLine("OK");
                }
            }

            return(parsedContent);
        }
Пример #3
0
        private void ParseOpCodes(ParsedContent parsedContent, BinaryReader reader)
        {
            int endOfOpcodes = parsedContent.StartOfOpCodes + parsedContent.LengthOfOpCodes;

            //make sure we are at start of opcodes
            reader.BaseStream.Position = parsedContent.StartOfOpCodes;
            parsedContent.OpCodeList   = new List <Operation>();

            //read through commmands
            while (reader.BaseStream.Position < endOfOpcodes)
            {
                Operation op = new Operation();
                op.Address = (short)(reader.BaseStream.Position - parsedContent.StartOfOpCodes);

                op.OpCode = (OpCodeType)reader.ReadByte();

                //push has an index parameter
                if (op.OpCode == OpCodeType.OP_PUSH ||
                    op.OpCode == OpCodeType.OP_GETTOP)
                {
                    //op.Parameters.Add(reader.ReadInt16());
                    op.DataIndex       = new DataIndex();
                    op.DataIndex.Value = reader.ReadInt16();
                    if (op.DataIndex.Value < parsedContent.BaseAddress)
                    {
                        op.DataIndex.IsFunctionPointer = true;
                    }
                }
                else if (op.OpCode == OpCodeType.OP_JMP ||
                         op.OpCode == OpCodeType.OP_JMPF ||
                         op.OpCode == OpCodeType.JUMPTARGET)
                {
                    //op.Parameters.Add(reader.ReadInt16());
                    op.DataIndex       = new DataIndex();
                    op.DataIndex.Value = reader.ReadInt16();
                }

                //else if (op.OpCode == OpCodeType.OP_FUNCTION)
                //{
                //    //set last push as a function pointer
                //    parsedContent.OpCodeList[parsedContent.OpCodeList.Count].IsFunctionPointer = true;
                //}

                //add operation to list
                parsedContent.OpCodeList.Add(op);
            }
        }
Пример #4
0
        private static void DisplayOpCodes(ParsedContent parsedContent)
        {
            foreach (Operation op in parsedContent.OpCodeList)
            {
                if (op.DataIndex != null)
                {
                    Console.Write("[{0}] {1}", op.Address, op.OpCode);

                    if (op.DataIndex.IsFunctionPointer)
                    {
                        //if (parsedContent.IsOldFile)
                        //{
                        //    //OldFunctionType oft = (OldFunctionType)op.DataIndex.Value;
                        //    string oldFunction;
                        //    if (FunctionTable.Functions.ContainsKey(op.DataIndex.Value))
                        //    {
                        //        oldFunction = FunctionTable.Functions[op.DataIndex.Value];
                        //    }
                        //    else
                        //    {
                        //        oldFunction = "?";
                        //    }

                        //    Console.WriteLine(string.Format(" -> {0} ({1})", op.DataIndex.Value, oldFunction));
                        //}
                        //else
                        //{
                        string newFunction;
                        if (FunctionTable.Functions.ContainsKey(op.DataIndex.Value))
                        {
                            newFunction = FunctionTable.Functions[op.DataIndex.Value];
                        }
                        else
                        {
                            newFunction = "?";
                        }

                        //NewFunctionType nft = (NewFunctionType)op.DataIndex.Value;
                        Console.WriteLine(string.Format(" -> {0} ({1})", op.DataIndex.Value, newFunction));
                        //}
                    }
                    else
                    {
                        var qValue = from value in parsedContent.ValuesList
                                     where value.Address == op.DataIndex.Value
                                     select value;
                        Value v = qValue.FirstOrDefault();
                        if (v != null)
                        {
                            Console.WriteLine(" -> {0} [{1}] ({2})", op.DataIndex.Value, v.DataType, v.SubValues[0]);
                        }
                        else
                        {
                            Console.WriteLine(" -> " + op.DataIndex.Value.ToString());
                        }
                    }

                    if (op.OpCode == OpCodeType.OP_JMP ||
                        op.OpCode == OpCodeType.OP_JMPF)
                    {
                        Console.WriteLine();
                    }
                }
                else
                {
                    Console.WriteLine("[{0}] {1}", op.Address, op.OpCode);
                    if (op.OpCode == OpCodeType.OP_PRINT ||
                        op.OpCode == OpCodeType.OP_DISCARD)
                    {
                        Console.WriteLine();
                    }
                }
            }
        }
Пример #5
0
        private void BuildNewMemory(BinFile binFile, ParsedContent parsedContent)
        {
            Console.WriteLine("Building new memory...");


            Console.WriteLine("Writing name.");
            int nameLength = parsedContent.ScriptName.Length;

            newContent.Clear();
            char[] name = parsedContent.ScriptName.ToCharArray();
            foreach (char c in name)
            {
                newContent.Add((byte)c);
            }
            newContent.Add(0x00);
            for (int i = 0; i < 255 - nameLength; i++)
            {
                newContent.Add(0xCD);
            }

            Console.WriteLine("Writing stub values.");

            int opCount = 0;

            //opcodes
            foreach (Operation op in parsedContent.OpCodeList)
            {
                opCount++;

                if (op.DataIndex != null)
                {
                    opCount += 2;
                }
            }

            foreach (Byte b in BitConverter.GetBytes((Int32)opCount))
            {
                newContent.Add(b);
            }

            //startofcodes
            foreach (Byte b in BitConverter.GetBytes((Int32)276))
            {
                newContent.Add(b);
            }

            //numberofvalues
            foreach (Byte b in BitConverter.GetBytes((Int32)parsedContent.ValuesList.Count))
            {
                newContent.Add(b);
            }

            //base address
            foreach (Byte b in BitConverter.GetBytes((Int32)760))
            {
                newContent.Add(b);
            }

            //startofvalues
            foreach (Byte b in BitConverter.GetBytes((Int32)opCount + 276))
            {
                newContent.Add(b);
            }

            //write the opcodes
            foreach (Operation op in parsedContent.OpCodeList)
            {
                newContent.Add((byte)op.OpCode);
                if (op.DataIndex != null)
                {
                    byte[] dataIndex = BitConverter.GetBytes(op.DataIndex.Value);
                    foreach (byte b in dataIndex)
                    {
                        newContent.Add(b);
                    }
                }
            }

            //write the value list
            foreach (Value value in parsedContent.ValuesList)
            {
                newContent.Add((byte)value.DataType);
                if (value.DataType == DataTypeType.Character ||
                    value.DataType == DataTypeType.String ||
                    value.DataType == DataTypeType.Point ||
                    value.DataType == DataTypeType.Quaternion)
                {
                    byte[] refBytes = BitConverter.GetBytes(value.Reference);
                    foreach (byte b in refBytes)
                    {
                        newContent.Add(b);
                    }
                }
                else if (value.DataType == DataTypeType.Int ||
                         value.DataType == DataTypeType.Float)
                {
                    byte[] valueBytes = BitConverter.GetBytes((Int32)value.SubValues[0]);
                    foreach (byte b in valueBytes)
                    {
                        newContent.Add(b);
                    }
                }
            }

            //write the references
            foreach (Value value in parsedContent.ValuesList)
            {
                //if (value.DataType == DataTypeType.Character
                //    || value.DataType == DataTypeType.String
                //    || value.DataType == DataTypeType.Point
                //    || value.DataType == DataTypeType.Quaternion)
                //{
                //    foreach (object o in value.SubValues)
                //    {
                //        byte[] oBytes = BitConverter.GetBytes(o);
                //        foreach (byte b in oBytes)
                //        {
                //            newContent.Add(b);
                //        }
                //    }
                //}
                if (value.DataType == DataTypeType.Character)
                {
                    byte[] characterBytes = BitConverter.GetBytes((Int32)value.SubValues[0]);
                    foreach (byte b in characterBytes)
                    {
                        newContent.Add(b);
                    }
                    newContent.Add((byte)0x00);
                    char[] characters = ((string)value.SubValues[1]).ToCharArray();
                    foreach (char c in characters)
                    {
                        newContent.Add((byte)c);
                    }
                    newContent.Add((byte)0x00);

                    characterBytes = BitConverter.GetBytes((Int32)value.SubValues[2]);
                    foreach (byte b in characterBytes)
                    {
                        newContent.Add(b);
                    }
                }
                else if (value.DataType == DataTypeType.String)
                {
                    char[] characters = ((string)value.SubValues[0]).ToCharArray();
                    foreach (char c in characters)
                    {
                        newContent.Add((byte)c);
                    }
                    newContent.Add((byte)0x00);
                }
                else if (value.DataType == DataTypeType.Point)
                {
                    byte[] characterBytes = BitConverter.GetBytes((Int32)value.SubValues[0]);
                    foreach (byte b in characterBytes)
                    {
                        newContent.Add(b);
                    }
                    characterBytes = BitConverter.GetBytes((Int32)value.SubValues[1]);
                    foreach (byte b in characterBytes)
                    {
                        newContent.Add(b);
                    }
                    characterBytes = BitConverter.GetBytes((Int32)value.SubValues[2]);
                    foreach (byte b in characterBytes)
                    {
                        newContent.Add(b);
                    }
                }
                else if (value.DataType == DataTypeType.Quaternion)
                {
                    byte[] characterBytes = BitConverter.GetBytes((Int32)value.SubValues[0]);
                    foreach (byte b in characterBytes)
                    {
                        newContent.Add(b);
                    }
                    characterBytes = BitConverter.GetBytes((Int32)value.SubValues[1]);
                    foreach (byte b in characterBytes)
                    {
                        newContent.Add(b);
                    }
                    characterBytes = BitConverter.GetBytes((Int32)value.SubValues[2]);
                    foreach (byte b in characterBytes)
                    {
                        newContent.Add(b);
                    }
                    characterBytes = BitConverter.GetBytes((Int32)value.SubValues[3]);
                    foreach (byte b in characterBytes)
                    {
                        newContent.Add(b);
                    }
                }
            }

            //convert to byte[]
            byte[] newFile = newContent.ToArray();

            Console.WriteLine("Saving new file...");
            binFile.Save(true, newFile);
            Console.WriteLine("OK.");
        }
Пример #6
0
        private void ParseValues(ParsedContent parsedContent, BinaryReader reader)
        {
            //make sure we are at start of values
            reader.BaseStream.Position = parsedContent.StartOfValues;
            parsedContent.ValuesList   = new List <Value>();


            //read through commmands
            for (short i = 0; i < parsedContent.NumberOfValues; i++)
            {
                Value value = new Value()
                {
                    Address  = (short)(parsedContent.BaseAddress + i),
                    DataType = (DataTypeType)reader.ReadByte()
                };
                if (value.DataType == DataTypeType.Character ||
                    value.DataType == DataTypeType.String ||
                    value.DataType == DataTypeType.Point ||
                    value.DataType == DataTypeType.Quaternion)
                {
                    //always a reference
                    value.Reference = reader.ReadInt32();

                    long position = reader.BaseStream.Position;

                    //move to reference
                    reader.BaseStream.Position = value.Reference;
                    if (value.DataType == DataTypeType.String)
                    {
                        //print has one char reference
                        value.SubValues.Add(this.ReadString(reader));
                    }
                    else if (value.DataType == DataTypeType.Character)
                    {
                        if (i == 0)
                        {
                            value.IsMe = true;
                        }
                        else if (i == 1)
                        {
                            value.IsPlayer = true;
                        }
                        //print has one char reference
                        value.SubValues.Add((Int32)reader.ReadInt32());
                        reader.ReadByte(); //a zero here
                        value.SubValues.Add(this.ReadString(reader));
                        value.SubValues.Add((Int32)reader.ReadInt32());
                    }
                    else if (value.DataType == DataTypeType.Point)
                    {
                        //x, y, z floats
                        value.SubValues.Add((Int32)reader.ReadInt32());
                        value.SubValues.Add((Int32)reader.ReadInt32());
                        value.SubValues.Add((Int32)reader.ReadInt32());
                    }
                    else if (value.DataType == DataTypeType.Quaternion)
                    {
                        //x, y, z floats
                        value.SubValues.Add((Int32)reader.ReadInt32());
                        value.SubValues.Add((Int32)reader.ReadInt32());
                        value.SubValues.Add((Int32)reader.ReadInt32());
                        value.SubValues.Add((Int32)reader.ReadInt32());
                    }

                    //go back to correct position
                    reader.BaseStream.Position = position;
                }
                else if (value.DataType == DataTypeType.Int ||
                         value.DataType == DataTypeType.Float)
                {
                    value.Reference = (Int32)(reader.BaseStream.Position);
                    // no params
                    value.SubValues.Add(reader.ReadInt32());
                }



                parsedContent.ValuesList.Add(value);
            }
        }