Example #1
0
        private void HandleFile(string filePath)
        {
            try
            {
                // parse lua file
                var file = LuaFileFactory.Create(filePath, UsesDebugInfo);

#if DEBUG
                Console.WriteLine($"Decompiling file: {filePath}");
#endif

                // decompile file
                var output = _decompiler.Decompile(file);

                // replace extension
                var outFileName = Path.ChangeExtension(filePath, ".dec.lua");

                // save output
                File.WriteAllText(outFileName, output);

                Console.WriteLine($"Decompiled file: {filePath}");
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error while decompiling file: {filePath}");
                Console.WriteLine(e);
            }
        }
Example #2
0
 public override void Create(DecompileContext ctx)
 {
     using (var writer = new StreamWriter(Filename, false, Encoding.UTF8)) {
         var output = createDecompilerOutput(writer);
         decompiler.Decompile(DecompilationType.AssemblyInfo, new DecompileAssemblyInfo(output, decompilationContext, module));
     }
 }
        (MethodDebugInfo debugInfo, MethodDebugInfo?stateMachineDebugInfo) TryDecompileCode(MethodDef method, uint methodToken, DecompilationContext ctx, DecompilerOutputImpl output)
        {
            output.Initialize(methodToken);
            decompiler.Decompile(method, output, ctx);
            var info = output.TryGetMethodDebugInfo();

            cancellationToken.ThrowIfCancellationRequested();
            return(info);
        }
Example #4
0
        DbgLanguageDebugInfo CreateDebugInfo(IDbgDotNetCodeLocation location, CancellationToken cancellationToken)
        {
            const DbgLoadModuleOptions options = DbgLoadModuleOptions.AutoLoaded;
            ModuleDef mdModule;

            if (location.DbgModule is DbgModule dbgModule)
            {
                mdModule = dbgMetadataService.TryGetMetadata(dbgModule, options);
            }
            else
            {
                mdModule = dbgMetadataService.TryGetMetadata(location.Module, options);
            }
            Debug.Assert(mdModule != null);
            if (mdModule == null)
            {
                return(null);
            }
            cancellationToken.ThrowIfCancellationRequested();

            var method = mdModule.ResolveToken(location.Token) as MethodDef;

            Debug.Assert(method != null);
            if (method == null)
            {
                return(null);
            }

            var context = new DecompilationContext {
                CancellationToken = cancellationToken,
                CalculateBinSpans = true,
            };
            var output = DecompilerOutputImplCache.Alloc();

            output.Initialize(method.MDToken.Raw);
            //TODO: Whenever the decompiler options change, we need to invalidate our cache and every
            //		single DbgLanguageDebugInfo instance.
            decompiler.Decompile(method, output, context);
            var methodDebugInfo = output.TryGetMethodDebugInfo();

            DecompilerOutputImplCache.Free(ref output);
            cancellationToken.ThrowIfCancellationRequested();
            Debug.Assert(methodDebugInfo != null);
            if (methodDebugInfo == null)
            {
                return(null);
            }

            // We don't support EnC so the version is always 1
            const int methodVersion = 1;

            return(new DbgLanguageDebugInfo(methodDebugInfo, methodVersion, location.Offset));
        }
Example #5
0
        Task DecompileAsync(MethodDef method, MethodSourceStatement?methodSourceStatement)
        {
            Debug.Assert(decompileCodeState == null);
            if (decompileCodeState != null)
            {
                throw new InvalidOperationException();
            }
            var state = new DecompileCodeState(method, methodSourceStatement);

            decompileCodeState = state;

            return(Task.Run(() => {
                state.CancellationToken.ThrowIfCancellationRequested();

                var type = method.DeclaringType;
                while (type.DeclaringType != null)
                {
                    type = type.DeclaringType;
                }

                DecompileTypeMethods options;

                state.DecompilationContext.CalculateBinSpans = true;
                options = new DecompileTypeMethods(state.MainOutput, state.DecompilationContext, type);
                options.Methods.Add(method);
                options.DecompileHidden = false;
                options.MakeEverythingPublic = makeEverythingPublic;
                decompiler.Decompile(DecompilationType.TypeMethods, options);

                state.CancellationToken.ThrowIfCancellationRequested();

                state.DecompilationContext.CalculateBinSpans = false;
                options = new DecompileTypeMethods(state.HiddenOutput, state.DecompilationContext, type);
                options.Methods.Add(method);
                options.DecompileHidden = true;
                options.MakeEverythingPublic = makeEverythingPublic;
                decompiler.Decompile(DecompilationType.TypeMethods, options);
            }, state.CancellationToken));
        }
