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);
        }
Example #3
0
        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++;
            }
        }