private static uint HashKeyValueList(ProcessMemory memory, uint baseAddress, uint hash) { var entries = new List <KeyValuePair <string, string> >(); var listAddress = memory.ReadU32(baseAddress); var count = memory.ReadS32(listAddress + 8); if (count > 0) { var entriesAddress = memory.ReadU32(listAddress + 4); var data = memory.ReadAllBytes(entriesAddress, count * 8); for (int i = 0; i < count; i++) { var name = memory.ReadStringZ(BitConverter.ToUInt32(data, (i * 8) + 0)); var value = memory.ReadStringZ(BitConverter.ToUInt32(data, (i * 8) + 4)); entries.Add(new KeyValuePair <string, string>(name, value)); } } var sb = new StringBuilder(); foreach (var entry in entries.OrderBy(e => e.Key.ToLowerInvariant())) { sb.Append(entry.Key); sb.Append(entry.Value); } return(Adler32.Hash(sb.ToString(), hash)); }
private static void ExportExpressionFunctions(ProcessMemory memory, string outputPath) { // expression functions var exprFuncs = new List <KeyValuePair <string, uint> >(); uint stashPointer; if (Locate(memory, out stashPointer, Locators.ExpressionFunctionTableLocator1.Locate, Locators.ExpressionFunctionTableLocator2.Locate) == false) { Console.WriteLine("Warning: failed to locate expression function table."); return; } var stashCount = memory.ReadS32(stashPointer + 0x08); var stashEntryPointer = memory.ReadU32(stashPointer + 0x14); var stashEntries = memory.ReadAllBytes(stashEntryPointer, stashCount * 8); for (int i = 0; i < stashCount; i++) { var namePointer = BitConverter.ToUInt32(stashEntries, (i * 8) + 0); var dataPointer = BitConverter.ToUInt32(stashEntries, (i * 8) + 4); if (namePointer == 0 && dataPointer == 0) { continue; } var name = memory.ReadStringZ(namePointer); exprFuncs.Add(new KeyValuePair <string, uint>(name, dataPointer)); } if (exprFuncs.Count > 0) { using (var output = File.Create(Path.Combine(outputPath, "expression functions.txt"))) { var writer = new StreamWriter(output); foreach (var kv in exprFuncs.OrderBy(kv => kv.Key)) { ExportExpressionFunction(kv.Key, kv.Value, memory, writer); } writer.Flush(); } } }
private static List <KeyValuePair <string, string> > ReadKeyValueList(ProcessMemory memory, uint baseAddress) { var entries = new List <KeyValuePair <string, string> >(); var listAddress = memory.ReadU32(baseAddress); if (listAddress != 0) { var count = memory.ReadS32(listAddress + 8); if (count > 0) { var entriesAddress = memory.ReadU32(listAddress + 4); var data = memory.ReadAllBytes(entriesAddress, count * 8); for (int i = 0; i < count; i++) { var name = memory.ReadStringZ(BitConverter.ToUInt32(data, (i * 8) + 0)); var value = memory.ReadStringZ(BitConverter.ToUInt32(data, (i * 8) + 4)); entries.Add(new KeyValuePair <string, string>(name, value)); } } } return(entries); }
private static void ExportSchemas(ProcessMemory memory, string outputPath, List <KeyValuePair <string, uint> > enums) { uint stashPointer; if (Locate(memory, out stashPointer, Locators.ParserTableLocator1.Locate, Locators.ParserTableLocator2.Locate) == false) { Console.WriteLine("Warning: failed to locate schema table."); return; } var parsers = new List <KeyValuePair <string, uint> >(); var stashCount = memory.ReadS32(stashPointer + 0x08); var stashEntryPointer = memory.ReadU32(stashPointer + 0x14); var stashEntries = memory.ReadAllBytes(stashEntryPointer, stashCount * 8); for (int i = 0; i < stashCount; i++) { var namePointer = BitConverter.ToUInt32(stashEntries, (i * 8) + 0); var dataPointer = BitConverter.ToUInt32(stashEntries, (i * 8) + 4); if (namePointer == 0 && dataPointer == 0) { continue; } var name = memory.ReadStringZ(namePointer); parsers.Add(new KeyValuePair <string, uint>(name, dataPointer)); } if (parsers.Count > 0) { Directory.CreateDirectory(Path.Combine(outputPath, "schemas")); foreach (var kv in parsers.OrderBy(kv => kv.Key)) { var name = kv.Key; var pointer = kv.Value; Console.WriteLine("[schema] {0}", name); var settings = new XmlWriterSettings() { Indent = true, }; var schemaPath = Path.Combine(outputPath, "schemas", name + ".schema.xml"); using (var xml = XmlWriter.Create(schemaPath, settings)) { xml.WriteStartDocument(); xml.WriteStartElement("parser"); xml.WriteAttributeString("name", name); xml.WriteStartElement("table"); ExportParserTable(memory, pointer, xml, parsers, enums); xml.WriteEndElement(); xml.WriteEndElement(); xml.WriteEndDocument(); } } } }
private static IEnumerable <KeyValuePair <string, string> > ReadEnum(ProcessMemory memory, uint baseAddress) { var elements = new List <KeyValuePair <string, string> >(); var valueType = 4; while (true) { var type = memory.ReadU32(baseAddress); if (type == 0) { break; } switch (type) { case 1: { valueType = 1; baseAddress += 8; break; } case 2: { valueType = 2; baseAddress += 8; break; } // dynamic bullshit case 3: { baseAddress += 8; break; } case 5: { var parent = memory.ReadU32(baseAddress + 4); var nested = ReadEnum(memory, parent); elements.AddRange(nested); return(elements); } default: { var name = memory.ReadStringZ(type); object value; switch (valueType) { case 1: { value = memory.ReadS32(baseAddress + 4); baseAddress += 8; break; } case 2: { value = memory.ReadStringZ(baseAddress + 4); baseAddress += 8; break; } default: { throw new NotImplementedException(); } } elements.Add(new KeyValuePair <string, string>(name, value.ToString())); break; } } } return(elements); }
private static List <KeyValuePair <string, uint> > ExportEnums(ProcessMemory memory, string outputPath) { var enums = new List <KeyValuePair <string, uint> >(); uint stashPointer; if (Locate(memory, out stashPointer, Locators.EnumTableLocator1.Locate, Locators.EnumTableLocator2.Locate, Locators.EnumTableLocator3.Locate) == false) { Console.WriteLine("Warning: failed to locate enum table."); return(enums); } var stashCount = memory.ReadS32(stashPointer + 0x08); var stashEntryPointer = memory.ReadU32(stashPointer + 0x14); var stashEntries = memory.ReadAllBytes(stashEntryPointer, stashCount * 8); var enumLocations = new Dictionary <uint, string>(); for (int i = 0; i < stashCount; i++) { var namePointer = BitConverter.ToUInt32(stashEntries, (i * 8) + 0); var dataPointer = BitConverter.ToUInt32(stashEntries, (i * 8) + 4); if (namePointer == 0 && dataPointer == 0) { continue; } var name = memory.ReadStringZ(namePointer); if (enumLocations.ContainsKey(dataPointer) == true) { var otherName = enumLocations[dataPointer]; if (name != otherName) { // Cryptic pls if (name != "PowerCategory" && otherName != "PowerCategories") { throw new InvalidOperationException(); } } continue; } enumLocations.Add(dataPointer, name); } if (enumLocations.Count > 0) { Directory.CreateDirectory(Path.Combine(outputPath, "enums")); foreach (var kv in enumLocations.OrderBy(kv => kv.Value)) { var name = kv.Value; var pointer = kv.Key; var elements = ReadEnum(memory, pointer); if (elements == null) { continue; } enums.Add(new KeyValuePair <string, uint>(name, pointer)); Console.WriteLine("[enum] {0}", name); var settings = new XmlWriterSettings() { Indent = true, }; using ( var xml = XmlWriter.Create(Path.Combine(outputPath, "enums", name + ".enum.xml"), settings)) { xml.WriteStartDocument(); xml.WriteStartElement("enum"); xml.WriteAttributeString("name", name); ExportEnum(memory, pointer, elements, xml); xml.WriteEndElement(); xml.WriteEndDocument(); } } } return(enums); }