internal DllTypeData(TypeDefinition def, DllConfig config)
        {
            _config = config;
            foreach (var i in def.Interfaces)
            {
                ImplementingInterfaces.Add(DllTypeRef.From(i.InterfaceType));
            }

            This = DllTypeRef.From(def);
            Type = def.IsEnum ? TypeEnum.Enum : (def.IsInterface ? TypeEnum.Interface : (def.IsValueType ? TypeEnum.Struct : TypeEnum.Class));
            Info = new TypeInfo
            {
                Refness = def.IsValueType ? Refness.ValueType : Refness.ReferenceType
            };

            if (def.BaseType != null)
            {
                Parent = DllTypeRef.From(def.BaseType);
            }

            // TODO: Parse this eventually
            TypeDefIndex = -1;

            if (_config.ParseTypeAttributes && def.HasCustomAttributes)
            {
                Attributes.AddRange(def.CustomAttributes.Select(ca => new DllAttribute(ca)).Where(a => !string.IsNullOrEmpty(a.Name)));
            }
            Layout = (ITypeData.LayoutKind)(def.Attributes & TypeAttributes.LayoutMask);
            if (_config.ParseTypeFields)
            {
                InstanceFields.AddRange(def.Fields.Where(f => !f.IsStatic).Select(f => new DllField(f)));
                StaticFields.AddRange(def.Fields.Where(f => f.IsStatic).Select(f => new DllField(f)));
            }
            if (_config.ParseTypeProperties)
            {
                Properties.AddRange(def.Properties.Select(p => new DllProperty(p)));
            }
            if (_config.ParseTypeMethods)
            {
                var mappedBaseMethods = new HashSet <MethodDefinition>();
                var methods           = def.Methods.Select(m => DllMethod.From(m, ref mappedBaseMethods)).ToList();
                // It's important that Foo.IBar.func() goes after func() (if present)
                Methods.AddRange(methods.Where(m => m.ImplementedFrom is null));
                Methods.AddRange(methods.Where(m => m.ImplementedFrom != null));
            }
        }
