Exemplo n.º 1
0
        public void Decompile(CompilationStreamPair streams, TextWriter codeWriter)
        {
            Argument.NotNull(nameof(streams), streams);
            Argument.NotNull(nameof(codeWriter), codeWriter);

            using (var resultScope = JitCompileAndGetMethods(streams.AssemblyStream))
                using (var dataTarget = DataTarget.AttachToProcess(Current.ProcessId, uint.MaxValue, AttachFlag.Passive)) {
                    var currentMethodAddressRef = new Reference <ulong>();
                    var runtime    = dataTarget.ClrVersions.Single(v => v.Flavor == ClrFlavor).CreateRuntime();
                    var translator = new IntelTranslator {
                        SymbolResolver = (Instruction instruction, long addr, ref long offset) =>
                                         ResolveSymbol(runtime, instruction, addr, currentMethodAddressRef.Value)
                    };

                    WriteJitInfo(runtime.ClrInfo, codeWriter);
                    WriteProfilerState(codeWriter);
                    codeWriter.WriteLine();

                    var architecture = MapArchitecture(runtime.ClrInfo.DacInfo.TargetArchitecture);
                    foreach (var result in resultScope.Results)
                    {
                        DisassembleAndWrite(result, runtime, architecture, translator, currentMethodAddressRef, codeWriter);
                        codeWriter.WriteLine();
                    }
                }
        }
Exemplo n.º 2
0
        public void Decompile(CompilationStreamPair streams, TextWriter codeWriter)
        {
            Argument.NotNull(nameof(streams), streams);
            Argument.NotNull(nameof(codeWriter), codeWriter);

            var currentSetup = AppDomain.CurrentDomain.SetupInformation;

            using (var dataTarget = DataTarget.AttachToProcess(CurrentProcess.Id, UInt32.MaxValue, AttachFlag.Passive))
                using (var context = AppDomainContext.Create(new AppDomainSetup {
                    ApplicationBase = currentSetup.ApplicationBase,
                    PrivateBinPath = currentSetup.PrivateBinPath
                })) {
                    context.LoadAssembly(LoadMethod.LoadFrom, Assembly.GetExecutingAssembly().GetAssemblyFile().FullName);
                    var results = RemoteFunc.Invoke(context.Domain, streams.AssemblyStream, Remote.GetCompiledMethods);

                    var currentMethodAddressRef = new Reference <ulong>();
                    var runtime    = dataTarget.ClrVersions.Single().CreateRuntime();
                    var translator = new IntelTranslator {
                        SymbolResolver = (Instruction instruction, long addr, ref long offset) =>
                                         ResolveSymbol(runtime, instruction, addr, currentMethodAddressRef.Value)
                    };

                    WriteJitInfo(runtime.ClrInfo, codeWriter);

                    var architecture = MapArchitecture(runtime.ClrInfo.DacInfo.TargetArchitecture);
                    foreach (var result in results)
                    {
                        DisassembleAndWrite(result, runtime, architecture, translator, currentMethodAddressRef, codeWriter);
                        codeWriter.WriteLine();
                    }
                }
        }