Example #6
0
        private void HandleFile(string filePath)
        {
            try
            {
                // parse lua file
                var file = LuaFileFactory.Create(filePath);

                // decompile file
                var output = _decompiler.Decompile(file);

                // replace extension
                var outFileName = Path.ChangeExtension(filePath, ".dec.lua");

                // save output
                File.WriteAllText(outFileName, output);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
Example #7
0
 protected virtual void Decompile(DecompileContext ctx, IDecompilerOutput output) =>
 decompiler.Decompile(Type, output, decompilationContext);
Example #8
0
        public void Decompile(DocumentTreeNodeData node)
        {
            var nodeType = GetNodeType(node);

            switch (nodeType)
            {
            case NodeType.Unknown:
                DecompileUnknown(node);
                break;

            case NodeType.Assembly:
                decompiler.Decompile(((AssemblyDocumentNode)node).Document.AssemblyDef !, output, decompilationContext);
                break;

            case NodeType.Module:
                decompiler.Decompile(((ModuleDocumentNode)node).Document.ModuleDef !, output, decompilationContext);
                break;

            case NodeType.Type:
                decompiler.Decompile(((TypeNode)node).TypeDef, output, decompilationContext);
                break;

            case NodeType.Method:
                decompiler.Decompile(((MethodNode)node).MethodDef, output, decompilationContext);
                break;

            case NodeType.Field:
                decompiler.Decompile(((FieldNode)node).FieldDef, output, decompilationContext);
                break;

            case NodeType.Property:
                decompiler.Decompile(((PropertyNode)node).PropertyDef, output, decompilationContext);
                break;

            case NodeType.Event:
                decompiler.Decompile(((EventNode)node).EventDef, output, decompilationContext);
                break;

            case NodeType.AssemblyRef:
                Decompile((AssemblyReferenceNode)node);
                break;

            case NodeType.BaseTypeFolder:
                Decompile((BaseTypeFolderNode)node);
                break;

            case NodeType.BaseType:
                Decompile((BaseTypeNode)node);
                break;

            case NodeType.DerivedType:
                Decompile((DerivedTypeNode)node);
                break;

            case NodeType.DerivedTypesFolder:
                Decompile((DerivedTypesFolderNode)node);
                break;

            case NodeType.ModuleRef:
                Decompile((ModuleReferenceNode)node);
                break;

            case NodeType.Namespace:
                Decompile((NamespaceNode)node);
                break;

            case NodeType.PEFile:
                Decompile((PEDocumentNode)node);
                break;

            case NodeType.ReferencesFolder:
                Decompile((ReferencesFolderNode)node);
                break;

            case NodeType.ResourcesFolder:
                Decompile((ResourcesFolderNode)node);
                break;

            case NodeType.Resource:
                Decompile((ResourceNode)node);
                break;

            case NodeType.ResourceElement:
                Decompile((ResourceElementNode)node);
                break;

            case NodeType.ResourceElementSet:
                Decompile((ResourceElementSetNode)node);
                break;

            case NodeType.UnknownFile:
                Decompile((UnknownDocumentNode)node);
                break;

            case NodeType.Message:
                Decompile((MessageNode)node);
                break;

            default:
                Debug.Fail($"Unknown NodeType: {nodeType}");
                goto case NodeType.Unknown;
            }
        }
Example #9
0
        DbgLanguageDebugInfo CreateDebugInfo(DbgEvaluationContext context, IDbgDotNetCodeLocation location, CancellationToken cancellationToken)
        {
            const DbgLoadModuleOptions options = DbgLoadModuleOptions.AutoLoaded;
            ModuleDef mdModule;

            if (location.DbgModule is DbgModule dbgModule)
            {
                mdModule = dbgMetadataService.TryGetMetadata(dbgModule, options);
            }
            else
            {
                dbgModule = null;
                mdModule  = dbgMetadataService.TryGetMetadata(location.Module, options);
            }
            Debug.Assert(mdModule != null);
            if (mdModule == null)
            {
                return(null);
            }
            cancellationToken.ThrowIfCancellationRequested();

            var method = mdModule.ResolveToken(location.Token) as MethodDef;

            // Could be null if it's a dynamic assembly. It will get refreshed later and we'll get called again.
            if (method == null)
            {
                return(null);
            }

            var runtime = context.Runtime.GetDotNetRuntime();
            int methodToken, localVarSigTok;

            if (dbgModule == null || !runtime.TryGetMethodToken(dbgModule, method.MDToken.ToInt32(), out methodToken, out localVarSigTok))
            {
                methodToken    = method.MDToken.ToInt32();
                localVarSigTok = (int)(method.Body?.LocalVarSigTok ?? 0);
            }

            var decContext = new DecompilationContext {
                CancellationToken = cancellationToken,
                CalculateBinSpans = true,
            };
            var output = DecompilerOutputImplCache.Alloc();

            output.Initialize(method.MDToken.Raw);
            //TODO: Whenever the decompiler options change, we need to invalidate our cache and every
            //		single DbgLanguageDebugInfo instance.
            decompiler.Decompile(method, output, decContext);
            var methodDebugInfo = output.TryGetMethodDebugInfo();

            DecompilerOutputImplCache.Free(ref output);
            cancellationToken.ThrowIfCancellationRequested();
            Debug.Assert(methodDebugInfo != null);
            if (methodDebugInfo == null)
            {
                return(null);
            }

            // We don't support EnC so the version is always 1
            const int methodVersion = 1;

            return(new DbgLanguageDebugInfo(methodDebugInfo, methodToken, localVarSigTok, methodVersion, location.Offset));
        }
Example #10
0
 public static Expression Decompile(this IDecompiler decompiler, MethodBase method, IList <Expression> arguments)
 {
     return(decompiler.Decompile(new MethodBaseAdapter(method), arguments));
 }
Example #11
0
 public static LambdaExpression Decompile(this IDecompiler decompiler, MethodBase method)
 {
     return(decompiler.Decompile(new MethodBaseAdapter(method)));
 }
Example #12
0
 public void Decompile(MethodDef method, IDecompilerOutput output, DecompilationContext ctx) => implementation.Decompile(method, GetOutput(output), ctx);
Example #13
0
        public void Decompile(IDocumentTreeNodeData node)
        {
            var nodeType = GetNodeType(node);

            switch (nodeType)
            {
            case NodeType.Unknown:
                DecompileUnknown(node);
                break;

            case NodeType.Assembly:
                decompiler.Decompile(((IAssemblyDocumentNode)node).Document.AssemblyDef, output, decompilationContext);
                break;

            case NodeType.Module:
                decompiler.Decompile(((IModuleDocumentNode)node).Document.ModuleDef, output, decompilationContext);
                break;

            case NodeType.Type:
                decompiler.Decompile(((ITypeNode)node).TypeDef, output, decompilationContext);
                break;

            case NodeType.Method:
                decompiler.Decompile(((IMethodNode)node).MethodDef, output, decompilationContext);
                break;

            case NodeType.Field:
                decompiler.Decompile(((IFieldNode)node).FieldDef, output, decompilationContext);
                break;

            case NodeType.Property:
                decompiler.Decompile(((IPropertyNode)node).PropertyDef, output, decompilationContext);
                break;

            case NodeType.Event:
                decompiler.Decompile(((IEventNode)node).EventDef, output, decompilationContext);
                break;

            case NodeType.AssemblyRef:
                Decompile((IAssemblyReferenceNode)node);
                break;

            case NodeType.BaseTypeFolder:
                Decompile((IBaseTypeFolderNode)node);
                break;

            case NodeType.BaseType:
                Decompile((IBaseTypeNode)node);
                break;

            case NodeType.DerivedType:
                Decompile((IDerivedTypeNode)node);
                break;

            case NodeType.DerivedTypesFolder:
                Decompile((IDerivedTypesFolderNode)node);
                break;

            case NodeType.ModuleRef:
                Decompile((IModuleReferenceNode)node);
                break;

            case NodeType.Namespace:
                Decompile((INamespaceNode)node);
                break;

            case NodeType.PEFile:
                Decompile((IPEDocumentNode)node);
                break;

            case NodeType.ReferencesFolder:
                Decompile((IReferencesFolderNode)node);
                break;

            case NodeType.ResourcesFolder:
                Decompile((IResourcesFolderNode)node);
                break;

            case NodeType.Resource:
                Decompile((IResourceNode)node);
                break;

            case NodeType.ResourceElement:
                Decompile((IResourceElementNode)node);
                break;

            case NodeType.ResourceElementSet:
                Decompile((IResourceElementSetNode)node);
                break;

            case NodeType.UnknownFile:
                Decompile((IUnknownDocumentNode)node);
                break;

            case NodeType.Message:
                Decompile((IMessageNode)node);
                break;

            default:
                Debug.Fail(string.Format("Unknown NodeType: {0}", nodeType));
                goto case NodeType.Unknown;
            }
        }
        private void HandleLuaFiles(List <LuaFileData> luaFiles, IGame game, bool dumpRaw = false)
        {
            Parallel.ForEach(luaFiles, file =>
            {
                string filePath = file.Name;
                if (String.IsNullOrEmpty(filePath))
                {
                    ulong hashNumber = (ulong)(file.Hash & 0xFFFFFFFFFFFFFFF);

                    if (_hashEntries.ContainsKey(hashNumber))
                    {
                        filePath = _hashEntries[hashNumber];
                    }
                    else
                    {
                        filePath = String.Format("Luafile_{0:x}", hashNumber);
                    }
                }


                var directory = Path.GetDirectoryName(game.ExportFolder + filePath);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory !);
                }

                var outFileName = Path.ChangeExtension(game.ExportFolder + filePath, ".dec.lua");

                // Check if we already decompiled the file
                string hash = "";
                if (File.Exists(outFileName))
                {
                    string line = File.ReadLines(outFileName).FirstOrDefault();
                    if (!String.IsNullOrEmpty(line) && line.StartsWith("-- "))
                    {
                        var checksum = line.Remove(0, 3);
                        hash         = GetHash(file);
                        if (checksum == hash)
                        {
                            return;
                        }
                    }
                }

                if (dumpRaw)
                {
                    using (var fileStream = File.Create(Path.ChangeExtension(game.ExportFolder + filePath, ".luac")))
                    {
                        file.Reader.BaseStream.Seek(0, SeekOrigin.Begin);
                        file.Reader.BaseStream.CopyTo(fileStream);
                    }
                }

                var luaFile = LuaFileFactory.Create(file.Reader, null);
                try
                {
                    if (String.IsNullOrEmpty(hash))
                    {
                        hash = GetHash(file);
                    }
                    var prefix         = $"-- {hash}\n-- This hash is used for caching, delete to decompile the file again\n\n";
                    var decompiledFile = _decompiler.Decompile(luaFile);

                    // save output
                    File.WriteAllText(outFileName, prefix + decompiledFile);
                    Console.WriteLine($"Decompiled file: {Path.GetFileName(filePath)}");
                }
                catch (Exception e)
                {
                    Console.WriteLine($"Error while trying to decompile file {Path.GetFileName(filePath)}: {e.Message}");
                }
            });
        }