Exemple #2
0
        /// <summary>Creates a new instance of the Tsort.PandA.PandaService class.</summary>
        /// <param name="databaseConnection">An ADO.Net database connection string.</param>
        /// <param name="enableUI">Set to true to have a task tray icon displayed that provides access to the Panda Service user interface.</param>
        /// <exceptions cref="ApplicationException">Thrown for unexpected errors.</exceptions>
        public PandaService(string databaseConnection, bool enableUI)
        {
            //Constructor
            try {
                //Configure user access
                if (enableUI)
                {
                    this.mTrayIcon = new TrayIcon("PandA Library", new Icon(Assembly.GetExecutingAssembly().GetManifestResourceStream("Tsort.PandA.panda.ico")));
                    #region Tray Icon Menu Configuration
                    ctxOpen             = new MenuItem("Open", new System.EventHandler(this.OnIconMenuClicked));
                    ctxOpen.Index       = MNU_ICON_OPEN;
                    ctxOpen.Enabled     = true;
                    ctxOpen.DefaultItem = true;
                    this.mTrayIcon.MenuItems.AddRange(new MenuItem[] { ctxOpen });
                    #endregion
                    this.mTrayIcon.DoubleClick += new System.EventHandler(OnIconDoubleClicked);
                }

                //Get configuration
                PandaPacket.ValidateMessageLength = Convert.ToBoolean(DllConfig.AppSettings("ValidateMessageLength"));
                PandaPacket.CartonIDLength        = Convert.ToInt32(DllConfig.AppSettings("CartonIDLength"));
                PandaPacket.LabelDataLength       = Convert.ToInt32(DllConfig.AppSettings("LabelDataLength"));
                if (databaseConnection.Trim().Length == 0)
                {
                    databaseConnection = DllConfig.AppSettings("SQLConnection");
                }
                LogLevel level = (LogLevel)Convert.ToInt32(DllConfig.AppSettings("TraceLevel"));

                //Create objects
                ArgixTrace.AddListener(new ArgixEventLogTraceListener(level, AppLib.PRODUCTNAME));
                this.mOperator = new StationOperator(databaseConnection);
                if (enableUI)
                {
                    this.mPandaUI = new frmPanda(this, level);
                }
            }
            catch (ApplicationException ex) { throw ex; }
            catch (Exception ex) { throw new ApplicationException("Unexpected error while creating new PandaService instance.", ex); }
        }
        private static void Main(string[] args)
        {
            Console.WriteLine(DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"));
            Console.WriteLine("Drag and drop your dump.cs file (or a partial of it of the correct format) then press enter...");
            string path = @"C:\Users\Sc2ad\Desktop\Code\Android Modding\BeatSaber\1.16.3\DummyDll-Inspector";

            //string path = @"C:\Users\Sc2ad\Desktop\Code\Android Modding\GorillaTag\DummyDll";
            if (!Directory.Exists(path))
            {
                path = Console.ReadLine().Replace("\"", string.Empty);
            }
            bool    parseDlls = false;
            IParser parser;

            if (Directory.Exists(path))
            {
                var parseConfig = new DllConfig()
                {
                };
                parser    = new DllParser(parseConfig);
                parseDlls = true;
            }
            else
            {
                var parseConfig = new DumpConfig()
                {
                };
                parser = new DumpParser(parseConfig);
            }

            Console.WriteLine("Parsing...");
            Stopwatch watch = new();

            watch.Start();
            IParsedData parsed;

            if (parseDlls)
            {
                parsed = parser.Parse(path);
            }
            else
            {
                using var stream = File.OpenRead(path);
                parsed           = parser.Parse(stream);
            }
            watch.Stop();
            //Console.WriteLine(parsed);
            Console.WriteLine($"Parsing took: {watch.Elapsed}!");
            Console.WriteLine("============================================");
            Console.WriteLine("Type the name of an output style (or don't for Normal) then press enter to serialize:");
            var input = "ThrowUnless";

            //var input = Console.ReadLine();
            // TODO: strip non-alphabetic characters out of input before parsing it
            if (Enum.TryParse(input, true, out OutputStyle style))
            {
                Console.WriteLine($"Parsed style '{style}'");
            }

            var libIl2cpp = @"C:\Program Files\Unity\Hub\Editor\2019.3.15f1\Editor\Data\il2cpp\libil2cpp";

            if (!Directory.Exists(libIl2cpp))
            {
                Console.WriteLine("Drag and drop your libil2cpp folder into this window then press enter:");
                libIl2cpp = Console.ReadLine();
            }

            Console.WriteLine("Creating serializer...");
            var config = new SerializationConfig
            {
                OneSourceFile  = true,
                ChunkFrequency = 100,
                // from https://en.cppreference.com/w/cpp/keyword
                IllegalNames = new HashSet <string> {
                    "alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit", "atomic_noexcept", "auto",
                    "bitand", "bitor", "bool", "break", "case", "catch", "char", "char8_t", "char16_t", "char32_t", "class",
                    "compl", "concept", "const", "consteval", "constexpr", "constinit", "const_cast", "continue", "co_await",
                    "co_return", "co_yield", "decltype", "default", "delete", "do", "double", "dynamic_cast", "else", "enum",
                    "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if", "inline", "int", "long",
                    "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
                    "private", "protected", "public", "reflexpr", "register", "reinterpret_cast", "requires", "return",
                    "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", "switch", "synchronized",
                    "template", "this", "thread_local", "throw", "true", "try", "typedef", "typeid", "typename", "union",
                    "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq", "INT_MAX", "INT_MIN",
                    "Assert", "bzero", "ID", "VERSION", "NULL"
                },
                IllegalMethodNames = new HashSet <string> {
                    "bzero", "Assert"
                },
                QualifiedBlacklistMethods = new HashSet <(string @namespace, string typeName, string methodName)>
                {
                    ("UnityEngine.ResourceManagement.AsyncOperations", "AsyncOperationHandle", "Convert")
                },
                OutputDirectory                 = Path.Combine(Environment.CurrentDirectory, "output"),
                OutputHeaderDirectory           = "include",
                OutputSourceDirectory           = "src",
                GenericHandling                 = GenericHandling.Do,
                OutputStyle                     = style,
                UnresolvedTypeExceptionHandling = new UnresolvedTypeExceptionHandlingWrapper
                {
                    FieldHandling  = UnresolvedTypeExceptionHandling.DisplayInFile,
                    MethodHandling = UnresolvedTypeExceptionHandling.DisplayInFile,
                    TypeHandling   = UnresolvedTypeExceptionHandling.DisplayInFile
                },
                PrintSerializationProgress          = true,
                PrintSerializationProgressFrequency = 1000,
                Id        = "codegen",
                Version   = "0.2.5",
                Libil2cpp = libIl2cpp,
            };

            if (config.OneSourceFile)
            {
                // If we have one source file, yeet our destination src
                if (Directory.Exists(Path.Combine(config.OutputDirectory, config.OutputSourceDirectory)))
                {
                    Directory.Delete(Path.Combine(config.OutputDirectory, config.OutputSourceDirectory), true);
                }
            }
            Utils.Init(config);

            var serializer = new CppDataSerializer(config, parsed);

            Console.WriteLine("Resolving types...");
            try
            {
                watch.Restart();
                // context unused
                serializer.PreSerialize(null, parsed);
                watch.Stop();
                Console.WriteLine($"Resolution Complete, took: {watch.Elapsed}!");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.WriteLine("Performing JSON dump...");
            watch.Restart();
            var jsonOutput = Path.Combine(Environment.CurrentDirectory, "json_output");

            Directory.CreateDirectory(jsonOutput);
            var outp = Path.Combine(jsonOutput, "parsed.json");

            if (File.Exists(outp))
            {
                File.Delete(outp);
            }
            var conf = new JsonSerializerOptions
            {
                WriteIndented = true,
                Encoder       = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
            };
            var strc = new SimpleTypeRefConverter(parsed.Types);

            conf.Converters.Add(strc);
            conf.Converters.Add(new TypeDataConverter(parsed, strc));
            conf.Converters.Add(new MethodConverter());
            conf.Converters.Add(new JsonStringEnumConverter());
            conf.Converters.Add(new FieldConverter());
            conf.Converters.Add(new SpecifierConverter());
            conf.Converters.Add(new PropertyConverter());
            using (var fs = File.OpenWrite(outp))
            {
                JsonSerializer.SerializeAsync(fs, parsed as DllData, conf).Wait();
            }
            watch.Stop();
            Console.WriteLine($"Json Dump took: {watch.Elapsed}!");
            Console.WriteLine("============================================");

            Console.WriteLine("Serializing...");
            try
            {
                watch.Restart();
                serializer.Serialize(null, parsed, true);
                watch.Stop();
                Console.WriteLine($"Serialization Complete, took: {watch.Elapsed}!");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            Console.WriteLine(string.Join(", ", SerializationConfig.SpecialMethodNames));
            Console.ReadLine();
        }
Exemple #4
0
        internal DllData(string dir, DllConfig config)
        {
            _config = config;
            _dir    = dir;
            AddSearchDirectory(dir);
            _metadataResolver = new MetadataResolver(this);
            _readerParams     = new ReaderParameters(ReadingMode.Immediate)
            {
                AssemblyResolver = this,
                MetadataResolver = _metadataResolver
            };

            var modules = new List <ModuleDefinition>();

            foreach (var file in Directory.GetFiles(dir))
            {
                if (file.EndsWith(".dll") && !_config.BlacklistDlls.Contains(file))
                {
                    var assemb = AssemblyDefinition.ReadAssembly(file, _readerParams);
                    foreach (var module in assemb.Modules)
                    {
                        modules.Add(module);
                    }
                }
            }

            Queue <TypeDefinition> frontier = new Queue <TypeDefinition>();

            modules.ForEach(m => m.Types.ToList().ForEach(t =>
            {
                if (_config.ParseTypes && !_config.BlacklistTypes.Contains(t.Name))
                {
                    frontier.Enqueue(t);
                }
            }));

            while (frontier.Count > 0)
            {
                var t = frontier.Dequeue();
                if (t.Name.StartsWith("<") && t.Namespace.Length == 0 && t.DeclaringType is null)
                {
                    if (!t.Name.StartsWith("<Module>") && !t.Name.StartsWith("<PrivateImplementationDetails>"))
                    {
                        Console.Error.WriteLine($"Skipping TypeDefinition {t}");
                    }
                    continue;
                }

                var dllRef = DllTypeRef.From(t);
                if (!_types.ContainsKey(dllRef))
                {
                    var type = new DllTypeData(t, _config);
                    if (dllRef.DeclaringType != null)
                    {
                        _types[dllRef.DeclaringType].NestedTypes.AddOrThrow(type);
                    }
                    foreach (var nested in t.NestedTypes)
                    {
                        frontier.Enqueue(nested);
                    }
                    _types.Add(dllRef, type);
                }
                else
                {
                    Console.Error.WriteLine($"{dllRef} already in _types! Matching item: {_types[dllRef].This}");
                }
            }

            int total = DllTypeRef.Hits + DllTypeRef.Misses;

            Console.WriteLine($"{nameof(DllTypeRef)} cache hits: {DllTypeRef.Hits} / {total} = {100.0f * DllTypeRef.Hits / total}");
            // Ignore images for now.
        }
Exemple #5
0
 public DllParser(DllConfig config) => _config = config;
Exemple #6
0
        private static void Main(string[] args)
        {
            Console.WriteLine("Drag and drop your dump.cs file (or a partial of it of the correct format) then press enter...");
            string path;

            if (Directory.Exists(@"C:\Users\Sc2ad\Desktop\Code\Android Modding\BeatSaber\1.8.0\DummyDll"))
            {
                path = @"C:\Users\Sc2ad\Desktop\Code\Android Modding\BeatSaber\1.8.0\DummyDll";
            }
            else
            {
                path = Console.ReadLine().Replace("\"", string.Empty);
            }
            bool    parseDlls = false;
            IParser parser;

            if (Directory.Exists(path))
            {
                var parseConfig = new DllConfig()
                {
                };
                parser    = new DllParser(parseConfig);
                parseDlls = true;
            }
            else
            {
                var parseConfig = new DumpConfig()
                {
                };
                parser = new DumpParser(parseConfig);
            }

            Console.WriteLine("Parsing...");
            Stopwatch watch = new Stopwatch();

            watch.Start();
            IParsedData parsed;

            if (parseDlls)
            {
                parsed = parser.Parse(path);
            }
            else
            {
                using var stream = File.OpenRead(path);
                parsed           = parser.Parse(stream);
            }
            watch.Stop();
            //Console.WriteLine(parsed);
            Console.WriteLine($"Parsing took: {watch.Elapsed}!");
            Console.WriteLine("============================================");
            Console.WriteLine("Type the name of an output style (or don't for Normal) then press enter to serialize:");
            var input = Console.ReadLine();

            // TODO: strip non-alphabetic characters out of input before parsing it
            if (Enum.TryParse(input, true, out OutputStyle style))
            {
                Console.WriteLine($"Parsed style '{style}'");
            }

            var libIl2cpp = "C:/Program Files/Unity/Editor/Data/il2cpp/libil2cpp";

            if (!Directory.Exists(libIl2cpp))
            {
                Console.WriteLine("Drag and drop your libil2cpp folder into this window then press enter:");
                libIl2cpp = Console.ReadLine();
            }

            Console.WriteLine("Creating serializer...");
            var config = new SerializationConfig
            {
                // from https://en.cppreference.com/w/cpp/keyword
                IllegalNames = new HashSet <string> {
                    "alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit", "atomic_noexcept", "auto",
                    "bitand", "bitor", "bool", "break", "case", "catch", "char", "char8_t", "char16_t", "char32_t", "class",
                    "compl", "concept", "const", "consteval", "constexpr", "constinit", "const_cast", "continue", "co_await",
                    "co_return", "co_yield", "decltype", "default", "delete", "do", "double", "dynamic_cast", "else", "enum",
                    "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if", "inline", "int", "long",
                    "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
                    "private", "protected", "public", "reflexpr", "register", "reinterpret_cast", "requires", "return",
                    "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", "switch", "synchronized",
                    "template", "this", "thread_local", "throw", "true", "try", "typedef", "typeid", "typename", "union",
                    "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq", "INT_MAX", "INT_MIN"
                },
                IllegalMethodNames = new HashSet <string> {
                    "bzero", "Assert"
                },
                OutputDirectory                 = Path.Combine(Environment.CurrentDirectory, "output"),
                OutputHeaderDirectory           = "include",
                OutputSourceDirectory           = "src",
                GenericHandling                 = GenericHandling.Do,
                OutputStyle                     = style,
                UnresolvedTypeExceptionHandling = new UnresolvedTypeExceptionHandlingWrapper
                {
                    FieldHandling  = UnresolvedTypeExceptionHandling.DisplayInFile,
                    MethodHandling = UnresolvedTypeExceptionHandling.DisplayInFile,
                    TypeHandling   = UnresolvedTypeExceptionHandling.DisplayInFile
                },
                PrintSerializationProgress          = true,
                PrintSerializationProgressFrequency = 1000,
                Id        = "il2cpp_codegen",
                Version   = "0.2.2",
                Libil2cpp = libIl2cpp
            };

            var serializer = new CppDataSerializer(config, parsed);

            Console.WriteLine("Resolving types...");
            try
            {
                watch.Restart();
                // context unused
                serializer.PreSerialize(null, parsed);
                watch.Stop();
                Console.WriteLine($"Resolution Complete, took: {watch.Elapsed}!");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.WriteLine("Serializing...");
            try
            {
                watch.Restart();
                serializer.Serialize(null, parsed, true);
                watch.Stop();
                Console.WriteLine($"Serialization Complete, took: {watch.Elapsed}!");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            Console.WriteLine(string.Join(", ", SerializationConfig.SpecialMethodNames));
            Console.ReadLine();
        }