Exemplo n.º 3
0
        public string DumpASM()
        {
            TextWriter asmWriter = new StringWriter();

            using (DataTarget target = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive))
            {
                foreach (ClrInfo clrInfo in target.ClrVersions)
                {
                    this.engine.UpdateLog("Found CLR Version:" + clrInfo.Version.ToString());

                    // This is the data needed to request the dac from the symbol server:
                    ModuleInfo dacInfo = clrInfo.DacInfo;
                    this.engine.UpdateLog($"Filesize:  {dacInfo.FileSize:X}");
                    this.engine.UpdateLog($"Timestamp: {dacInfo.TimeStamp:X}");
                    this.engine.UpdateLog($"Dac File:  {dacInfo.FileName}");

                    ClrRuntime runtime   = target.ClrVersions.Single().CreateRuntime();
                    var        appDomain = runtime.AppDomains[0];
                    var        module    = appDomain.Modules.LastOrDefault(m => m.AssemblyName != null && m.AssemblyName.StartsWith(assemblyName));

                    asmWriter.WriteLine(
                        $"; {clrInfo.ModuleInfo.ToString()} ({clrInfo.Flavor} {clrInfo.Version})");
                    asmWriter.WriteLine(
                        $"; {clrInfo.DacInfo.FileName} ({clrInfo.DacInfo.TargetArchitecture} {clrInfo.DacInfo.Version})");
                    asmWriter.WriteLine();
                    foreach (var typeClr in module.EnumerateTypes())
                    {
                        asmWriter.WriteLine($"; Type {typeClr.Name}");

                        ClrHeap heap    = runtime.Heap;
                        ClrType @object = heap.GetTypeByMethodTable(typeClr.MethodTable);

                        foreach (ClrMethod method in @object.Methods)
                        {
                            MethodCompilationType compileType = method.CompilationType;
                            ArchitectureMode      mode        = clrInfo.DacInfo.TargetArchitecture == Architecture.X86
                                ? ArchitectureMode.x86_32
                                : ArchitectureMode.x86_64;

                            this.currentMethodAddress = 0;
                            var translator = new IntelTranslator
                            {
                                SymbolResolver = (Instruction instruction, long addr, ref long offset) =>
                                                 ResolveSymbol(runtime, instruction, addr, ref currentMethodAddress)
                            };

                            // This not work even ClrMd says opposite...
                            //ulong startAddress = method.NativeCode;
                            //ulong endAddress = method.ILOffsetMap.Select(entry => entry.EndAddress).Max();

                            DisassembleAndWrite(method, mode, translator, ref currentMethodAddress, asmWriter);
                            this.engine.UpdateLog($"Method {method.Name} disassembled to ASM.");
                            asmWriter.WriteLine();
                        }
                    }
                    break;
                }
            }
            return(asmWriter.ToString());
        }
