コード例 #1
0
ファイル: ClrDriver.cs プロジェクト: servicetitan/clrspy
        protected string?BuildDelegateMethodName(ClrType targetType, ulong action)
        {
            var typeAction        = heap.GetObjectType(action);
            var fieldMethodPtr    = typeAction.GetFieldByName("_methodPtr");
            var fieldMethodPtrAux = typeAction.GetFieldByName("_methodPtrAux");
            var methodPtr         = (ulong)(long)fieldMethodPtr.GetValue(action);

            if (methodPtr == 0)
            {
                return(null);
            }

            ClrMethod method = runtime.GetMethodByAddress(methodPtr)
                               ?? runtime.GetMethodByAddress((ulong)(long)fieldMethodPtrAux.GetValue(action)); // could happen in case of static method

            // anonymous method
            var methodTypeName = method.Type.Name;
            var targetTypeName = targetType.Name;

            return((methodTypeName != targetTypeName &&
                    targetTypeName != "System.Threading.WaitCallback" &&
                    !targetTypeName.StartsWith("System.Action<")     // method is implemented by an class inherited from targetType ... or a simple delegate indirection to a static/instance method
                        ? $"({targetTypeName})" : "")
                   + $"{methodTypeName}.{method.Name}");
        }
コード例 #2
0
        public string ResolveSymbol(ulong address)
        {
            using (DataTarget target =
                       DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive))
            {
                foreach (ClrInfo version in target.ClrVersions)
                {
                    ClrRuntime runtime         = target.ClrVersions.Single().CreateRuntime();
                    string     methodSignature = runtime.GetMethodByAddress(address)
                                                 ?.GetFullSignature();
                    if (!string.IsNullOrWhiteSpace(methodSignature))
                    {
                        return(methodSignature);
                    }
                }
            }

            Symbol symbol = this.nativeTarget.ResolveSymbol((ulong)address);

            if (!string.IsNullOrWhiteSpace(symbol.MethodName))
            {
                return(symbol.ToString());
            }
            return(null);
        }
コード例 #3
0
        private bool TryProcessNearJump(ulong methodPtr, [NotNull] ClrRuntime runtime,
                                        [CanBeNull] out ClrMethod methodDescriptor)
        {
            Assert.ArgumentNotNull(runtime, "runtime");
            try
            {
                byte[] bytes = ReadBytes(methodPtr + 1, runtime, 4);

                uint offset = 0;
                for (int i = bytes.Length; i > 0; i--)
                {
                    offset  = offset * 256;
                    offset += bytes[i - 1];
                }

                ulong res = methodPtr + 5 + offset;
                methodDescriptor = runtime.GetMethodByAddress(res);
                return(true);
            }
            catch (Exception)
            {
                methodDescriptor = null;
                return(false);
            }
        }
コード例 #4
0
        private static Translator GetTranslater(ClrRuntime runtime, AddressPrinter addressPrinter)
        {
            return(new IntelTranslator
            {
                SymbolResolver = (Instruction instruction, long address, ref long offset) =>
                {
                    var addr = (ulong)address;
                    var buffer = new StringWriter();

                    addressPrinter.Print(buffer, addr);

                    var operand = instruction.Operands.Length > 0 ? instruction.Operands[0] : null;
                    if (operand?.PtrOffset == 0)
                    {
                        return buffer.ToString();
                    }

                    var method = runtime.GetMethodByAddress(addr);
                    if (method != null)
                    {
                        buffer.Write(" (");
                        buffer.Write(method.GetFullSignature());
                        buffer.Write(")");
                    }

                    return buffer.ToString();
                }
            });
        }
コード例 #5
0
 private static ClrMethod GetMethod(ClrRuntime runtime, Remote.MethodJitResult result)
 {
     if (result.Pointer == null)
     {
         return(runtime.GetMethodByHandle((ulong)result.Handle.ToInt64()));
     }
     return(runtime.GetMethodByAddress((ulong)result.Pointer.Value.ToInt64()));
 }
