コード例 #1
0
        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);
        }
コード例 #2
0
        public void Generate(BeebyteDeobfuscatorPlugin plugin, LookupModule module)
        {
            using var exportFile = new FileStream(plugin.ExportPath + Path.DirectorySeparatorChar + "translations.txt", FileMode.Create);
            StreamWriter output = new StreamWriter(exportFile);

            foreach (Translation translation in module.Translations.Where(t => t.CleanName != t.ObfName))
            {
                output.WriteLine($"{translation.ObfName}/{translation.CleanName}");
            }
            output.Close();
        }
コード例 #3
0
        public void Generate(BeebyteDeobfuscatorPlugin plugin, LookupModule module)
        {
            List <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)
                                                                        ).ToList();

            List <JsonTypeMapping> mappings = new List <JsonTypeMapping>();

            foreach (Translation translation in translations)
            {
                List <string> KnownTypeTranslations = new List <string>();
                if (translation.CleanName != translation.ObfName)
                {
                    KnownTypeTranslations.Add(translation.ObfName);
                }

                JsonTypeMapping typeMapping = new JsonTypeMapping {
                    Name = translation.CleanName, KnownTranslations = KnownTypeTranslations
                };
                List <JsonFieldMapping> fieldMappings = new List <JsonFieldMapping>();
                foreach (LookupField field in translation._type.Fields)
                {
                    List <string> KnownFieldTranslations = new List <string>();
                    if (field.Translation != null && field.Translation?.CleanName != field.Translation?.ObfName)
                    {
                        KnownFieldTranslations.Add(field.Translation.ObfName);
                    }
                    fieldMappings.Add(new JsonFieldMapping
                    {
                        Name              = field.CSharpName,
                        Type              = field.Type.IsEmpty ? "unknown" : Regex.IsMatch(field.Type.Name, module.NamingRegex) ? "unknown" : field.Type.CSharpName,
                        Offset            = string.Format("0x{0:X}", field.Offset),
                        KnownTranslations = KnownFieldTranslations
                    });
                }
                typeMapping.Fields = fieldMappings;
                mappings.Add(typeMapping);
            }

            using var exportFile = new FileStream(plugin.ExportPath + Path.DirectorySeparatorChar + "mappings.json", FileMode.Create);
            StreamWriter output     = new StreamWriter(exportFile);
            string       jsonString = JsonSerializer.Serialize(mappings);

            output.Write(jsonString);
        }
コード例 #4
0
        public void Generate(BeebyteDeobfuscatorPlugin plugin, LookupModule module)
        {
            JsonTranslations translations = new JsonTranslations
            {
                Types  = module.Translations.Where(t => t.Type == TranslationType.TypeTranslation && t.ObfName != t.CleanName).ToDictionary(t => t.ObfName, t => t.CleanName),
                Fields = module.Translations.Where(t => t.Type == TranslationType.FieldTranslation && t.ObfName != t.CleanName).ToDictionary(t => t.ObfName, t => t.CleanName),
            };

            using var exportFile = new FileStream(plugin.ExportPath + Path.DirectorySeparatorChar + "translations.json", FileMode.Create);
            StreamWriter output     = new StreamWriter(exportFile);
            string       jsonString = JsonSerializer.Serialize(translations);

            output.Write(jsonString);
            output.Close();
        }
コード例 #5
0
        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);
        }
コード例 #6
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;
            }
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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++;
            }
        }