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); } } } } }
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); }
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); } }
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(); } } } }
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."); }
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); } }