コード例 #6
0
ファイル: ClrDacImpl.cs プロジェクト: youxiaotian/dnSpy
        public override bool TryGetSymbolCore(ulong address, out SymbolResolverResult result)
        {
            const ulong MIN_ADDR = 0x10000;

            if (address < MIN_ADDR)
            {
                result = default;
                return(false);
            }

            string name;

            name = clrRuntime.GetJitHelperFunctionName(address);
            if (!(name is null))
            {
                result = new SymbolResolverResult(SymbolKind.Function, name, address);
                return(true);
            }

            name = clrRuntime.GetMethodTableName(address);
            if (!(name is null))
            {
                result = new SymbolResolverResult(SymbolKind.Data, "methodtable(" + name + ")", address);
                return(true);
            }

            var method = clrRuntime.GetMethodByAddress(address);

            if (method is null && (address & ((uint)clrRuntime.PointerSize - 1)) == 0)
            {
                if (clrRuntime.ReadPointer(address, out ulong newAddress) && newAddress >= MIN_ADDR)
                {
                    method = clrRuntime.GetMethodByAddress(newAddress);
                }
            }
            if (!(method is null))
            {
                result = new SymbolResolverResult(SymbolKind.Function, method.ToString(), address);
                return(true);
            }

            result = default;
            return(false);
        }
コード例 #7
0
        private Tuple <ulong, uint, uint> GetClrRuntimeInstructionPointerInfo(Tuple <int, ulong> input)
        {
            int        runtimeId          = input.Item1;
            ulong      instructionPointer = input.Item2;
            ClrRuntime clrRuntime         = runtimesCache[runtimeId];
            ClrMethod  method             = clrRuntime.GetMethodByAddress(instructionPointer);
            ClrModule  clrModule          = method.Type.Module;

            return(Tuple.Create(clrModule.ImageBase, method.MetadataToken, FindIlOffset(method, instructionPointer)));
        }
コード例 #8
0
        private static string ResolveSymbol(ClrRuntime runtime, Instruction instruction, long addr, ulong currentMethodAddress)
        {
            var operand = instruction.Operands.Length > 0 ? instruction.Operands[0] : null;

            if (operand?.PtrOffset == 0)
            {
                var baseOffset = instruction.PC - currentMethodAddress;
                return($"L{baseOffset + operand.PtrSegment:x4}");
            }

            return(runtime.GetMethodByAddress(unchecked ((ulong)addr))?.GetFullSignature());
        }
コード例 #9
0
        private Tuple <string, ulong> ReadClrRuntimeFunctionNameAndDisplacement(Tuple <int, ulong> input)
        {
            int        runtimeId    = input.Item1;
            ulong      address      = input.Item2;
            ClrRuntime clrRuntime   = runtimesCache[runtimeId];
            ClrMethod  method       = clrRuntime.GetMethodByAddress(address);
            ClrModule  clrModule    = method.Type.Module;
            string     moduleName   = clrModule?.Name ?? "???";
            string     functionName = moduleName + "!" + method;
            ulong      displacement = address - method.NativeCode;

            return(Tuple.Create(functionName, displacement));
        }
コード例 #10
0
ファイル: ClrDacImpl.cs プロジェクト: yuan227301/dnSpy
        public override bool TryGetSymbolCore(ulong address, out SymbolResolverResult result)
        {
            string name;

            name = clrRuntime.GetJitHelperFunctionName(address);
            if (name != null)
            {
                result = new SymbolResolverResult(SymbolKind.Function, name, address);
                return(true);
            }

            name = clrRuntime.GetMethodTableName(address);
            if (name != null)
            {
                result = new SymbolResolverResult(SymbolKind.Data, "methodtable(" + name + ")", address);
                return(true);
            }

            var method = clrRuntime.GetMethodByAddress(address);

            if (method == null && address >= 0x10000)
            {
                if (clrRuntime.ReadPointer(address, out ulong newAddress))
                {
                    method = clrRuntime.GetMethodByAddress(newAddress);
                }
            }
            if (method != null)
            {
                result = new SymbolResolverResult(SymbolKind.Function, method.ToString(), method.NativeCode);
                return(true);
            }

            result = default;
            return(false);
        }
