private bool FindInterfaceMethod(MethodDefinition method, MethodObject methodNode) { // multi level inheritance is flattened here foreach (var interfaceParent in method.DeclaringType.Interfaces) { var matchingMethod = InterfaceMethodsIndexedByTypeName.Get(interfaceParent.InterfaceType.FullName) .FirstOrDefault(x => SignatureKeyService.GetMethodSignature(x).Equals(SignatureKeyService.GetMethodSignature(method))); if (matchingMethod != null) { methodNode.InterfaceMethod = matchingMethod; methodNode.ImplementsType = ImplementsType.Interface; return(true); } else // might be an interface with generics. We have indexed the generic form but now search using a generic instance (instead of T, a real type) { TypeDefinition interfaceDefinition = null; var resolved = ResolveService.TryResolve(interfaceParent.InterfaceType, out interfaceDefinition); if (resolved && interfaceDefinition.GenericParameters.Any()) { return(ResolveGenericsInterface(method, methodNode, interfaceParent.InterfaceType, interfaceDefinition)); } } } return(false); }
private void IndexConcreteMethods(ModuleDefinition module) { var implementationMethods = DecompilerService.GetConcreteMethods(module); foreach (var method in implementationMethods) { if (ShouldSkip(method)) { continue; } var methodNameKey = SignatureKeyService.GetFullMethodSignature(method); if (!ImplementationMethodsIndexedByName.ContainsKey(methodNameKey)) { ImplementationMethodsIndexedByName.Add(methodNameKey, method); ImplementationMethodsList.Add(method); ImplementationMethodsIndexedByTypeName.Add(method.DeclaringType.FullName, method); } var genericSignature = SignatureKeyService.GetGenericMethodSignature(method); if (!string.IsNullOrEmpty(genericSignature)) { if (!ImplementationMethodsIndexedByGenericSignature.ContainsKey(genericSignature)) { ImplementationMethodsIndexedByGenericSignature.Add(genericSignature, method); } } } }
private void IndexInterfaceMethods(ModuleDefinition module) { var interfaceMethods = DecompilerService.GetInterfaceMethods(module); foreach (var method in interfaceMethods) { // index by a simplified generic signature if it is a generic interface method var genericSignature = SignatureKeyService.GetGenericMethodSignature(method); if (!string.IsNullOrEmpty(genericSignature)) { if (!InterfaceMethodsIndexedByGenericSignature.ContainsKey(genericSignature)) { InterfaceMethodsIndexedByGenericSignature.Add(genericSignature, method); } } // index by the standard method signature var methodSignature = SignatureKeyService.GetFullMethodSignature(method); if (!InterfaceMethodsIndexedByName.ContainsKey(methodSignature)) { InterfaceMethodsIndexedByName.Add(methodSignature, method); } InterfaceMethodsIndexedByTypeName.Add(method.DeclaringType.FullName, method); InterfaceMethodsList.Add(method); } }
private void DoCrossAssemblyWalk(MethodGraph methodGraph, string companyAssembliesPattern, ModuleDefinition module, string moduleMessagee) { var publicMethods = DecompilerService.GetPublicMethods(companyAssembliesPattern, module) .Where(x => !IsBlackListed(x)) .OrderBy(x => x.DeclaringType.Name) .ThenBy(x => x.Name) .ToList(); int methodCount = publicMethods.Count; var publicMethodsAnalyzed = new HashSet <string>(); _methodNodeLookup.Clear(); int methodCounter = 0; foreach (var publicMethod in publicMethods) { methodCounter++; _logOutput.LogAnalysis("Method " + methodCounter + " of " + methodCount + " : " + moduleMessagee + " -> " + publicMethod.Name); if ((publicMethod.IsGetter || publicMethod.IsSetter) && !IsNoteworthyProperty(publicMethod)) { continue; } var signature = SignatureKeyService.GetFullMethodSignature(publicMethod); if (_methodIndexer.HasMethod(signature)) { var unfilteredRootNodes = _methodIndexer.GetMethods(signature); var rootNodes = unfilteredRootNodes.Where(x => x.HasImplementation() && ( // if it is a public implementation of a different assembly, then'll we'll filter it out here (and analyze it that assembly) (x.ConcreteMethod.IsPublic && x.ConcreteMethod.Module.Name.Equals(module.Name)) // if it is a private implementation then analyze it now as we'll miss it when we analyze the public methods of the other assembly || !x.ConcreteMethod.DeclaringType.IsPublic ) ) .ToList(); foreach (var rootMethod in rootNodes) { if (!AlreadyProcessed(rootMethod.GetMethodDefinition())) { var publicMethodNode = GetMethodNode(methodGraph.GraphType, methodGraph.ApplicationName, rootMethod); var callTreeNode = new ExploreTreeNode() { FullSignature = signature }; CrossAssemblyWalk(methodGraph, publicMethodNode, rootMethod, 1, callTreeNode); CacheNode(rootMethod.GetMethodDefinition(), publicMethodNode); methodGraph.AddMethodNode(publicMethodNode); } } } } }
private void IndexAbstractMethods(ModuleDefinition module) { var abstractMethods = DecompilerService.GetAbstractMethods(module); foreach (var method in abstractMethods) { AbstractMethodsIndexedByName.Add(SignatureKeyService.GetFullMethodSignature(method), method); AbstractMethodsIndexedByTypeName.Add(method.DeclaringType.FullName, method); AbstractMethodsList.Add(method); } }
private void ContinueDownFullTree(MethodGraph methodGraph, MethodNode parentMethodNode, MethodObject parentMethod, int depth, ExploreTreeNode callTreeNode) { foreach (var calledMethod in parentMethod.MethodsCalled) { CheckForResourceCall(methodGraph, calledMethod, parentMethod, parentMethodNode); var calledMethodSignature = SignatureKeyService.GetFullMethodSignature(calledMethod.MethodCalled); var treeNode = new ExploreTreeNode() { FullSignature = calledMethodSignature }; callTreeNode.AddChild(treeNode); bool isGenericAndIndexed = false; string genericSignature = null; var methodIsIndexed = _methodIndexer.HasMethod(calledMethodSignature); if (!methodIsIndexed) { genericSignature = SignatureKeyService.GetGenericMethodSignature(calledMethod.MethodCalled); if (!string.IsNullOrEmpty(genericSignature)) { isGenericAndIndexed = _methodIndexer.HasMethod(genericSignature); } } if (methodIsIndexed || isGenericAndIndexed) { List <MethodObject> matchingMethodNodes = null; if (methodIsIndexed) { matchingMethodNodes = _methodIndexer.GetMethods(calledMethodSignature); } else if (isGenericAndIndexed) { matchingMethodNodes = _methodIndexer.GetMethods(genericSignature); } foreach (var calledMethodNode in matchingMethodNodes) { var cachedRootNode = GetCachedRootNode(calledMethodNode.GetMethodDefinition()); if (cachedRootNode != null) // this is a call to an already analyzed method, we copy over the calls and resource accesses already calculated for this node { cachedRootNode.CopyCallsToNode(parentMethodNode); } else // this is not a call to a previously analyzed method, so we continue down the call tree { PublicInnerAssemblyWalk(methodGraph, parentMethodNode, calledMethodNode, depth + 1, treeNode); } } } } }
private void EmptyIndexes() { _assembliesProcessed = new HashSet <string>(); _modulesToAnalyze = new List <ModuleDefinition>(); _assignmentGraphIndexer.CleanIndexes(); _delegateIndexer.CleanIndexes(); _methodIndexer.CleanIndexes(); _typeService.CleanIndexes(); ResolveService.CleanIndexes(); PropertyService.CleanIndexes(); SignatureKeyService.CleanIndexes(); }
private void DoDirectCallWalk(MethodGraph methodGraph, string companyAssembliesPattern, ModuleDefinition module, string moduleMessagee) { var methods = _methodIndexer.GetAllMethods(); foreach (var method in methods) { var methodNode = GetMethodNode(methodGraph.GraphType, methodGraph.ApplicationName, method); foreach (var calledMethod in method.MethodsCalled) { CheckForResourceCall(methodGraph, calledMethod, method, methodNode); var calledMethodSignature = SignatureKeyService.GetFullMethodSignature(calledMethod.MethodCalled); bool isGenericAndIndexed = false; string genericSignature = null; var methodIsIndexed = _methodIndexer.HasMethod(calledMethodSignature); if (!methodIsIndexed) { genericSignature = SignatureKeyService.GetGenericMethodSignature(calledMethod.MethodCalled); if (!string.IsNullOrEmpty(genericSignature)) { isGenericAndIndexed = _methodIndexer.HasMethod(genericSignature); } } if (methodIsIndexed || isGenericAndIndexed) { List <MethodObject> matchingMethodNodes = null; if (methodIsIndexed) { matchingMethodNodes = _methodIndexer.GetMethods(calledMethodSignature); } else if (isGenericAndIndexed) { matchingMethodNodes = _methodIndexer.GetMethods(genericSignature); } foreach (var calledMethodNode in matchingMethodNodes) { AddDirectCalls(methodGraph, methodNode, calledMethodNode); } } } methodGraph.AddMethodNode(methodNode); } }
private MethodNode GetMethodNode(GraphType graphType, string appDomain, MethodObject method) { var methodDef = method.GetMethodDefinition(); var methodNode = new MethodNode(graphType, appDomain); methodNode.MethodName = SignatureKeyService.GetMethodSignature(methodDef); methodNode.IsPublic = methodDef.IsPublic && methodDef.DeclaringType.IsPublic; if (method.HasImplementation()) { methodNode.ConcreteType = new TypeInfo(); methodNode.ConcreteType.AssemblyName = method.ConcreteMethod.DeclaringType.Module.Assembly.Name.Name; methodNode.ConcreteType.AssemblyVersion = GetAssemblyVersion(method.ConcreteMethod); methodNode.ConcreteType.TypeName = method.ConcreteMethod.DeclaringType.FullName; } else { } if (method.HasInterface()) { methodNode.InterfaceType = new TypeInfo(); methodNode.InterfaceType.AssemblyName = method.InterfaceMethod.DeclaringType.Module.Assembly.Name.Name; methodNode.InterfaceType.AssemblyVersion = GetAssemblyVersion(method.InterfaceMethod); methodNode.InterfaceType.TypeName = method.InterfaceMethod.DeclaringType.FullName; } if (method.HasAbstract()) { methodNode.AbstractType = new TypeInfo(); methodNode.AbstractType.AssemblyName = method.AbstractMethod.DeclaringType.Module.Assembly.Name.Name; methodNode.AbstractType.AssemblyVersion = GetAssemblyVersion(method.AbstractMethod); methodNode.AbstractType.TypeName = method.AbstractMethod.DeclaringType.FullName; } if (method.OverridesBaseClass()) { methodNode.BaseClassType = new TypeInfo(); methodNode.BaseClassType.AssemblyName = method.VirtualMethod.DeclaringType.Module.Assembly.Name.Name; methodNode.BaseClassType.AssemblyVersion = GetAssemblyVersion(method.VirtualMethod); methodNode.BaseClassType.TypeName = method.VirtualMethod.DeclaringType.FullName; } return(methodNode); }
private bool FindBaseClassMethod(MethodDefinition method, MethodObject methodNode) { // TODO currently only looks at direct base type if (ImplementationMethodsIndexedByTypeName.HasIndex(method.DeclaringType.BaseType.FullName)) { var methodsOfBaseParent = ImplementationMethodsIndexedByTypeName.Get(method.DeclaringType.BaseType.FullName); var matchingMethod = methodsOfBaseParent.FirstOrDefault(x => SignatureKeyService.GetMethodSignature(x).Equals(SignatureKeyService.GetMethodSignature(method))); if (matchingMethod != null) { methodNode.VirtualMethod = matchingMethod; methodNode.ImplementsType = ImplementsType.Overrides; return(true); } } return(false); }
private bool ResolveGenericsInterface(MethodDefinition method, MethodObject methodNode, TypeReference interfaceParent, TypeDefinition interfaceDefinition) { var genericTypes = TypeService.GetGenericTypeParameters(interfaceParent.FullName); if (interfaceDefinition.GenericParameters.Count != genericTypes.Count) { return(false); } var genericTypesDict = new Dictionary <string, string>(); for (int i = 0; i < interfaceDefinition.GenericParameters.Count; i++) { var genericPlaceholder = interfaceDefinition.GenericParameters[i].FullName; var typedGeneric = genericTypes[i]; genericTypesDict.Add(genericPlaceholder, typedGeneric); } foreach (var m in interfaceDefinition.Methods) { foreach (var k in genericTypesDict.Keys) { var typedMethodName = m.FullName.Replace(k, genericTypesDict[k]); var interfaceMethodNamePart = typedMethodName.Substring(typedMethodName.IndexOf("::") + 2); var concreteMethodNamePart = method.FullName.Substring(method.FullName.IndexOf("::") + 2); if (interfaceMethodNamePart.Equals(concreteMethodNamePart)) { // we replace a generic T type with a generic instance type and index that var sig = SignatureKeyService.ConvertFullNameToSignature(typedMethodName); MethodObjectsIndexedByFullName.Add(sig, methodNode); methodNode.InterfaceMethod = m; methodNode.ImplementsType = ImplementsType.Interface; return(true); } } } return(false); }
public void BuildMethodObjects(string appDomain) { foreach (var method in ImplementationMethodsList) { if (ShouldSkip(method)) { continue; } var node = new MethodObject(); node.AppDomain = appDomain; node.ConcreteMethod = method; var implementsInterface = FindInterfaceMethod(method, node); if (implementsInterface) { MethodObjectsIndexedByFullName.Add(SignatureKeyService.GetFullMethodSignature(node.InterfaceMethod), node); var genericSignature = SignatureKeyService.GetGenericMethodSignature(node.InterfaceMethod); if (!string.IsNullOrEmpty(genericSignature)) { MethodObjectsIndexedByFullName.Add(genericSignature, node); } } var implementsAbstractClass = FindAbstractMethod(method, node); if (implementsAbstractClass) { MethodObjectsIndexedByFullName.Add(SignatureKeyService.GetFullMethodSignature(node.AbstractMethod), node); } var inheritsFromBaseClass = FindBaseClassMethod(method, node); if (inheritsFromBaseClass) { MethodObjectsIndexedByFullName.Add(SignatureKeyService.GetFullMethodSignature(node.VirtualMethod), node); } FindFieldsAndMethods(method, node, true); MethodObjectsIndexedByFullName.Add(SignatureKeyService.GetFullMethodSignature(method), node); MethodObjectsList.Add(node); } foreach (var method in InterfaceMethodsList) { if (!MethodObjectsIndexedByFullName.HasIndex(SignatureKeyService.GetFullMethodSignature(method))) { var node = new MethodObject(); node.AppDomain = appDomain; node.InterfaceMethod = method; node.ImplementsType = ImplementsType.None; MethodObjectsIndexedByFullName.Add(SignatureKeyService.GetFullMethodSignature(method), node); } } foreach (var method in AbstractMethodsList) { if (!MethodObjectsIndexedByFullName.HasIndex(SignatureKeyService.GetFullMethodSignature(method))) { var node = new MethodObject(); node.AppDomain = appDomain; node.AbstractMethod = method; node.ImplementsType = ImplementsType.None; MethodObjectsIndexedByFullName.Add(SignatureKeyService.GetFullMethodSignature(method), node); } } }