Exemplo n.º 4
0
        private static int Main(string[] args)
        {
            Console.WriteLine();
            Console.WriteLine("Mosa.Tool.Disassembler.Intel.Disassembler [www.mosa-project.org]");
            Console.WriteLine("Copyright 2016. New BSD License.");
            Console.WriteLine("Written by Phil Garcia ([email protected])");
            Console.WriteLine();

            try
            {
                var options = ParseOptions(args);
                if (options == null)
                {
                    return(-1);                    //Commandline errors will be printed by the commandline lib
                }

                // Need a new instance of translator every time as they aren't thread safe
                var translator = new IntelTranslator()
                {
                    // Configure the translator to output instruction addresses and instruction binary as hex
                    IncludeAddress = true,
                    IncludeBinary  = true
                };

                var code2 = File.ReadAllBytes(options.InputFile);

                var code = new byte[code2.Length];

                for (ulong i = options.FileOffset; i < (ulong)code2.Length; i++)
                {
                    code[i - options.FileOffset] = code2[i];
                }

                //using (var disasm = new SharpDisasm.Disassembler(code, ArchitectureMode.x86_32, options.StartingAddress, true, Vendor.Any, options.FileOffset))
                using (var disasm = new SharpDisasm.Disassembler(code, ArchitectureMode.x86_32, options.StartingAddress, true, Vendor.Any))
                {
                    using (var dest = File.CreateText(options.OutputFile))
                    {
                        foreach (var instruction in disasm.Disassemble())
                        {
                            var inst = translator.Translate(instruction);
                            dest.WriteLine(inst);

                            if (options.Length != 0 && instruction.PC > options.StartingAddress + options.Length)
                            {
                                break;
                            }
                        }
                    }
                }

                return(0);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Exception: {0}", e.ToString());
                return(-1);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Disassembler" /> class. The instructions can then be disassembled with a call to <see cref="Disassemble"/>. The base address used to resolve relative addresses should be provided in <paramref name="address"/>.
        /// </summary>
        /// <param name="codePtr">A pointer to memory to be disassembled.</param>
        /// <param name="codeLength">The maximum length to be disassembled.</param>
        /// <param name="architecture">The architecture of the code (e.g. 64-bit, 32-bit or 16-bit).</param>
        /// <param name="address">The address of the first byte of code. This value is used to resolve relative addresses into absolute addresses while disassembling.</param>
        /// <param name="copyBinaryToInstruction">Keeps a copy of the binary code for the instruction. This will increase the memory usage for each instruction. This is necessary if planning on using the <see cref="Translators.Translator.IncludeBinary"/> option.</param>
        /// <param name="vendor">What vendors to support for disassembly, default is Any. Other options are AMD or Intel.</param>
        public Disassembler(IntPtr codePtr, int codeLength, ArchitectureMode architecture, ulong address = 0x0, bool copyBinaryToInstruction = false, Vendor vendor = Vendor.Any)
            : this(null, architecture, address, copyBinaryToInstruction, vendor)
        {
            if (codePtr == IntPtr.Zero)
            {
                throw new ArgumentOutOfRangeException("codePtr");
            }

            if (codeLength <= 0)
            {
                throw new ArgumentOutOfRangeException("codeLength", "Code length must be larger than 0.");
            }

            this.codePtr    = codePtr;
            this.codeLength = codeLength;

            Translator = new IntelTranslator();
        }
Exemplo n.º 6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Disassembler" /> class. Prepares a new disassembler instance for the code provided. The instructions can then be disassembled with a call to <see cref="Disassemble"/>. The base address used to resolve relative addresses should be provided in <paramref name="address"/>.
        /// </summary>
        /// <param name="code">The code to be disassembled</param>
        /// <param name="architecture">The target x86 instruction set architecture of the code (e.g. 64-bit, 32-bit or 16-bit).</param>
        /// <param name="address">The address of the first byte of code. This value is used to resolve relative addresses into absolute addresses while disassembling.</param>
        /// <param name="copyBinaryToInstruction">Keeps a copy of the binary code for the instruction. This will increase the memory usage for each instruction. This is necessary if planning on using the <see cref="Translators.Translator.IncludeBinary"/> option.</param>
        /// <param name="vendor">What vendor instructions to support during disassembly, default is Any. Other options are AMD or Intel.</param>
        public Disassembler(Byte[] code, ArchitectureMode architecture, ulong address = 0x0, bool copyBinaryToInstruction = true, Vendor vendor = Vendor.Any)
        {
            this.code                    = code;
            this.Architecture            = architecture;
            this.Address                 = address;
            this.CopyBinaryToInstruction = copyBinaryToInstruction;
            this.Vendor                  = vendor;

            if (code != null)
            {
                this.pinnedCodeArray = new AutoPinner(this.code);
                this.codePtr         = this.pinnedCodeArray;
                this.codeLength      = this.code.Length;
            }

            Translator = new IntelTranslator();
            this.InitUdis86();
        }
Exemplo n.º 7
0
        public void Decompile(Stream assemblyStream, TextWriter codeWriter)
        {
            var currentSetup = AppDomain.CurrentDomain.SetupInformation;

            using (var dataTarget = DataTarget.AttachToProcess(CurrentProcess.Id, UInt32.MaxValue, AttachFlag.Passive))
                using (var context = AppDomainContext.Create(new AppDomainSetup {
                    ApplicationBase = currentSetup.ApplicationBase,
                    PrivateBinPath = currentSetup.PrivateBinPath
                })) {
                    context.LoadAssembly(LoadMethod.LoadFrom, Assembly.GetExecutingAssembly().GetAssemblyFile().FullName);
                    var results = RemoteFunc.Invoke(context.Domain, assemblyStream, Remote.GetCompiledMethods);

                    var currentMethodAddressRef = new Reference <ulong>();
                    var runtime    = dataTarget.ClrVersions.Single().CreateRuntime();
                    var translator = new IntelTranslator {
                        SymbolResolver = (Instruction instruction, long addr, ref long offset) =>
                                         ResolveSymbol(runtime, instruction, addr, currentMethodAddressRef.Value)
                    };

                    codeWriter.WriteLine("; This is an experimental implementation.");
                    codeWriter.WriteLine("; Please report any bugs to https://github.com/ashmind/TryRoslyn/issues.");
                    codeWriter.WriteLine();

                    WriteJitInfo(runtime.ClrInfo, codeWriter);

                    var architecture = MapArchitecture(runtime.ClrInfo.DacInfo.TargetArchitecture);
                    foreach (var result in results)
                    {
                        var methodHandle = (ulong)result.Handle.ToInt64();
                        var method       = runtime.GetMethodByHandle(methodHandle);
                        if (method == null)
                        {
                            codeWriter.WriteLine("    ; Method with handle 0x{0:X} was somehow not found by CLRMD.", methodHandle);
                            codeWriter.WriteLine("    ; See https://github.com/ashmind/TryRoslyn/issues/84.");
                            continue;
                        }

                        DisassembleAndWrite(method, result.Message, architecture, translator, currentMethodAddressRef, codeWriter);
                        codeWriter.WriteLine();
                    }
                }
        }
Exemplo n.º 8
0
        public string DumpASM()
        {
            TextWriter asmWriter = new StringWriter();

            using (DataTarget target = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive))
            {
                foreach (ClrInfo clrInfo in target.ClrVersions)
                {
                    this.engine.UpdateLog("Found CLR Version:" + clrInfo.Version.ToString());

                    // This is the data needed to request the dac from the symbol server:
                    ModuleInfo dacInfo = clrInfo.DacInfo;
                    this.engine.UpdateLog($"Filesize:  {dacInfo.FileSize:X}");
                    this.engine.UpdateLog($"Timestamp: {dacInfo.TimeStamp:X}");
                    this.engine.UpdateLog($"Dac File:  {dacInfo.FileName}");

                    ClrRuntime runtime   = target.ClrVersions.Single().CreateRuntime();
                    var        appDomain = runtime.AppDomains[0];
                    var        module    = appDomain.Modules.LastOrDefault(m => m.AssemblyName != null && m.AssemblyName.StartsWith(assemblyName));

                    asmWriter.WriteLine(
                        $"; {clrInfo.ModuleInfo.ToString()} ({clrInfo.Flavor} {clrInfo.Version})");
                    asmWriter.WriteLine(
                        $"; {clrInfo.DacInfo.FileName} ({clrInfo.DacInfo.TargetArchitecture} {clrInfo.DacInfo.Version})");
                    asmWriter.WriteLine();
                    foreach (var typeClr in module.EnumerateTypes())
                    {
                        // Note: Accroding to https://github.com/dotnet/coreclr/blob/master/src/vm/methodtable.h:
                        // "(...) for value types GetBaseSize returns the size of instance fields for
                        // a boxed value, and GetNumInstanceFieldsBytes for an unboxed value."
                        // but mentioned method implementation is trivial:
                        // inline DWORD MethodTable::GetNumInstanceFieldBytes()
                        //{
                        //    LIMITED_METHOD_DAC_CONTRACT;
                        //    return (GetBaseSize() - GetClass()->GetBaseSizePadding());
                        //}

                        asmWriter.WriteLine($"; Type {typeClr.Name}");
                        asmWriter.WriteLine($";    MethodTable: 0x{typeClr.MethodTable:x16}");
                        asmWriter.WriteLine($";    Size:        {typeClr.BaseSize}{(typeClr.IsValueClass ? string.Format(" (when boxed)") : string.Empty)}");
                        asmWriter.WriteLine($";    IsValueType: {typeClr.IsValueClass}");
                        asmWriter.WriteLine($";    IsArray:     {typeClr.IsArray}");
                        asmWriter.WriteLine($";    IsEnum:      {typeClr.IsEnum}");
                        asmWriter.WriteLine($";    IsPrimitive: {typeClr.IsPrivate}");
                        asmWriter.WriteLine(";    Fields:");
                        asmWriter.WriteLine(";        {0,6} {1,16} {2,20} {3,4}", "Offset", "Name", "Type", "Size");
                        var orderedFields = typeClr.Fields.ToList().OrderBy(x => x.Offset);
                        foreach (var field in orderedFields)
                        {
                            asmWriter.WriteLine($";        {field.Offset,6} {field.Name,16} {field.Type.Name,20} {field.Size,4}");
                        }

                        ClrHeap heap = runtime.Heap;

                        foreach (ClrMethod method in typeClr.Methods)
                        {
                            MethodCompilationType compileType = method.CompilationType;
                            ArchitectureMode      mode        = clrInfo.DacInfo.TargetArchitecture == Architecture.X86
                                ? ArchitectureMode.x86_32
                                : ArchitectureMode.x86_64;

                            this.currentMethodAddress = 0;
                            var translator = new IntelTranslator
                            {
                                SymbolResolver = (Instruction instruction, long addr, ref long offset) =>
                                                 ResolveSymbol(runtime, instruction, addr, ref currentMethodAddress)
                            };

                            // This not work even ClrMd says opposite...
                            //ulong startAddress = method.NativeCode;
                            //ulong endAddress = method.ILOffsetMap.Select(entry => entry.EndAddress).Max();

                            DisassembleAndWrite(method, mode, translator, ref currentMethodAddress, asmWriter);
                            this.engine.UpdateLog($"Method {method.Name} disassembled to ASM.");
                            asmWriter.WriteLine();
                        }
                    }
                    break;
                }
            }
            return(asmWriter.ToString());
        }
Exemplo n.º 9
0
        private void GenerateASMFile()
        {
            var translator = new IntelTranslator()
            {
                IncludeAddress = true,
                IncludeBinary  = true
            };

            var map = new Dictionary <ulong, List <string> >();

            foreach (var symbol in Linker.Symbols)
            {
                if (!map.TryGetValue(symbol.VirtualAddress, out List <string> list))
                {
                    list = new List <string>();
                    map.Add(symbol.VirtualAddress, list);
                }

                list.Add(symbol.Name);
            }

            var textSection     = Linker.Sections[(int)SectionKind.Text];
            var startingAddress = textSection.VirtualAddress + MultibootHeaderLength;
            var fileOffset      = Linker.BaseFileOffset + MultibootHeaderLength;
            var length          = textSection.Size;

            var code2 = File.ReadAllBytes(LauncherSettings.OutputFile);

            var code = new byte[code2.Length];

            for (ulong i = fileOffset; i < (ulong)code2.Length; i++)
            {
                code[i - fileOffset] = code2[i];
            }

            var mode = ArchitectureMode.x86_32;

            switch (LauncherSettings.Platform)
            {
            case "x86": mode = ArchitectureMode.x86_32; break;

            case "x64": mode = ArchitectureMode.x86_64; break;
            }

            using (var disasm = new Disassembler(code, mode, startingAddress, true, Vendor.Any))
            {
                using (var dest = File.CreateText(LauncherSettings.AsmFile))
                {
                    if (map.TryGetValue(startingAddress, out List <string> list))
                    {
                        foreach (var entry in list)
                        {
                            dest.WriteLine($"; {entry}");
                        }
                    }

                    foreach (var instruction in disasm.Disassemble())
                    {
                        var inst = translator.Translate(instruction);
                        dest.WriteLine(inst);

                        if (map.TryGetValue(instruction.PC, out List <string> list2))
                        {
                            foreach (var entry in list2)
                            {
                                dest.WriteLine($"; {entry}");
                            }
                        }

                        if (instruction.PC > startingAddress + length)
                        {
                            break;
                        }
                    }
                }
            }
        }
Exemplo n.º 10
0
        private void GenerateASMFile()
        {
            var translator = new IntelTranslator()
            {
                IncludeAddress = true,
                IncludeBinary  = true
            };

            var asmfile = Path.Combine(LauncherOptions.DestinationDirectory, Path.GetFileNameWithoutExtension(LauncherOptions.SourceFile) + ".asm");

            var textSection = Linker.Sections[(int)SectionKind.Text];

            var map = new Dictionary <ulong, List <string> >();

            foreach (var symbol in Linker.Symbols)
            {
                if (!map.TryGetValue(symbol.VirtualAddress, out List <string> list))
                {
                    list = new List <string>();
                    map.Add(symbol.VirtualAddress, list);
                }

                list.Add(symbol.Name);
            }

            const uint multibootHeaderLength = MultibootHeaderLength;
            ulong      startingAddress       = textSection.VirtualAddress + multibootHeaderLength;
            uint       fileOffset            = textSection.FileOffset + multibootHeaderLength;
            uint       length = textSection.Size;

            var code2 = File.ReadAllBytes(CompiledFile);

            var code = new byte[code2.Length];

            for (ulong i = fileOffset; i < (ulong)code2.Length; i++)
            {
                code[i - fileOffset] = code2[i];
            }

            using (var disasm = new Disassembler(code, ArchitectureMode.x86_32, startingAddress, true, Vendor.Any))
            {
                using (var dest = File.CreateText(asmfile))
                {
                    if (map.TryGetValue(startingAddress, out List <string> list))
                    {
                        foreach (var entry in list)
                        {
                            dest.WriteLine($"; {entry}");
                        }
                    }

                    foreach (var instruction in disasm.Disassemble())
                    {
                        var inst = translator.Translate(instruction);
                        dest.WriteLine(inst);

                        if (map.TryGetValue(instruction.PC, out List <string> list2))
                        {
                            foreach (var entry in list2)
                            {
                                dest.WriteLine($"; {entry}");
                            }
                        }

                        if (instruction.PC > startingAddress + length)
                        {
                            break;
                        }
                    }
                }
            }
        }
Exemplo n.º 11
0
        private void GenerateASMFile()
        {
            // Need a new instance of translator every time as they aren't thread safe
            var translator = new IntelTranslator();

            // Configure the translator to output instruction addresses and instruction binary as hex
            translator.IncludeAddress = true;
            translator.IncludeBinary  = true;

            var asmfile = Path.Combine(Options.DestinationDirectory, Path.GetFileNameWithoutExtension(Options.SourceFile) + ".asm");

            var textSection = Linker.LinkerSections[(int)SectionKind.Text];

            var map = new Dictionary <ulong, string>();

            foreach (var symbol in Linker.Symbols)
            {
                if (map.ContainsKey(symbol.VirtualAddress))
                {
                    continue;
                }

                map.Add(symbol.VirtualAddress, symbol.Name);
            }

            uint  multibootHeaderLength = MultibootHeaderLength;
            ulong startingAddress       = textSection.VirtualAddress + multibootHeaderLength;
            uint  fileOffset            = textSection.FileOffset + multibootHeaderLength;
            uint  length = textSection.Size;

            var code2 = File.ReadAllBytes(CompiledFile);

            var code = new byte[code2.Length];

            for (ulong i = fileOffset; i < (ulong)code2.Length; i++)
            {
                code[i - fileOffset] = code2[i];
            }

            using (var disasm = new SharpDisasm.Disassembler(code, ArchitectureMode.x86_32, startingAddress, true, Vendor.Any))
            {
                using (var dest = File.CreateText(asmfile))
                {
                    if (map.ContainsKey(startingAddress))
                    {
                        dest.WriteLine("; " + map[startingAddress]);
                    }

                    foreach (var instruction in disasm.Disassemble())
                    {
                        var inst = translator.Translate(instruction);
                        dest.WriteLine(inst);

                        if (map.ContainsKey(instruction.PC))
                        {
                            dest.WriteLine("; " + map[instruction.PC]);
                        }

                        if (instruction.PC > startingAddress + length)
                        {
                            break;
                        }
                    }
                }
            }
        }