コード例 #11
0
        private string GetCalledMethodFromAssemblyOutput(ClrRuntime runtime, string assemblyString)
        {
            string hexAddressText   = "";
            var    callLocation     = assemblyString.LastIndexOf("call");
            var    qwordPtrLocation = assemblyString.IndexOf("qword ptr");
            var    openBracket      = assemblyString.IndexOf('(');
            var    closeBracket     = assemblyString.IndexOf(')');

            if (openBracket != -1 && closeBracket != -1 && closeBracket > openBracket)
            {
                // 000007fe`979171fb e800261b5e      call    mscorlib_ni+0x499800 (000007fe`f5ac9800)
                hexAddressText = assemblyString.Substring(openBracket, closeBracket - openBracket)
                                 .Replace("(", "")
                                 .Replace(")", "")
                                 .Replace("`", "");
            }
            else if (callLocation != -1 && qwordPtrLocation != -1)
            {
                // TODO have to also deal with:
                // 000007fe`979f666f 41ff13          call    qword ptr [r11] ds:000007fe`978e0050=000007fe978ed260
            }
            else if (callLocation != -1)
            {
                // 000007fe`979e6721 e8e2b5ffff      call    000007fe`979e1d08
                var endOfCallLocation = callLocation + 4;
                hexAddressText = assemblyString.Substring(endOfCallLocation, assemblyString.Length - endOfCallLocation)
                                 .Replace("`", "")
                                 .Trim(' ');
            }

            ulong actualAddress;

            if (ulong.TryParse(hexAddressText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out actualAddress))
            {
                ClrMethod method = runtime.GetMethodByAddress(actualAddress);
                if (method != null)
                {
                    return($"Call: {method.GetFullSignature()}");
                }
                else
                {
                    return($"Call: {actualAddress:x16} -> No matching method found");
                }
            }

            return($"\"{hexAddressText}\" -> Not a valid hex value");
        }
コード例 #12
0
        private static string?ResolveSymbol(ClrRuntime runtime, Instruction instruction, long addr, ulong currentMethodAddress)
        {
            var operand = instruction.Operands.Length > 0 ? instruction.Operands[0] : null;

            if (operand?.PtrOffset == 0)
            {
                var lvalue = GetOperandLValue(operand !);
                if (lvalue == null)
                {
                    return($"{operand!.RawValue} ; failed to resolve lval ({operand.Size}), please report at https://github.com/ashmind/SharpLab/issues");
                }
                var baseOffset = instruction.PC - currentMethodAddress;
                return($"L{baseOffset + lvalue:x4}");
            }

            return(runtime.GetMethodByAddress(unchecked ((ulong)addr))?.GetFullSignature());
        }
コード例 #13
0
ファイル: MethodDisassembler.cs プロジェクト: dreamsql/SeeJit
        public override void Disassemble(ClrRuntime runtime, TextWriter writer)
        {
            var method = runtime.GetMethodByAddress((ulong)Method.MethodHandle.GetFunctionPointer());
            if (method == null)
            {
                writer.Write("; Failed to load method '");

                var declaringType = Method.DeclaringType;
                if (declaringType != null)
                {
                    writer.Write(declaringType.FullName);
                    writer.Write('.');
                }

                writer.Write(Method.Name);
                writer.WriteLine("'.");

                return;
            }

            writer.Write("; ");
            writer.WriteLine(method.GetFullSignature());

            if (method.CompilationType == MethodCompilationType.None)
            {
                writer.WriteLine("; Failed to JIT compile this method.");
                writer.WriteLine("; Please see https://github.com/JeffreyZhao/SeeJit/issues/1 for more details.");

                return;
            }

            var methodAddress = method.HotColdInfo.HotStart;
            var methodSize = method.HotColdInfo.HotSize;
            var arch = runtime.ClrInfo.DacInfo.TargetArchitecture == Architecture.X86 ? ArchitectureMode.x86_32 : ArchitectureMode.x86_64;
            var instructions = Disassemble(methodAddress, methodSize, arch);
            var maxBytesLength = instructions.Max(i => i.Bytes.Length);
            var bytesColumnWidth = maxBytesLength * 2 + 2;
            var addressPrinter = arch == ArchitectureMode.x86_32 ? AddressPrinter.Short : AddressPrinter.Long;
            var translater = GetTranslater(runtime, addressPrinter);

            foreach (var ins in instructions)
            {
                PrintInstruction(writer, ins, addressPrinter, bytesColumnWidth, translater);
            }
        }
コード例 #14
0
        private (ClrMethod?method, HotColdRegions?regions) ResolveJitResult(ClrRuntime runtime, MethodJitResult result)
        {
            ClrMethod?methodByPointer = null;

            if (result.Pointer != null)
            {
                methodByPointer = runtime.GetMethodByAddress((ulong)result.Pointer.Value.ToInt64());
                if (methodByPointer != null)
                {
                    if (!result.IsSuccess)
                    {
                        return(methodByPointer, null);
                    }

                    var regionsByPointer = FindNonEmptyHotColdInfo(methodByPointer);
                    if (regionsByPointer != null)
                    {
                        return(methodByPointer, regionsByPointer);
                    }
                }
            }

            var methodByHandle = runtime.GetMethodByHandle((ulong)result.Handle.ToInt64());

            if (methodByHandle == null)
            {
                return(methodByPointer, null);
            }
            if (!result.IsSuccess)
            {
                return(methodByHandle, null);
            }
            var regionsByHandle = FindNonEmptyHotColdInfo(methodByHandle);

            if (regionsByHandle == null && methodByPointer != null)
            {
                return(methodByPointer, null);
            }

            return(methodByHandle, regionsByHandle);
        }
