Ejemplo n.º 1
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());
        }
Ejemplo n.º 2
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());
        }