public static void ParseScriptFunctionTables ( [Optional(null, "exe")] string path ) { if (path == null) { path = FindExecutablePath(); } if (path == null) { Console.WriteLine("Unable to local TS3.exe. Please specify a path to it."); return; } Stream input = File.OpenRead(path); string hash = GetMd5Hash(input); ExecutableVersion version = GetExecutableVersion(hash); if (version == null) { Console.WriteLine("Executable information for this version (md5 hash of {0} is unavailable.", hash); input.Close(); return; } if (version.ScriptTables == null || version.ScriptTables.Count == 0) { Console.WriteLine("No native script tables to parse."); input.Close(); return; } Executable exe = new Executable(); exe.Read(input); foreach (UInt32 virtualAddress in version.ScriptTables) { UInt32 fileOffset = exe.GetFileOffset(virtualAddress); if (fileOffset == 0) { Console.WriteLine("Failed to get file offset for virtual address {0:X8}", virtualAddress); return; } input.Seek(fileOffset, SeekOrigin.Begin); Dictionary <UInt32, UInt32> natives = new Dictionary <UInt32, UInt32>(); while (true) { UInt32 nativeAddress = input.ReadValueU32(); if (nativeAddress == 0) { break; } UInt32 nameAddress = input.ReadValueU32(); natives.Add(nameAddress, nativeAddress); } Console.WriteLine("Table {0:X8}", virtualAddress); foreach (KeyValuePair <UInt32, UInt32> native in natives) { UInt32 nameOffset = exe.GetFileOffset(native.Key); if (nameOffset == 0) { Console.WriteLine(" {0:X8} => {1:X8}", native.Key, native.Value); } else { input.Seek(nameOffset, SeekOrigin.Begin); Console.WriteLine(" '{0}' => {1:X8}", input.ReadStringASCIIZ(), native.Value); } } } input.Close(); }
public static void ParseLocaleTable ( [Optional(null, "exe")] string path ) { if (path == null) { path = FindExecutablePath(); } if (path == null) { Console.WriteLine("Unable to local TS3.exe. Please specify a path to it."); return; } Stream input = File.OpenRead(path); string hash = GetMd5Hash(input); ExecutableVersion version = GetExecutableVersion(hash); if (version == null) { Console.WriteLine("Executable information for this version (md5 hash of {0} is unavailable.", hash); input.Close(); return; } if (version.LocaleTable == 0) { Console.WriteLine("No locale table to parse."); input.Close(); return; } Executable exe = new Executable(); exe.Read(input); input.Seek(exe.GetFileOffset(version.LocaleTable), SeekOrigin.Begin); int count = 0; List <LocaleOffset> offsets = new List <LocaleOffset>(); while (true) { UInt32 nameOffset = input.ReadValueU32(); UInt32 bOffset = input.ReadValueU32(); UInt32 cOffset = input.ReadValueU32(); if (nameOffset == 0 || bOffset == 0 || cOffset == 0) { break; } LocaleOffset offset = new LocaleOffset(); offset.Id = count; offset.Name = nameOffset; offset.Language = bOffset; offset.Region = cOffset; offsets.Add(offset); count++; } List <LocaleData> locales = new List <LocaleData>(); foreach (LocaleOffset offset in offsets) { LocaleData locale = new LocaleData(); locale.Id = offset.Id; input.Seek(exe.GetFileOffset(offset.Name), SeekOrigin.Begin); locale.Name = input.ReadStringUTF16Z(); input.Seek(exe.GetFileOffset(offset.Language), SeekOrigin.Begin); locale.Language = input.ReadStringUTF16Z(); input.Seek(exe.GetFileOffset(offset.Region), SeekOrigin.Begin); locale.Region = input.ReadStringUTF16Z(); locales.Add(locale); } StreamWriter writer = new StreamWriter("locales.txt", false, Encoding.Unicode); foreach (LocaleData locale in locales) { string[] data; writer.WriteLine("|-"); writer.WriteLine("| <tt>{0:X2}</tt>", locale.Id); writer.WriteLine("| {0}", locale.Id); writer.WriteLine("| {0}", locale.Name); data = locale.Language.Split('^'); writer.WriteLine("| {0}", data[1]); data = locale.Region.Split('^'); writer.WriteLine("| {0}", data[1]); writer.WriteLine(); } writer.Flush(); writer.Close(); input.Close(); }