コード例 #15
0
ファイル: Timers.cs プロジェクト: unbaiat/dotnet-gargoyle
        private string BuildTimerCallbackMethodName(ClrRuntime runtime, ulong timerCallbackRef, string methodPtrString)
        {
            var heap      = runtime.Heap;
            var methodPtr = GetFieldValue(heap, timerCallbackRef, methodPtrString);

            if (methodPtr != null)
            {
                ClrMethod method = runtime.GetMethodByAddress((ulong)(long)methodPtr);
                if (method != null)
                {
                    // look for "this" to figure out the real callback implementor type
                    string thisTypeName = "?";
                    var    thisPtr      = GetFieldValue(heap, timerCallbackRef, "_target");
                    if ((thisPtr != null) && ((ulong)thisPtr) != 0)
                    {
                        ulong thisRef  = (ulong)thisPtr;
                        var   thisType = heap.GetObjectType(thisRef);
                        if (thisType != null)
                        {
                            thisTypeName = thisType.Name;
                        }
                    }
                    else
                    {
                        thisTypeName = (method.Type != null) ? method.Type.Name : "?";
                    }
                    return(method.GetFullSignature());

                    return(string.Format("{0}.{1}", thisTypeName, method.Name));
                }
                else
                {
                    return("");
                }
            }
            else
            {
                return("");
            }
        }
コード例 #16
0
        private string BuildTimerCallbackMethodName(ulong timerCallbackRef)
        {
            var methodPtr = GetFieldValue(timerCallbackRef, "_methodPtr");

            if (methodPtr != null)
            {
                var method = _clr.GetMethodByAddress((ulong)(long)methodPtr);
                if (method != null)
                {
                    // look for "this" to figure out the real callback implementor type
                    var thisTypeName = "?";
                    var thisPtr      = GetFieldValue(timerCallbackRef, "_target");
                    if ((thisPtr != null) && ((ulong)thisPtr) != 0)
                    {
                        ulong thisRef  = (ulong)thisPtr;
                        var   thisType = _heap.GetObjectType(thisRef);
                        if (thisType != null)
                        {
                            thisTypeName = thisType.Name;
                        }
                    }
                    else
                    {
                        thisTypeName = (method.Type != null) ? method.Type.Name : "?";
                    }
                    return($"{thisTypeName}.{method.Name}");
                }
                else
                {
                    return("");
                }
            }
            else
            {
                return("");
            }
        }
コード例 #17
0
        private string ResolveSymbol(ClrRuntime runtime, Instruction instruction, long addr, ref ulong currentMethodAddress)
        {
            var operand = instruction.Operands.Length > 0 ? instruction.Operands[0] : null;

            if (operand?.PtrOffset == 0)
            {
                var baseOffset = instruction.PC - currentMethodAddress;
                return($"L{baseOffset + operand.PtrSegment:x4}");
            }

            string signature = runtime.GetMethodByAddress(unchecked ((ulong)addr))?.GetFullSignature();

            if (!string.IsNullOrWhiteSpace(signature))
            {
                return(signature);
            }
            Symbol symbol = this.engine.ResolveNativeSymbol((ulong)addr);

            if (!string.IsNullOrWhiteSpace(symbol.MethodName))
            {
                return(symbol.ToString());
            }
            return(null);
        }
コード例 #18
0
        private static ClrMethod FindCompiledMethod(ClrRuntime runtime, MethodBase methodInfo)
        {
            var method = runtime.GetMethodByAddress((ulong)methodInfo.MethodHandle.GetFunctionPointer());

            if (method == null)
            {
                return(null);
            }

            if (method.CompilationType != MethodCompilationType.None)
            {
                return(method);
            }

            foreach (var other in method.Type.Methods)
            {
                if (other.MetadataToken == method.MetadataToken && other.CompilationType != MethodCompilationType.None)
                {
                    return(other);
                }
            }

            return(method);
        }
