/// <summary> /// Get the <see cref="System.Reflection.MetadataToken"/> for the <see cref="mi"/> /// </summary> /// <param name="mi"></param> /// <param name="resolveManifold">True will cast the <see cref="mi"/> to /// a <see cref="MethodBase"/> and find the tokens used within the /// method's body. </param> /// <param name="asmIdx"></param> /// <returns></returns> public static MetadataTokenId GetMetadataToken(MemberInfo mi, bool resolveManifold, int asmIdx = 0) { if (mi == null) { return(new MetadataTokenId()); } var token = new MetadataTokenId { Id = mi.MetadataToken, RslvAsmIdx = asmIdx, Items = new MetadataTokenId[0] }; var mti = mi as MethodBase; if (mti == null) { return(token); } token.Items = resolveManifold ? Asm.GetCallsMetadataTokens(mti) .Where(t => t != mi.MetadataToken) .Select(t => new MetadataTokenId { Id = t, RslvAsmIdx = asmIdx }) .ToArray() : new MetadataTokenId[0]; return(token); }
/// <summary> /// Resolves the <see cref="tokenId"/>to a <see cref="MemberInfo"/> using /// the <see cref="manifestModule"/> /// </summary> /// <param name="manifestModule"></param> /// <param name="tokenId"></param> /// <param name="mi"></param> /// <param name="msgOut">Intended for debug trace from the Console.</param> /// <returns></returns> internal bool TryResolveRtMemberInfo(Module manifestModule, MetadataTokenId tokenId, out MemberInfo mi, StringBuilder msgOut) { mi = null; if (manifestModule == null) { return(false); } try { mi = manifestModule.ResolveMember(tokenId.Id); } catch (SystemException)//does not resolve the token { if (msgOut != null) { msgOut.Append(", Message: 'manifest module could not resolve id'"); } return(false); } return(mi != null); }
/// <summary> /// Get the <see cref="System.Reflection.MetadataToken"/> for the <see cref="asmType"/> /// and for all its members. /// </summary> /// <param name="asmType"></param> /// <param name="asmIdx"></param> /// <param name="logFile"> /// optional, the path to a log file where any assembly, type, member, method, etc. loader exceptions will be written. /// </param> /// <returns></returns> public static MetadataTokenId GetMetadataToken(Type asmType, int asmIdx = 0, string logFile = null) { if (asmType == null) { return new MetadataTokenId { Items = new MetadataTokenId[0] } } ; var token = new MetadataTokenId { Id = asmType.MetadataToken, RslvAsmIdx = asmIdx, Items = asmType.NfGetMembers(NfSettings.DefaultFlags, false, logFile) .Select(x => GetMetadataToken(x, true, asmIdx)) .Distinct() .ToArray() }; return(token); }
public void TestFlattenToDistinct() { var t0 = new MetadataTokenId { Id = 1, RslvAsmIdx = 0, Items = new[] { new MetadataTokenId { Id = 2, RslvAsmIdx = 0, Items = new[] { new MetadataTokenId {Id = 3, RslvAsmIdx = 0}, new MetadataTokenId { Id = 4, RslvAsmIdx = 0, Items = new[] { new MetadataTokenId {Id = 1, RslvAsmIdx = 1}, new MetadataTokenId {Id = 2, RslvAsmIdx = 1} } }, new MetadataTokenId { Id = 5, RslvAsmIdx = 0, Items = new[] {new MetadataTokenId {Id = 1, RslvAsmIdx = 1}} } }, }, new MetadataTokenId {Id = 6, RslvAsmIdx = 0}, new MetadataTokenId {Id = 7, RslvAsmIdx = 0} } }; var t1 = new MetadataTokenId { Id = 8, RslvAsmIdx = 0, Items = new[] { new MetadataTokenId { Id = 9, RslvAsmIdx = 0, Items = new[] {new MetadataTokenId {Id = 1, RslvAsmIdx = 0}} } } }; var testSubject = new TokenIds {Tokens = new[] {t0, t1}}; var testResult = testSubject.FlattenToDistinct(); Assert.IsNotNull(testResult); Assert.AreNotEqual(0, testResult.Length); Assert.AreEqual(11, testResult.Length); testResult = testSubject.FlattenToDistinct(true); Assert.IsNotNull(testResult); Assert.AreNotEqual(0, testResult.Length); Assert.AreEqual(11,testResult.Length); var t1x0 = testResult.FirstOrDefault(x => x.Id == 1 && x.RslvAsmIdx == 0); Assert.IsNotNull(t1x0); Assert.IsNotNull(t1x0.Items); Assert.AreNotEqual(0,t1x0.Items.Length); Assert.AreEqual(3, t1x0.Items.Length); }
/// <summary> /// Attempts to resolve <see cref="tokenId"/> to a <see cref="MetadataTokenName"/> /// </summary> /// <param name="resolvesWith"></param> /// <param name="tokenId"></param> /// <param name="tokenName"></param> /// <param name="msgOut">Intended for debug trace from the Console.</param> /// <returns></returns> internal bool ResolveSingleTokenName(Assembly resolvesWith, MetadataTokenId tokenId, out MetadataTokenName tokenName, StringBuilder msgOut = null) { tokenName = null; if (tokenId.Id == 0) { if (msgOut != null) { msgOut.Append(", Message:'the token id is zero'"); } return(false); } if (_myProgram.TokenId2NameCache.ContainsKey(tokenId)) { tokenName = _myProgram.TokenId2NameCache[tokenId]; if (msgOut != null) { msgOut.Append(", Message:'token previously resolved'"); } return(true); } if (resolvesWith == null) { if (msgOut != null) { msgOut.Append(string.Format(", Message:'resolve assembly idx {0} has no match'", tokenId.RslvAsmIdx)); } return(false); } MemberInfo mi; var rtMiRslt = false; rtMiRslt = TryResolveRtMemberInfo(resolvesWith.ManifestModule, tokenId, out mi, msgOut); if (!rtMiRslt) { return(false); } if (mi == null) { return(false); } tokenName = AssemblyAnalysis.ConvertToMetadataTokenName(mi, _myProgram.AsmIndicies, IsIgnore, _myProgram.LogFile); if (tokenName == null) { if (msgOut != null) { msgOut.Append(", Message:'could not construct a token name'"); } return(false); } tokenName.Id = tokenId.Id; tokenName.RslvAsmIdx = tokenId.RslvAsmIdx; tokenName.DeclTypeId = mi.DeclaringType?.MetadataToken ?? 0; return(true); }
/// <summary> /// Helper method which resolves the assembly using the <see cref="tokenId"/> RslvAsmIdx. /// </summary> /// <param name="tokenId"></param> /// <param name="tokenName"></param> /// <param name="msgOut">Intended for debug trace from the Console.</param> /// <returns></returns> internal bool ResolveSingleTokenName(MetadataTokenId tokenId, out MetadataTokenName tokenName, StringBuilder msgOut = null) { var manifestAsm = _myProgram.AsmIndicies.GetAssemblyByIndex(tokenId.RslvAsmIdx); return(ResolveSingleTokenName(manifestAsm, tokenId, out tokenName, msgOut)); }
/// <summary> /// Get the <see cref="System.Reflection.MetadataToken"/> for the <see cref="mi"/> /// </summary> /// <param name="mi"></param> /// <param name="resolveManifold">True will cast the <see cref="mi"/> to /// a <see cref="MethodBase"/> and find the tokens used within the /// method's body. </param> /// <param name="asmIdx"></param> /// <returns></returns> public static MetadataTokenId GetMetadataToken(MemberInfo mi, bool resolveManifold, int asmIdx = 0) { if (mi == null) return new MetadataTokenId(); var token = new MetadataTokenId { Id = mi.MetadataToken, RslvAsmIdx = asmIdx, Items = new MetadataTokenId[0] }; var mti = mi as MethodBase; if (mti == null) return token; token.Items = resolveManifold ? Asm.GetCallsMetadataTokens(mti) .Where(t => t != mi.MetadataToken) .Select(t => new MetadataTokenId {Id = t, RslvAsmIdx = asmIdx}) .ToArray() : new MetadataTokenId[0]; return token; }
/// <summary> /// Helper method which resolves the assembly using the <see cref="tokenId"/> RslvAsmIdx. /// </summary> /// <param name="tokenId"></param> /// <param name="tokenName"></param> /// <param name="msgOut">Inteneded for debug trace from the Console.</param> /// <returns></returns> internal bool ResolveSingleTokenName(MetadataTokenId tokenId, out MetadataTokenName tokenName, StringBuilder msgOut = null) { var manifestAsm = _myProgram.AsmIndicies.GetAssemblyByIndex(tokenId.RslvAsmIdx); return ResolveSingleTokenName(manifestAsm, tokenId, out tokenName, msgOut); }
/// <summary> /// Resolves the outbound call stack for the given <see cref="token"/> /// </summary> /// <param name="token"></param> /// <param name="depth"></param> /// <param name="stackTrc">For detecting recursive call patterns</param> /// <param name="msgOut">For getting details on recursion.</param> internal void ResolveCallOfCall(MetadataTokenId token, ref int depth, Stack <MetadataTokenId> stackTrc, StringBuilder msgOut) { if (msgOut != null) { if (depth > 0) { msgOut.Append(new string(' ', depth)); } msgOut.AppendFormat("Depth:{0}", depth); msgOut.AppendFormat(", Token:{0}.0x{1}", token.RslvAsmIdx, token.Id.ToString("X4")); } //detect if we are in a recursive call if (stackTrc.Any(x => x.Equals(token))) { if (msgOut != null) { msgOut.AppendLine(", Message:'present in stack trace'"); } return; } stackTrc.Push(new MetadataTokenId { Id = token.Id, RslvAsmIdx = token.RslvAsmIdx }); //increment the current depth depth += 1; //abort if max depth has been reached if (depth > ((IaaProgram)MyProgram).MaxRecursionDepth) { depth -= 1; MyProgram.PrintToConsole( String.Format("Max Recursion Depth @ {0}.{1}\n", token.RslvAsmIdx, token.Id)); if (msgOut != null) { msgOut.AppendLine(", Message:'max recursion depth'"); } return; } //when there are already Items then leave them as is if (token.Items != null && token.Items.Length > 0) { depth -= 1; if (msgOut != null) { msgOut.AppendLine(", Message:'Items already present'"); } return; } //don't waste clock cycles on Ignore types if (((IaaProgram)MyProgram).DisolutionCache.Contains(token)) { depth -= 1; if (msgOut != null) { msgOut.AppendLine(", Message:'token in DisolutionCache'"); } return; } //resolve token to name MetadataTokenName tokenName = null; if (((IaaProgram)MyProgram).TokenId2NameCache.ContainsKey(token)) { tokenName = ((IaaProgram)MyProgram).TokenId2NameCache[token]; } else { // the token must be resolvable with the its manifest module var resolveRslt = ((IaaProgram)MyProgram).UtilityMethods.ResolveSingleTokenName(token, out tokenName, msgOut); if (!resolveRslt || tokenName == null) { ((IaaProgram)MyProgram).DisolutionCache.Add(token); depth -= 1; if (msgOut != null) { msgOut.AppendLine(", Message:'ResolveSingleTokenName failed'"); } return; } ((IaaProgram)MyProgram).TokenId2NameCache.Add(token, tokenName); } //only proceed to find calls of calls, types are resolved elsewhere if (!tokenName.IsMethodName()) { depth -= 1; if (msgOut != null) { msgOut.AppendLine(", Message:'token is not a method'"); } return; } //match is on Asm Name, not type nor member name var owningAsmName = ((IaaProgram)MyProgram).AsmIndicies.Asms.FirstOrDefault(x => x.IndexId == tokenName.OwnAsmIdx); if (owningAsmName == null) { ((IaaProgram)MyProgram).DisolutionCache.Add(token); depth -= 1; if (msgOut != null) { msgOut.AppendLine(string.Format(", Message:'owning assembly idx {0} has no match'", tokenName.OwnAsmIdx)); } return; } //check for match of asm name to user defined regex if (!Regex.IsMatch(owningAsmName.AssemblyName, ((IaaProgram)MyProgram).AssemblyNameRegexPattern)) { ((IaaProgram)MyProgram).DisolutionCache.Add(token); if (msgOut != null) { msgOut.AppendLine(string.Format(", Message:'assembly name [{1}] does not match regex [{0}]'", ((IaaProgram)MyProgram).AssemblyNameRegexPattern, owningAsmName.AssemblyName)); } depth -= 1; return; } //resolve token to runtime member info MemberInfo mi; var rtMiRslt = ((IaaProgram)MyProgram).UtilityMethods.TryResolveRtMemberInfo(((IaaProgram)MyProgram).AsmIndicies.GetAssemblyByIndex(owningAsmName.IndexId), tokenName.Name, out mi, msgOut); if (!rtMiRslt) { ((IaaProgram)MyProgram).DisolutionCache.Add(token); depth -= 1; return; } //get the token as it is called in its own assembly var r = AssemblyAnalysis.GetMetadataToken(mi, true, tokenName.OwnAsmIdx); if (stackTrc.Any(x => x.Equals(r))) { depth -= 1; token.IsByRef = 1; if (msgOut != null) { msgOut.AppendLine(string.Format(", Message:'name resolved token id {0},{1} found in stack trace'", r.RslvAsmIdx, r.Id.ToString("X4"))); } return; } //this token differs from the method arg 'token' stackTrc.Push(new MetadataTokenId { Id = r.Id, RslvAsmIdx = r.RslvAsmIdx }); //unwind when its a terminal token if (r.Items == null || r.Items.Length <= 0) { depth -= 1; if (msgOut != null) { msgOut.AppendLine(string.Format(", Message:'name resolved token id {0},{1} is a terminal node'", r.RslvAsmIdx, r.Id.ToString("X4"))); } return; } //these token ids are only resolvable to the asm who owns MemberInfo(mi) token.Items = r.Items; //recurse each of these calls-of-calls[...]-of-calls foreach (var iToken in token.Items) { ResolveCallOfCall(iToken, ref depth, stackTrc, msgOut); } depth -= 1; }
/// <summary> /// Get the <see cref="System.Reflection.MetadataToken"/> for the <see cref="asmType"/> /// and for all its members. /// </summary> /// <param name="asmType"></param> /// <param name="asmIdx"></param> /// <returns></returns> public static MetadataTokenId GetMetadataToken(Type asmType, int asmIdx = 0) { if (asmType == null) return new MetadataTokenId { Items = new MetadataTokenId[0] }; var token = new MetadataTokenId { Id = asmType.MetadataToken, RslvAsmIdx = asmIdx, Items = asmType.GetMembers(NfConfig.DefaultFlags) .Select(x => GetMetadataToken(x, true, asmIdx)) .Distinct() .ToArray() }; return token; }
/// <summary> /// Helper method to loop ids to names. /// </summary> /// <param name="tokens"></param> /// <returns></returns> internal List<MetadataTokenName> ResolveAllTokenNames(MetadataTokenId[] tokens) { var counter = 0; var total = tokens.Length; var names = new List<MetadataTokenName>(); for (var i = 0; i < tokens.Length; i++) { counter += 1; try { var cid = tokens[i]; _myProgram.ReportProgress(new ProgressMessage { Activity = string.Format("{0}.{1}", cid.RslvAsmIdx, cid.Id), ProcName = System.Diagnostics.Process.GetCurrentProcess().ProcessName, ProgressCounter = Etc.CalcProgressCounter(counter, total), Status = "Resolving names" }); if (_myProgram.DisolutionCache.Contains(cid) || names.Any(x => x.Id == cid.Id && x.RslvAsmIdx == cid.RslvAsmIdx)) continue; if (_myProgram.TokenId2NameCache.ContainsKey(cid)) { names.Add(_myProgram.TokenId2NameCache[cid]); continue; } MetadataTokenName tokenName; var resolved = ResolveSingleTokenName(cid, out tokenName); if (!resolved) { if (!_myProgram.DisolutionCache.Contains(cid)) _myProgram.DisolutionCache.Add(cid); continue; } names.Add(tokenName); if (!_myProgram.TokenId2NameCache.ContainsKey(cid)) { _myProgram.TokenId2NameCache.Add(cid, tokenName); } } catch { continue; } } return names; }
/// <summary> /// Resolves the <see cref="tokenId"/>to a <see cref="MemberInfo"/> using /// the <see cref="manifestModule"/> /// </summary> /// <param name="manifestModule"></param> /// <param name="tokenId"></param> /// <param name="mi"></param> /// <param name="msgOut">Inteneded for debug trace from the Console.</param> /// <returns></returns> internal bool TryResolveRtMemberInfo(Module manifestModule, MetadataTokenId tokenId, out MemberInfo mi, StringBuilder msgOut) { mi = null; if (manifestModule == null) return false; try { mi = manifestModule.ResolveMember(tokenId.Id); } catch (SystemException)//does not resolve the token { if (msgOut != null) msgOut.Append(", Message: 'manifest module could not resolve id'"); return false; } return mi != null; }
/// <summary> /// Attempts to resolve <see cref="tokenId"/> to a <see cref="MetadataTokenName"/> /// </summary> /// <param name="resolvesWith"></param> /// <param name="tokenId"></param> /// <param name="tokenName"></param> /// <param name="msgOut">Inteneded for debug trace from the Console.</param> /// <returns></returns> internal bool ResolveSingleTokenName(Assembly resolvesWith, MetadataTokenId tokenId, out MetadataTokenName tokenName, StringBuilder msgOut = null) { tokenName = null; if (tokenId.Id == 0) { if (msgOut != null) msgOut.Append(", Message:'the token id is zero'"); return false; } if (_myProgram.TokenId2NameCache.ContainsKey(tokenId)) { tokenName = _myProgram.TokenId2NameCache[tokenId]; if (msgOut != null) msgOut.Append(", Message:'token previously resolved'"); return true; } if (resolvesWith == null) { if (msgOut != null) msgOut.Append(string.Format(", Message:'resolve assembly idx {0} has no match'", tokenId.RslvAsmIdx)); return false; } MemberInfo mi; var rtMiRslt = false; rtMiRslt = TryResolveRtMemberInfo(resolvesWith.ManifestModule, tokenId, out mi, msgOut); if (!rtMiRslt) { return false; } if (mi == null) { return false; } tokenName = AssemblyAnalysis.ConvertToMetadataTokenName(mi, _myProgram.AsmIndicies, IsIgnore); if (tokenName == null) { if (msgOut != null) msgOut.Append(", Message:'could not construct a token name'"); return false; } tokenName.Id = tokenId.Id; tokenName.RslvAsmIdx = tokenId.RslvAsmIdx; return true; }
public void TestFlattenToDistinct() { var t0 = new MetadataTokenId { Id = 1, RslvAsmIdx = 0, Items = new[] { new MetadataTokenId { Id = 2, RslvAsmIdx = 0, Items = new[] { new MetadataTokenId { Id = 3, RslvAsmIdx = 0 }, new MetadataTokenId { Id = 4, RslvAsmIdx = 0, Items = new[] { new MetadataTokenId { Id = 1, RslvAsmIdx = 1 }, new MetadataTokenId { Id = 2, RslvAsmIdx = 1 } } }, new MetadataTokenId { Id = 5, RslvAsmIdx = 0, Items = new[] { new MetadataTokenId { Id = 1, RslvAsmIdx = 1 } } } }, }, new MetadataTokenId { Id = 6, RslvAsmIdx = 0 }, new MetadataTokenId { Id = 7, RslvAsmIdx = 0 } } }; var t1 = new MetadataTokenId { Id = 8, RslvAsmIdx = 0, Items = new[] { new MetadataTokenId { Id = 9, RslvAsmIdx = 0, Items = new[] { new MetadataTokenId { Id = 1, RslvAsmIdx = 0 } } } } }; var testSubject = new MetadataTokenId() { Items = new[] { t0, t1 } }; var testResult = testSubject.SelectDistinct(); Assert.IsNotNull(testResult); Assert.AreNotEqual(0, testResult.Length); Assert.AreEqual(11, testResult.Length); testResult = testSubject.SelectDistinct(true); Assert.IsNotNull(testResult); Assert.AreNotEqual(0, testResult.Length); Assert.AreEqual(11, testResult.Length); var t1x0 = testResult.FirstOrDefault(x => x.Id == 1 && x.RslvAsmIdx == 0); Assert.IsNotNull(t1x0); Assert.IsNotNull(t1x0.Items); Assert.AreNotEqual(0, t1x0.Items.Length); Assert.AreEqual(3, t1x0.Items.Length); }
/// <summary> /// Resolves the given Metadata Token Ids to thier names & types. /// </summary> /// <param name="metadataTokenIds"></param> /// <returns></returns> public TokenNames GetTokenNames(MetadataTokenId[] metadataTokenIds) { return _getTokenNamesCmd.Receive(metadataTokenIds); }
/// <summary> /// Handles a specific set of formatted runtime commands as printed in <see cref="RuntimeHelp"/> /// </summary> /// <param name="ut">User entered text</param> protected internal void RtCommands(string ut) { try { if (string.IsNullOrWhiteSpace(ut)) return; if (!ut.StartsWith(Constants.CMD_LINE_ARG_SWITCH)) return; var cmds = ut.Split(' '); var rtArgHash = ConsoleCmd.ArgHash(cmds); if (rtArgHash.ContainsKey(ASSIGN_REGEX_PATTERN_RT_CMD)) { var regexPattern = rtArgHash[ASSIGN_REGEX_PATTERN_RT_CMD]; if (string.IsNullOrWhiteSpace(regexPattern?.ToString())) return; AssemblyNameRegexPattern = regexPattern.ToString().Trim(); PrintToConsole($"AssemblyNameRegexPattern = {AssemblyNameRegexPattern}"); } if (rtArgHash.ContainsKey(RESOLVE_TOKEN_ID_CMD)) { var tokenCmd = rtArgHash[RESOLVE_TOKEN_ID_CMD]; if (string.IsNullOrWhiteSpace(tokenCmd?.ToString())) return; var tokenCmdStr = tokenCmd.ToString().Trim(); if (!Regex.IsMatch(tokenCmdStr, @"^[0-9]\.([0-9]+|0x[0-9a-fA-F]+)$")) return; var asmIdxStr = tokenCmdStr.Split('.')[0]; var tokenIdStr = tokenCmdStr.Split('.')[1]; int tokenId; int asmIdx; if (!int.TryParse(asmIdxStr, out asmIdx)) return; if (Regex.IsMatch(tokenIdStr, "0x[0-9a-fA-F]+")) { tokenIdStr = tokenIdStr.Substring(2); if (!int.TryParse(tokenIdStr, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out tokenId)) return; } else { if (!int.TryParse(tokenIdStr, out tokenId)) return; } var mdt = new MetadataTokenId { Id = tokenId, RslvAsmIdx = asmIdx }; MetadataTokenName tokenName; if (!_utilityMethods.ResolveSingleTokenName(mdt, out tokenName)) { PrintToConsole($"could not resolve name {ut}"); return; } PrintToConsole(tokenName.Name); if (!tokenName.IsMethodName()) return; var resolveDepth = 0; var st = new Stack<MetadataTokenId>(); var msg = new StringBuilder(); var tTokensIds = new GetTokenIds(this); tTokensIds.ResolveCallOfCall(mdt, ref resolveDepth, st, msg); if (mdt.Items == null || mdt.Items.Length <= 0) { PrintToConsole("ResolveCallOfCall returned nothing"); PrintToConsole(msg.ToString(), false); return; } Console.WriteLine(); PrintToConsole(MetadataTokenId.Print(mdt), false); } } catch (Exception ex) { PrintToConsole("console entry error"); PrintToConsole(ex); } }
/// <summary> /// Handles a specific set of formatted runtime commands as printed in <see cref="RuntimeHelp"/> /// </summary> /// <param name="ut">User entered text</param> protected internal void RtCommands(string ut) { try { if (string.IsNullOrWhiteSpace(ut)) { return; } if (!ut.StartsWith(NfConfig.CmdLineArgSwitch)) { return; } var cmds = ut.Split(' '); var rtArgHash = ConsoleCmd.ArgHash(cmds); if (rtArgHash.ContainsKey(ASSIGN_REGEX_PATTERN_RT_CMD)) { var regexPattern = rtArgHash[ASSIGN_REGEX_PATTERN_RT_CMD]; if (string.IsNullOrWhiteSpace(regexPattern?.ToString())) { return; } AssemblyNameRegexPattern = regexPattern.ToString().Trim(); PrintToConsole($"AssemblyNameRegexPattern = {AssemblyNameRegexPattern}"); } if (rtArgHash.ContainsKey(RESOLVE_TOKEN_ID_CMD)) { var tokenCmd = rtArgHash[RESOLVE_TOKEN_ID_CMD]; if (string.IsNullOrWhiteSpace(tokenCmd?.ToString())) { return; } var tokenCmdStr = tokenCmd.ToString().Trim(); if (!Regex.IsMatch(tokenCmdStr, @"^[0-9]\.([0-9]+|0x[0-9a-fA-F]+)$")) { return; } var asmIdxStr = tokenCmdStr.Split('.')[0]; var tokenIdStr = tokenCmdStr.Split('.')[1]; int tokenId; int asmIdx; if (!int.TryParse(asmIdxStr, out asmIdx)) { return; } if (Regex.IsMatch(tokenIdStr, "0x[0-9a-fA-F]+")) { tokenIdStr = tokenIdStr.Substring(2); if (!int.TryParse(tokenIdStr, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out tokenId)) { return; } } else { if (!int.TryParse(tokenIdStr, out tokenId)) { return; } } var mdt = new MetadataTokenId { Id = tokenId, RslvAsmIdx = asmIdx }; MetadataTokenName tokenName; if (!_utilityMethods.ResolveSingleTokenName(mdt, out tokenName)) { PrintToConsole($"could not resolve name {ut}"); return; } PrintToConsole(tokenName.Name); if (!tokenName.IsMethodName()) { return; } var resolveDepth = 0; var st = new Stack <MetadataTokenId>(); var msg = new StringBuilder(); var tTokensIds = new GetTokenIds(this); tTokensIds.ResolveCallOfCall(mdt, ref resolveDepth, st, msg); if (mdt.Items == null || mdt.Items.Length <= 0) { PrintToConsole("ResolveCallOfCall returned nothing"); PrintToConsole(msg.ToString(), false); return; } Console.WriteLine(); PrintToConsole(MetadataTokenId.Print(mdt), false); } } catch (Exception ex) { PrintToConsole("console entry error"); PrintToConsole(ex); } }