public static void Analyze(INameService service, ICollection <ModuleDefMD> modules, Core.ILogger logger, ModuleDefMD module) { // MemberRef var table = module.TablesStream.Get(Table.Method); var len = table.Rows; IEnumerable <MethodDef> methods = module.GetTypes().SelectMany(type => type.Methods); foreach (MethodDef method in methods) { foreach (MethodOverride methodImpl in method.Overrides) { if (methodImpl.MethodBody is MemberRef) { AnalyzeMemberRef(modules, service, (MemberRef)methodImpl.MethodBody); } if (methodImpl.MethodDeclaration is MemberRef) { AnalyzeMemberRef(modules, service, (MemberRef)methodImpl.MethodDeclaration); } } if (!method.HasBody) { continue; } foreach (Instruction instr in method.Body.Instructions) { if (instr.Operand is MemberRef) { AnalyzeMemberRef(modules, service, (MemberRef)instr.Operand); } else if (instr.Operand is MethodSpec) { var spec = (MethodSpec)instr.Operand; if (spec.Method is MemberRef) { AnalyzeMemberRef(modules, service, (MemberRef)spec.Method); } } } } // CustomAttribute table = module.TablesStream.Get(Table.CustomAttribute); len = table.Rows; var attrs = Enumerable.Range(1, (int)len) .Select(rid => { if (module.TablesStream.TryReadCustomAttributeRow((uint)rid, out var row)) { return(module.ResolveHasCustomAttribute(row.Parent)); } return(null); }) .Where(a => a != null) .Distinct() .SelectMany(owner => owner.CustomAttributes); foreach (CustomAttribute attr in attrs) { if (attr.Constructor is MemberRef) { AnalyzeMemberRef(modules, service, (MemberRef)attr.Constructor); } foreach (CAArgument arg in attr.ConstructorArguments) { AnalyzeCAArgument(modules, service, arg); } foreach (CANamedArgument arg in attr.Fields) { AnalyzeCAArgument(modules, service, arg.Argument); } foreach (CANamedArgument arg in attr.Properties) { AnalyzeCAArgument(modules, service, arg.Argument); } TypeDef attrType = attr.AttributeType.ResolveTypeDefThrow(); if (!modules.Contains((ModuleDefMD)attrType.Module)) { continue; } foreach (var arg in attr.NamedArguments) { var memberDef = FindArgumentMemberDef(arg, attrType); if (memberDef == null) { logger.WarnFormat( arg.IsField ? "Failed to resolve CA field '{0}::{1} : {2}'." : "Failed to resolve CA property '{0}::{1} : {2}'.", attrType, arg.Name, arg.Type); } else { service.AddReference(memberDef, new CAMemberReference(arg, memberDef)); } } } }