public LookupModule Process(TypeModel model, BeebyteDeobfuscatorPlugin plugin) { PluginServices services = PluginServices.For(plugin); services.StatusUpdate("Creating model for Mono dll"); if (plugin.CompilerType.Value != CppCompilerType.MSVC) { throw new System.ArgumentException("Cross compiler deobfuscation has not been implemented yet"); } MonoDecompiler.MonoDecompiler monoDecompiler = MonoDecompiler.MonoDecompiler.FromFile(plugin.MonoPath); if (monoDecompiler == null) { throw new System.ArgumentException("Could not load unobfuscated application"); } services.StatusUpdate("Creating LookupModel for obfuscated application"); LookupModule lookupModel = new LookupModule(plugin.NamingRegex); lookupModel.Init(model.ToLookupModel(statusCallback: services.StatusUpdate), LookupModel.FromModuleDef(monoDecompiler.Module, statusCallback: services.StatusUpdate), statusCallback: services.StatusUpdate); services.StatusUpdate("Deobfuscating binary"); lookupModel.TranslateTypes(statusCallback: services.StatusUpdate); plugin.CompilerType = null; return(lookupModel); }
public LookupModel Process(TypeModel model, BeebyteDeobfuscatorPlugin plugin) { if (!plugin.CompilerType.HasValue) { return(null); } PluginServices services = PluginServices.For(plugin); services.StatusUpdate("Loading unobfuscated application"); var il2cppClean = Il2CppInspector.Il2CppInspector.LoadFromPackage(new[] { plugin.BinaryPath }, statusCallback: services.StatusUpdate); if (il2cppClean == null) { il2cppClean = Il2CppInspector.Il2CppInspector.LoadFromFile(plugin.BinaryPath, plugin.MetadataPath, statusCallback: services.StatusUpdate); } if (il2cppClean == null) { throw new System.ArgumentException("Could not load unobfuscated application"); } if (plugin.CompilerType.Value != CppCompiler.GuessFromImage(il2cppClean[0].BinaryImage)) { throw new System.ArgumentException("Cross compiler deobfuscation has not been implemented yet"); } services.StatusUpdate("Creating type model for unobfuscated application"); var modelClean = new TypeModel(il2cppClean[0]); if (modelClean == null) { throw new System.ArgumentException("Could not create type model for unobfuscated application"); } services.StatusUpdate("Creating LookupModel for obfuscated application"); LookupModel lookupModel = new LookupModel(plugin.NamingRegex); lookupModel.Init(model.ToLookupModule(lookupModel, statusCallback: services.StatusUpdate), modelClean.ToLookupModule(lookupModel, statusCallback: services.StatusUpdate)); services.StatusUpdate("Deobfuscating binary"); lookupModel.TranslateTypes(true, statusCallback: services.StatusUpdate); plugin.CompilerType = null; return(lookupModel); }
public static void Export(BeebyteDeobfuscatorPlugin plugin, LookupModel lookupModel) { PluginServices services = PluginServices.For(plugin); services.StatusUpdate("Generating output.."); if (!lookupModel.Translations.Any(t => t.CleanName != t.ObfName)) { return; } switch (plugin.Export) { case ExportType.PlainText: ExportPlainText(plugin.ExportPath, lookupModel); break; case ExportType.Classes: ExportClasses(plugin.ExportPath, plugin.PluginName, lookupModel, statusCallback: services.StatusUpdate); break; } }
public static void Export(BeebyteDeobfuscatorPlugin plugin, LookupModule lookupModule) { PluginServices services = PluginServices.For(plugin); services.StatusUpdate("Generating output.."); if (!lookupModule.Translations.Any(t => t.CleanName != t.ObfName)) { return; } List <Translation> filteredTranslations = lookupModule.Translations .Where(t => !t.CleanName.EndsWith('&')) .GroupBy(t => t.CleanName) .Select(t => t.First()) .GroupBy(t => t.ObfName) .Select(t => t.First()) .ToList(); lookupModule.Translations.Clear(); lookupModule.Translations.AddRange(filteredTranslations); IGenerator.GetGenerator(plugin).Generate(plugin, lookupModule); }
public void Generate(BeebyteDeobfuscatorPlugin plugin, LookupModule module) { IEnumerable <Translation> translations = module.Translations.Where(t => t.Type == TranslationType.TypeTranslation && !Regex.IsMatch(t.CleanName, @"\+<.*(?:>).*__[1-9]{0,4}|[A-z]*=.{1,4}|<.*>") && !Regex.IsMatch(t.CleanName, module.NamingRegex) && (t._type?.DeclaringType.IsEmpty ?? false) && !(t._type?.IsArray ?? false) && !(t._type?.IsGenericType ?? false) && !(t._type?.IsNested ?? false) && !(t._type?.Namespace.Contains("System") ?? false) && !(t._type?.Namespace.Contains("MS") ?? false) ); int current = 0; int total = translations.Count(); PluginServices services = PluginServices.For(plugin); foreach (Translation translation in translations) { services.StatusUpdate(translations, $"Exported {current}/{total} classes"); FileStream exportFile = null; if (!translation.CleanName.Contains("+")) { exportFile = new FileStream(plugin.ExportPath + Path.DirectorySeparatorChar + $"{Helpers.SanitizeFileName(translation.CleanName)}.cs", FileMode.Create); } else { if (!File.Exists($"{Helpers.SanitizeFileName(translation.CleanName.Split("+")[0])}.cs")) { continue; } var lines = File.ReadAllLines($"{Helpers.SanitizeFileName(translation.CleanName.Split("+")[0])}.cs"); File.WriteAllLines($"{Helpers.SanitizeFileName(translation.CleanName.Split("+")[0])}.cs", lines.Take(lines.Length - 1).ToArray()); exportFile = new FileStream(plugin.ExportPath + Path.DirectorySeparatorChar + $"{Helpers.SanitizeFileName(translation.CleanName.Split("+")[0])}.cs", FileMode.Open); } StreamWriter output = new StreamWriter(exportFile); if (!translation.CleanName.Contains("+")) { string start = Output.ClassOutputTop; start = start.Replace("#PLUGINNAME#", plugin.PluginName); output.Write(start); output.Write($" [Translator]\n public struct {translation.CleanName}\n {{\n"); } else { var names = translation.CleanName.Split("+").ToList(); names.RemoveAt(0); output.Write($" [Translator]\n public struct {string.Join('.', names)}\n {{\n"); } foreach (LookupField f in translation._type.Fields) { output.WriteLine(f.ToFieldExport()); } output.Write(" }\n}"); output.Close(); current++; } }