コード例 #19
0
        private static void OnGetMethodName(ClrRuntime runtime, string args)
        {
            // Use ClrMD as normal, but ONLY cache the copy of ClrRuntime (this.Runtime).  All other
            // types you get out of ClrMD (such as ClrHeap, ClrTypes, etc) should be discarded and
            // reobtained every run.
            ClrHeap heap = runtime.Heap;

            // Console.WriteLine now writes to the debugger.

            ClrMDHelper helper = new ClrMDHelper(runtime);

            try
            {
                ulong methodPtr;
                if (!ulong.TryParse(args.Trim(), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out methodPtr))
                {
                    Console.WriteLine("numeric value expected as method pointer");
                    return;
                }


                ClrMethod method = runtime.GetMethodByAddress(methodPtr);
                if (method != null)
                {
                    Console.WriteLine($"{method.Type.Name}.{method.Name}");
                }
                else
                {
                    Console.WriteLine("invalid method pointer.");
                }
            }
            catch (Exception x)
            {
                Console.WriteLine(x.Message);
            }
        }
コード例 #20
0
        private bool GetReferencedAddressToMethodName(out ulong refAddress, out uint codeSize, out string name, Instruction instruction, ClrRuntime runtime)
        {
            name       = null;
            refAddress = 0;
            codeSize   = 0;

            bool isAddressOk = false;

            for (int i = 0; i < instruction.OpCount; i++)
            {
                switch (instruction.GetOpKind(i))
                {
                case OpKind.NearBranch16:
                case OpKind.NearBranch32:
                case OpKind.NearBranch64:
                    refAddress  = instruction.NearBranchTarget;
                    isAddressOk = refAddress > ushort.MaxValue;
                    break;

                case OpKind.Immediate64:
                    refAddress  = instruction.GetImmediate(i);
                    isAddressOk = refAddress > ushort.MaxValue;
                    break;

                case OpKind.Memory64:
                    refAddress  = instruction.MemoryAddress64;
                    isAddressOk = refAddress > ushort.MaxValue;
                    break;

                case OpKind.Memory when instruction.IsIPRelativeMemoryOperand:
                    refAddress  = instruction.IPRelativeMemoryAddress;
                    isAddressOk = refAddress > ushort.MaxValue;
                    break;

                case OpKind.Memory:
                    refAddress  = instruction.MemoryDisplacement;
                    isAddressOk = refAddress > ushort.MaxValue;
                    break;
                }
            }

            if (refAddress == 0)
            {
                return(false);
            }

            var jitHelperFunctionName = runtime.GetJitHelperFunctionName(refAddress);

            if (string.IsNullOrWhiteSpace(jitHelperFunctionName) == false)
            {
                name = jitHelperFunctionName;
                return(true);
            }

            var methodTableName = runtime.GetMethodTableName(refAddress);

            if (string.IsNullOrWhiteSpace(methodTableName) == false)
            {
                name = methodTableName;
                return(true);
            }

            var methodDescriptor = runtime.GetMethodByHandle(refAddress);

            if (methodDescriptor != null)
            {
                name       = methodDescriptor.Name;
                refAddress = methodDescriptor.HotColdInfo.HotStart;
                codeSize   = methodDescriptor.HotColdInfo.HotSize;
                return(true);
            }

            var methodCall = runtime.GetMethodByAddress(refAddress);

            if (methodCall != null && string.IsNullOrWhiteSpace(methodCall.Name) == false)
            {
                name       = methodCall.Name;
                refAddress = methodCall.HotColdInfo.HotStart;
                codeSize   = methodCall.HotColdInfo.HotSize;
                return(true);
            }

            if (methodCall == null)
            {
                if (runtime.ReadPointer(refAddress, out ulong newAddress) && newAddress > ushort.MaxValue)
                {
                    methodCall = runtime.GetMethodByAddress(newAddress);
                }

                if (methodCall is null)
                {
                    return(false);
                }

                name       = methodCall.Name;
                refAddress = methodCall.HotColdInfo.HotStart;
                codeSize   = methodCall.HotColdInfo.HotSize;

                return(true);
            }

            return(false);
        }
コード例 #21
0
 /// <summary>
 ///     Attempts to get a ClrMethod for the given instruction pointer.  This will return NULL if the
 ///     given instruction pointer is not within any managed method.
 /// </summary>
 /// <param name="ip">The ip.</param>
 /// <returns>IClrMethod.</returns>
 /// <inheritdoc />
 public IClrMethod GetMethodByAddress(ulong ip) => Converter.Convert(Runtime.GetMethodByAddress(ip));