diff --git a/.vs/CXMLCli/FileContentIndex/9879c506-10a9-4679-9588-ed45874348ed.vsidx b/.vs/CXMLCli/FileContentIndex/9879c506-10a9-4679-9588-ed45874348ed.vsidx new file mode 100644 index 0000000..7b7d8b6 Binary files /dev/null and b/.vs/CXMLCli/FileContentIndex/9879c506-10a9-4679-9588-ed45874348ed.vsidx differ diff --git a/.vs/CXMLCli/FileContentIndex/cec99b14-26f5-4a9c-980f-27f5b2f8771f.vsidx b/.vs/CXMLCli/FileContentIndex/cec99b14-26f5-4a9c-980f-27f5b2f8771f.vsidx new file mode 100644 index 0000000..da755bb Binary files /dev/null and b/.vs/CXMLCli/FileContentIndex/cec99b14-26f5-4a9c-980f-27f5b2f8771f.vsidx differ diff --git a/.vs/CXMLCli/FileContentIndex/read.lock b/.vs/CXMLCli/FileContentIndex/read.lock new file mode 100644 index 0000000..e69de29 diff --git a/.vs/CXMLCli/v17/.suo b/.vs/CXMLCli/v17/.suo new file mode 100644 index 0000000..5dfaa8f Binary files /dev/null and b/.vs/CXMLCli/v17/.suo differ diff --git a/CXMLCli/CXMLCli.csproj b/CXMLCli/CXMLCli.csproj index 01a2170..cbcae8e 100644 --- a/CXMLCli/CXMLCli.csproj +++ b/CXMLCli/CXMLCli.csproj @@ -1,112 +1,113 @@ - - - - - Debug - AnyCPU - {BE72E673-25FF-47AB-AF5B-9448B69E3990} - Exe - CXMLDecompiler - CXMLDecompiler - v4.6.1 - 512 - true - true - - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - true - bin\x64\Debug\ - DEBUG;TRACE - full - x64 - prompt - MinimumRecommendedRules.ruleset - true - - - bin\x64\Release\ - TRACE - true - pdbonly - x64 - prompt - MinimumRecommendedRules.ruleset - true - - - true - bin\x86\Debug\ - DEBUG;TRACE - full - x86 - prompt - MinimumRecommendedRules.ruleset - true - - - bin\x86\Release\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset - true - - - cxml.ico - - - - ..\packages\DotNetZip.1.13.3\lib\net40\DotNetZip.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + AnyCPU + {BE72E673-25FF-47AB-AF5B-9448B69E3990} + Exe + CXMLDecompiler + CXMLDecompiler + v4.6.1 + 512 + true + true + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + true + + + cxml.ico + + + + ..\packages\DotNetZip.1.13.3\lib\net40\DotNetZip.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CXMLCli/CXMLReader.cs b/CXMLCli/CXMLReader.cs index f04c60b..09170d4 100644 --- a/CXMLCli/CXMLReader.cs +++ b/CXMLCli/CXMLReader.cs @@ -1,13 +1,14 @@ using Ionic.Zlib; +using General; + using System; using System.Collections.Generic; using System.Diagnostics; -using General; using System.IO; using System.Text; using System.Xml; using System.Globalization; - + namespace CXML { @@ -67,6 +68,7 @@ namespace CXML List SilicaTypingInformationList = new List(); + String MagicReplacePattern = Tools.GenerateReplacePattern(); String SilicaTypingInformation = "SilicaTypingInformation{{[["; FileStream InfoFile; @@ -89,16 +91,9 @@ namespace CXML BinaryReader bHashIDTable; BinaryReader bStringIDTable; - public class LoopbackHandler - { - public String FileName; - public String OldFileName; - public Int64 FilePointer; - } - List FileList = new List(); - XmlWriter XMLFile; + XmlWriter XMLWriter; public bool ProcessFiles = false; public bool WaitExit = false; @@ -399,16 +394,22 @@ namespace CXML XmlWriterSettings XMLSettings = new XmlWriterSettings(); XMLSettings.Indent = true; + XMLSettings.Encoding = Encoding.UTF8; + string XMLPath = Path.Combine(MainDir, XMLFilename); - XMLFile = XmlWriter.Create(XMLPath, XMLSettings); - XMLFile.WriteStartDocument(); - XMLFile.WriteComment("REPLACE_WITH_SILICATOKEN"); + + StreamWriter sw = new StreamWriter(new MemoryStream(), Encoding.UTF8); + + + XMLWriter = XmlWriter.Create(sw, XMLSettings); + XMLWriter.WriteStartDocument(); + XMLWriter.WriteComment(MagicReplacePattern); AddTypingInfo("MAGIC", MagicNumber); AddTypingInfo("VERSION", ReadVersion()); ReadElements(); - XMLFile.WriteEndDocument(); - XMLFile.Flush(); - XMLFile.Close(); + XMLWriter.WriteEndDocument(); + XMLWriter.Flush(); + XMLWriter.Close(); GotoEnd(); int bytesRemaining = Convert.ToInt32(InfoFile.Length - InfoFile.Position); @@ -432,44 +433,62 @@ namespace CXML } SilicaTypingInformation += "]]}}SilicaTypingInformation"; + byte[] XMLBytes = new byte[sw.BaseStream.Length]; - // Make corrections - string XmlData = File.ReadAllText(XMLPath, Encoding.UTF8); - XmlData = XmlData.Replace("REPLACE_WITH_SILICATOKEN", SilicaTypingInformation); + sw.Flush(); + sw.BaseStream.Seek(0x00, SeekOrigin.Begin); + sw.BaseStream.Read(XMLBytes, 0x00, XMLBytes.Length); + sw.Close(); + + string XMLData = Encoding.UTF8.GetString(XMLBytes); + + // Resolve Replace Patterns + + XMLData = XMLData.Replace(MagicReplacePattern, SilicaTypingInformation); foreach(LoopbackHandler lpHandler in FileList) - { - if(lpHandler.OldFileName != null) - { - if(lpHandler.FileName != null) - { - string oldName = Path.Combine(lpHandler.OldFileName); - string extension = Path.GetExtension(oldName); - string folderPath = Path.GetDirectoryName(oldName); - string newPath = Path.ChangeExtension(Path.Combine(folderPath, lpHandler.FileName), extension); - - if(!File.Exists(newPath)) - { - File.Move(oldName, newPath); - - string xmlRelOldPath = oldName.Substring(Tools.GetRootFolder(oldName).Length + 1); - string xmlRelNewPath = newPath.Substring(Tools.GetRootFolder(newPath).Length + 1); - Console.WriteLine("Moved " + xmlRelOldPath + " => " + xmlRelNewPath); - XmlData = XmlData.Replace(xmlRelOldPath, xmlRelNewPath); - } - - if (ProcessFiles) - ProcessFile(newPath); - } - else - { - Console.WriteLine("NOT MOVING: " + lpHandler.OldFileName); - if (ProcessFiles) - ProcessFile(lpHandler.OldFileName); - } + { + if (lpHandler.ReplacePattern != null && lpHandler.OldFileName != null) + { + + string replacePattern = lpHandler.ReplacePattern; + string oldName = lpHandler.OldFileName; + string extension = Path.GetExtension(oldName); + string folderPath = Path.GetDirectoryName(oldName); + byte[] fileData = lpHandler.FileData; + + if (lpHandler.FileName != null) + { + + string newPath = Path.ChangeExtension(Path.Combine(folderPath, lpHandler.FileName), extension); + + if (!Directory.Exists(folderPath)) + Directory.CreateDirectory(folderPath); + + if (!File.Exists(newPath)) + { + File.WriteAllBytes(newPath, fileData); + string xmlRelNewPath = newPath.Substring(Tools.GetRootFolder(newPath).Length + 1); + Console.WriteLine("Resolved " + replacePattern + " => " + xmlRelNewPath); + XMLData = XMLData.Replace(replacePattern, xmlRelNewPath); + } + + if (ProcessFiles) + ProcessFile(newPath); + } + else + { + Console.WriteLine("Unable to resolve: " + oldName); + if (!File.Exists(oldName)) + File.WriteAllBytes(oldName, fileData); + + if (ProcessFiles) + ProcessFile(oldName); + } } + } - File.WriteAllText(XMLPath, XmlData); + File.WriteAllText(XMLPath, XMLData); Term(); } @@ -493,7 +512,7 @@ namespace CXML cxmlParser.Init(FileName); cxmlParser.ProcessFiles = this.ProcessFiles; cxmlParser.MainDir = DirectoryName; - cxmlParser.FileDir = Path.Combine(cxmlParser.MainDir,"files"); + cxmlParser.FileDir = Path.Combine(cxmlParser.MainDir, "files"); cxmlParser.DecompileCXML(FileName); } catch (Exception) { }; @@ -555,7 +574,7 @@ namespace CXML } } - public void RegisterFile(Int64 ElementPtr, String NewName, Boolean FileEntry, String IdealName=null) + public void RegisterFile(Int64 ElementPtr, String NewName, Boolean FileEntry, String ReplacePattern=null, byte[] FileData=null, String IdealName=null) { Console.WriteLine("Adding Entry for Loopback: 0x" + ElementPtr.ToString("X8", CultureInfo.InvariantCulture) + " (" + NewName + ")"); for(int i = 0; i < FileList.Count; i++) @@ -583,6 +602,8 @@ namespace CXML { lpHandler.OldFileName = NewName; lpHandler.FileName = IdealName; + lpHandler.FileData = FileData; + lpHandler.ReplacePattern = ReplacePattern; } else { @@ -610,12 +631,14 @@ namespace CXML break; case AttributeType.TYPE_INT: AttributeValue = bTreeTable.ReadInt32(); - Console.WriteLine("Int - Value: " + AttributeValue.ToString() + " sz:" + bTreeTable.ReadInt32()); + int sz = bTreeTable.ReadInt32(); + Console.WriteLine("Int - Value: " + AttributeValue.ToString() + " sz:" + sz); break; case AttributeType.TYPE_FLOAT: float FloatValue = bTreeTable.ReadSingle(); AttributeValue = FloatValue.ToString("G9", CultureInfo.InvariantCulture) + "f"; - Console.WriteLine("Float - Value: " + AttributeValue.ToString() + " sz:" + bTreeTable.ReadInt32()); + sz = bTreeTable.ReadInt32(); + Console.WriteLine("Float - Value: " + AttributeValue.ToString() + " sz:" + sz); break; case AttributeType.TYPE_STRING: int StringOffset = bTreeTable.ReadInt32(); @@ -689,28 +712,18 @@ namespace CXML Byte[] FileData = new Byte[FileSz]; FileTable.Seek(FilePtr, SeekOrigin.Begin); FileTable.Read(FileData, 0, FileSz); - string FileHash = Tools.GenerateHash(FileData); - string FileSmallHash = Tools.GenerateShortHash(FileData); + + String FileHash = Tools.GenerateHash(FileData); + String FileSmallHash = Tools.GenerateShortHash(FileData); String Extension = Tools.GetFileExtension(FileData); - String FileName = Path.Combine(FileDir, "original", FilePtr.ToString("X", CultureInfo.InvariantCulture) +"-"+FileHash + Extension); + String FileName = Path.Combine(FileDir, "original", FilePtr.ToString("X", CultureInfo.InvariantCulture) + "-" + FileHash + Extension); String IdealName = ElementName + "-" + AttributeName + "-" + FileSmallHash + Extension; - if (!File.Exists(FileName)) - { - Console.WriteLine("Writing: " + FileName); + String ReplacePattern = Tools.GenerateReplacePattern(); - if (!Directory.Exists(Path.GetDirectoryName(FileName))) - Directory.CreateDirectory(Path.GetDirectoryName(FileName)); + //File.WriteAllBytes(FileName, FileData); + RegisterFile(ElementPtr, FileName, true, ReplacePattern, FileData, IdealName); - File.WriteAllBytes(FileName, FileData); - RegisterFile(ElementPtr, FileName, true, IdealName); - } - else - { - Console.WriteLine("File allready extracted."); - } - - string xmlRelPath = FileName.Substring(Tools.GetRootFolder(FileName).Length + 1); - AttributeValue = xmlRelPath; + AttributeValue = ReplacePattern; break; case AttributeType.TYPE_ID_STRING_LOOPBACK: int StringIdTableOffset = bTreeTable.ReadInt32(); @@ -725,7 +738,9 @@ namespace CXML AttributeValue = Tools.ReadString(StringIDTable); RegisterFile(LoopbackPtr, AttributeValue.ToString(), false); - Console.WriteLine("Loopback ID String: " + StringIdTableOffset + " sz: " + bTreeTable.ReadInt32()); + sz = bTreeTable.ReadInt32(); + + Console.WriteLine("Loopback ID String: " + StringIdTableOffset + " sz: " + sz); break; case AttributeType.TYPE_ID_STRING: // This is probably right, tbh StringIdTableOffset = bTreeTable.ReadInt32(); @@ -733,7 +748,8 @@ namespace CXML AttributeValue = Tools.ReadString(StringIDTable); - Console.WriteLine("ID String: " + StringIdTableOffset + " sz: " + bTreeTable.ReadInt32()); + sz = bTreeTable.ReadInt32(); + Console.WriteLine("ID String: " + StringIdTableOffset + " sz: " + sz); break; case AttributeType.TYPE_ID_INT_LOOPBACK: int IntIdTableOffset = bTreeTable.ReadInt32(); @@ -750,7 +766,8 @@ namespace CXML AttributeValue = IDValue.ToString("X8", CultureInfo.InvariantCulture); RegisterFile(LoopbackPtr, AttributeValue.ToString(), false); - Console.WriteLine("Loopback Int: " + IntIdTableOffset + " sz: " + bTreeTable.ReadInt32()); + sz = bTreeTable.ReadInt32(); + Console.WriteLine("Loopback Int: " + IntIdTableOffset + " sz: " + sz); break; case AttributeType.TYPE_ID_INT: IntIdTableOffset = bTreeTable.ReadInt32(); @@ -758,7 +775,8 @@ namespace CXML IDValue = bIntIDTable.ReadInt32(); AttributeValue = IDValue.ToString("X8", CultureInfo.InvariantCulture); - Console.WriteLine("Int Id: " + IntIdTableOffset + " sz: " + bTreeTable.ReadInt32()); + sz = bTreeTable.ReadInt32(); + Console.WriteLine("Int Id: " + IntIdTableOffset + " sz: " + sz); break; default: Console.WriteLine("UNKNOWN TYPE @ " + TreeTable.Position); @@ -768,8 +786,8 @@ namespace CXML AddTypingInfo(ElementName + ":" + AttributeName, ((int)Type).ToString(CultureInfo.InvariantCulture)); Console.WriteLine(AttributeName + "=" + AttributeValue.ToString()); - XMLFile.WriteAttributeString(AttributeName, AttributeValue.ToString()); - XMLFile.Flush(); + XMLWriter.WriteAttributeString(AttributeName, AttributeValue.ToString()); + XMLWriter.Flush(); } public void ReadElements() @@ -796,7 +814,7 @@ namespace CXML Console.WriteLine("FirstChild: " + FirstChild); Console.WriteLine("LastChild: " + LastChild); - XMLFile.WriteStartElement(ElementName); + XMLWriter.WriteStartElement(ElementName); if(NumAttributes > 0) { @@ -813,8 +831,8 @@ namespace CXML } - XMLFile.WriteEndElement(); - XMLFile.Flush(); + XMLWriter.WriteEndElement(); + XMLWriter.Flush(); if (NextSibling != -1) { diff --git a/CXMLCli/LoopbackHandler.cs b/CXMLCli/LoopbackHandler.cs new file mode 100644 index 0000000..fdc356d --- /dev/null +++ b/CXMLCli/LoopbackHandler.cs @@ -0,0 +1,13 @@ +using System; + +namespace CXML +{ + public class LoopbackHandler + { + public String FileName; + public String OldFileName; + public String ReplacePattern; + public byte[] FileData; + public Int64 FilePointer; + } +} diff --git a/CXMLCli/Tools.cs b/CXMLCli/Tools.cs index c745f3d..7ab6f7f 100644 --- a/CXMLCli/Tools.cs +++ b/CXMLCli/Tools.cs @@ -1,8 +1,5 @@ using System; -using System.Collections.Generic; using System.Drawing; -using System.Drawing.Imaging; -using System.Globalization; using System.IO; using System.Linq; using System.Security.Cryptography; @@ -13,14 +10,14 @@ namespace General class Tools { - public static byte[] bmp = Encoding.ASCII.GetBytes("BM"); // BMP - public static byte[] gif = Encoding.ASCII.GetBytes("GIF"); // GIF - public static byte[] png = new byte[] { 137, 80, 78, 71 }; // PNG - public static byte[] tiff = new byte[] { 73, 73, 42 }; // TIFF - public static byte[] tiff2 = new byte[] { 77, 77, 42 }; // TIFF - public static byte[] jpeg = new byte[] { 255, 216, 255 }; // jpeg - - + public static byte[] bmp = Encoding.ASCII.GetBytes("BM"); // BMP + public static byte[] gif = Encoding.ASCII.GetBytes("GIF"); // GIF + public static byte[] png = new byte[] { 137, 80, 78, 71 }; // PNG + public static byte[] tiff = new byte[] { 73, 73, 42 }; // TIFF + public static byte[] tiff2 = new byte[] { 77, 77, 42 }; // TIFF + public static byte[] jpeg = new byte[] { 255, 216, 255 }; // jpeg + public static Random rng = new Random(Guid.NewGuid().GetHashCode()); + public static void WriteStringToStream(Stream s, String str) { Byte[] bytes = Encoding.UTF8.GetBytes(str); @@ -46,34 +43,40 @@ namespace General stream.Seek(0, SeekOrigin.Begin); stream.Read(Bytes, 0x00, StreamLen); return Bytes; - } - - public static string GetFileExtension(byte[] Bytes) - { - if (bmp.SequenceEqual(Bytes.Take(bmp.Length))) - { - return ".bmp"; - } - else if (gif.SequenceEqual(Bytes.Take(gif.Length))) - { - return ".gif"; - } - else if (png.SequenceEqual(Bytes.Take(png.Length))) - { - return ".png"; - } - else if (tiff.SequenceEqual(Bytes.Take(tiff.Length))) - { - return ".tiff"; - } - else if (tiff2.SequenceEqual(Bytes.Take(tiff2.Length))) - { - return ".tiff"; - } - else if (jpeg.SequenceEqual(Bytes.Take(jpeg.Length))) - { - return ".jpg"; - } + } + + public static string GenerateReplacePattern() + { + byte[] RandomNumber = new byte[0x20]; + rng.NextBytes(RandomNumber); + return "{{" + BitConverter.ToString(RandomNumber).Replace("-", "") + "}}"; + } + public static string GetFileExtension(byte[] Bytes) + { + if (bmp.SequenceEqual(Bytes.Take(bmp.Length))) + { + return ".bmp"; + } + else if (gif.SequenceEqual(Bytes.Take(gif.Length))) + { + return ".gif"; + } + else if (png.SequenceEqual(Bytes.Take(png.Length))) + { + return ".png"; + } + else if (tiff.SequenceEqual(Bytes.Take(tiff.Length))) + { + return ".tiff"; + } + else if (tiff2.SequenceEqual(Bytes.Take(tiff2.Length))) + { + return ".tiff"; + } + else if (jpeg.SequenceEqual(Bytes.Take(jpeg.Length))) + { + return ".jpg"; + } else if (IsZlib(Bytes)) { return ".z"; @@ -94,7 +97,7 @@ namespace General { return ".gim"; } - else if(!HasBinaryContent(Encoding.UTF8.GetString(Bytes))) + else if (!HasBinaryContent(Encoding.UTF8.GetString(Bytes))) { return ".txt"; }