예제 #1
0
 public KnownMember(KnownTypes parent, TypeDef declType, string name, TypeDef type)
 {
     Parent        = parent;
     Property      = declType.FindProperty(name);
     DeclaringType = declType;
     Name          = name;
     Type          = type;
 }
예제 #2
0
        private static IMemberDef FindArgumentMemberDef(UTF8String name, CallingConventionSig propertySig, TypeDef attrType)
        {
            while (attrType != null)
            {
                var property = attrType.FindProperty(name, propertySig);

                if (property != null)
                {
                    return(property);
                }
                attrType = attrType.BaseType.ResolveTypeDef();
            }

            return(null);
        }
예제 #3
0
        Tuple <IDnlibDef, AttributeInfoRecord, TypeDef> AnalyzeAttributeReference(TypeDef declType, AttributeInfoRecord rec)
        {
            IDnlibDef     retDef  = null;
            ITypeDefOrRef retType = null;

            while (declType != null)
            {
                var property = declType.FindProperty(rec.Name);
                if (property != null)
                {
                    retDef  = property;
                    retType = property.PropertySig.RetType.ToBasicTypeDefOrRef();
                    if (context.Modules.Contains((ModuleDefMD)declType.Module))
                    {
                        service.AddReference(property, new BAMLAttributeReference(property, rec));
                    }

                    break;
                }

                var evt = declType.FindEvent(rec.Name);
                if (evt != null)
                {
                    retDef  = evt;
                    retType = evt.EventType;
                    if (context.Modules.Contains((ModuleDefMD)declType.Module))
                    {
                        service.AddReference(evt, new BAMLAttributeReference(evt, rec));
                    }

                    break;
                }

                if (declType.BaseType == null)
                {
                    break;
                }

                declType = declType.BaseType.ResolveTypeDefThrow();
            }
            return(Tuple.Create(retDef, rec, retType == null ? null : retType.ResolveTypeDefThrow()));
        }
예제 #4
0
        void AnalyzeMethod(ConfuserContext context, INameService service, MethodDef method)
        {
            var dpRegInstrs        = new List <Tuple <bool, Instruction> >();
            var routedEvtRegInstrs = new List <Instruction>();

            for (int i = 0; i < method.Body.Instructions.Count; i++)
            {
                Instruction instr = method.Body.Instructions[i];
                if ((instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt))
                {
                    var regMethod = (IMethod)instr.Operand;

                    if (regMethod.DeclaringType.FullName == "System.Windows.DependencyProperty" &&
                        regMethod.Name.String.StartsWith("Register"))
                    {
                        dpRegInstrs.Add(Tuple.Create(regMethod.Name.String.StartsWith("RegisterAttached"), instr));
                    }
                    else if (regMethod.DeclaringType.FullName == "System.Windows.EventManager" &&
                             regMethod.Name.String == "RegisterRoutedEvent")
                    {
                        routedEvtRegInstrs.Add(instr);
                    }
                }
                else if (instr.OpCode.Code == Code.Newobj)
                {
                    var methodRef = (IMethod)instr.Operand;

                    if (methodRef.DeclaringType.FullName == "System.Windows.Data.PropertyGroupDescription" &&
                        methodRef.Name == ".ctor" && i - 1 >= 0 && method.Body.Instructions[i - 1].OpCode.Code == Code.Ldstr)
                    {
                        foreach (var property in analyzer.LookupProperty((string)method.Body.Instructions[i - 1].Operand))
                        {
                            service.SetCanRename(property, false);
                        }
                    }
                }
                else if (instr.OpCode == OpCodes.Ldstr)
                {
                    var operand = ((string)instr.Operand).ToUpperInvariant();
                    if (operand.EndsWith(".BAML") || operand.EndsWith(".XAML"))
                    {
                        var match = UriPattern.Match(operand);
                        if (match.Success)
                        {
                            operand = match.Groups[1].Value;
                        }
                        else if (operand.Contains("/"))
                        {
                            context.Logger.WarnFormat("[WPF] Fail to extract XAML name from '{0}'.", instr.Operand);
                        }

                        var reference = new BAMLStringReference(instr);
                        operand = operand.TrimStart('/');
                        var baml = operand.Substring(0, operand.Length - 5) + ".BAML";
                        var xaml = operand.Substring(0, operand.Length - 5) + ".XAML";
                        bamlRefs.AddListEntry(baml, reference);
                        bamlRefs.AddListEntry(xaml, reference);
                    }
                }
            }

            if (dpRegInstrs.Count == 0)
            {
                return;
            }

            var         traceSrv = context.Registry.GetService <ITraceService>();
            MethodTrace trace    = traceSrv.Trace(method);

            bool erred = false;

            foreach (var instrInfo in dpRegInstrs)
            {
                int[] args = trace.TraceArguments(instrInfo.Item2);
                if (args == null)
                {
                    if (!erred)
                    {
                        context.Logger.WarnFormat("Failed to extract dependency property name in '{0}'.", method.FullName);
                    }
                    erred = true;
                    continue;
                }
                Instruction ldstr = method.Body.Instructions[args[0]];
                if (ldstr.OpCode.Code != Code.Ldstr)
                {
                    if (!erred)
                    {
                        context.Logger.WarnFormat("Failed to extract dependency property name in '{0}'.", method.FullName);
                    }
                    erred = true;
                    continue;
                }

                var     name     = (string)ldstr.Operand;
                TypeDef declType = method.DeclaringType;
                bool    found    = false;
                if (instrInfo.Item1)                 // Attached DP
                {
                    MethodDef accessor;
                    if ((accessor = declType.FindMethod("Get" + name)) != null && accessor.IsStatic)
                    {
                        service.SetCanRename(accessor, false);
                        found = true;
                    }
                    if ((accessor = declType.FindMethod("Set" + name)) != null && accessor.IsStatic)
                    {
                        service.SetCanRename(accessor, false);
                        found = true;
                    }
                }

                // Normal DP
                // Find CLR property for attached DP as well, because it seems attached DP can be use as normal DP as well.
                PropertyDef property = null;
                if ((property = declType.FindProperty(name)) != null)
                {
                    service.SetCanRename(property, false);

                    found = true;
                    if (property.GetMethod != null)
                    {
                        service.SetCanRename(property.GetMethod, false);
                    }

                    if (property.SetMethod != null)
                    {
                        service.SetCanRename(property.SetMethod, false);
                    }

                    if (property.HasOtherMethods)
                    {
                        foreach (MethodDef accessor in property.OtherMethods)
                        {
                            service.SetCanRename(accessor, false);
                        }
                    }
                }
                if (!found)
                {
                    if (instrInfo.Item1)
                    {
                        context.Logger.WarnFormat("Failed to find the accessors of attached dependency property '{0}' in type '{1}'.",
                                                  name, declType.FullName);
                    }
                    else
                    {
                        context.Logger.WarnFormat("Failed to find the CLR property of normal dependency property '{0}' in type '{1}'.",
                                                  name, declType.FullName);
                    }
                }
            }

            erred = false;
            foreach (Instruction instr in routedEvtRegInstrs)
            {
                int[] args = trace.TraceArguments(instr);
                if (args == null)
                {
                    if (!erred)
                    {
                        context.Logger.WarnFormat("Failed to extract routed event name in '{0}'.", method.FullName);
                    }
                    erred = true;
                    continue;
                }
                Instruction ldstr = method.Body.Instructions[args[0]];
                if (ldstr.OpCode.Code != Code.Ldstr)
                {
                    if (!erred)
                    {
                        context.Logger.WarnFormat("Failed to extract routed event name in '{0}'.", method.FullName);
                    }
                    erred = true;
                    continue;
                }

                var     name     = (string)ldstr.Operand;
                TypeDef declType = method.DeclaringType;

                EventDef eventDef = null;
                if ((eventDef = declType.FindEvent(name)) == null)
                {
                    context.Logger.WarnFormat("Failed to find the CLR event of routed event '{0}' in type '{1}'.",
                                              name, declType.FullName);
                    continue;
                }
                service.SetCanRename(eventDef, false);

                if (eventDef.AddMethod != null)
                {
                    service.SetCanRename(eventDef.AddMethod, false);
                }

                if (eventDef.RemoveMethod != null)
                {
                    service.SetCanRename(eventDef.RemoveMethod, false);
                }

                if (eventDef.InvokeMethod != null)
                {
                    service.SetCanRename(eventDef.InvokeMethod, false);
                }

                if (eventDef.HasOtherMethods)
                {
                    foreach (MethodDef accessor in eventDef.OtherMethods)
                    {
                        service.SetCanRename(accessor, false);
                    }
                }
            }
        }
예제 #5
0
        private Tuple<IDnlibDef, TypeDef> AnalyzeAttributeReference(TypeDef declType, AttributeInfoRecord rec)
        {
            IDnlibDef retDef = null;
            TypeDef retType = null;
            while (declType != null) {
                PropertyDef property = declType.FindProperty(rec.Name);
                if (property != null) {
                    retDef = property;
                    retType = property.PropertySig.RetType.ToBasicTypeDefOrRef().ResolveTypeDefThrow();
                    if (context.Modules.Contains((ModuleDefMD)declType.Module))
                        service.AddReference(property, new BAMLAttributeReference(property, rec));
                    break;
                }

                EventDef evt = declType.FindEvent(rec.Name);
                if (evt != null) {
                    retDef = evt;
                    retType = evt.EventType.ResolveTypeDefThrow();
                    if (context.Modules.Contains((ModuleDefMD)declType.Module))
                        service.AddReference(evt, new BAMLAttributeReference(evt, rec));
                    break;
                }

                if (declType.BaseType == null)
                    break;
                declType = declType.BaseType.ResolveTypeDefThrow();
            }
            return Tuple.Create(retDef, retType);
        }
예제 #6
0
		public KnownMember(KnownTypes parent, TypeDef declType, string name, TypeDef type) {
			Parent = parent;
			Property = declType.FindProperty(name);
			DeclaringType = declType;
			Name = name;
			Type = type;
		}
예제 #7
0
        private void ProcessConverter(PropertyWithConverterRecord rec, TypeDef type)
        {
            TypeDef converter = ResolveType(rec.ConverterTypeId);

            if (converter.FullName == "System.ComponentModel.EnumConverter")
            {
                if (type != null && context.Modules.Contains((ModuleDefMD)type.Module))
                {
                    FieldDef enumField = type.FindField(rec.Value);
                    if (enumField != null)
                    {
                        service.AddReference(enumField, new BAMLEnumReference(enumField, rec));
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Input.CommandConverter")
            {
                string cmd   = rec.Value.Trim();
                int    index = cmd.IndexOf('.');
                if (index != -1)
                {
                    string  typeName = cmd.Substring(0, index);
                    string  prefix;
                    TypeSig sig = ResolveType(typeName, out prefix);
                    if (sig != null)
                    {
                        string cmdName = cmd.Substring(index + 1);

                        TypeDef typeDef = sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow();
                        if (context.Modules.Contains((ModuleDefMD)typeDef.Module))
                        {
                            PropertyDef property = typeDef.FindProperty(cmdName);
                            if (property != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, property, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(property, RenameMode.Letters);
                                service.AddReference(property, reference);
                            }
                            FieldDef field = typeDef.FindField(cmdName);
                            if (field != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, field, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(field, RenameMode.Letters);
                                service.AddReference(field, reference);
                            }
                            if (property == null && field == null)
                            {
                                context.Logger.WarnFormat("Could not resolve command '{0}' in '{1}'.", cmd, bamlName);
                            }
                        }
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Markup.DependencyPropertyConverter")
            {
                // Umm... Again nothing to do, DP already won't be renamed.
            }
            else if (converter.FullName == "System.Windows.PropertyPathConverter")
            {
                AnalyzePropertyPath(rec.Value);
            }
            else if (converter.FullName == "System.Windows.Markup.RoutedEventConverter")
            {
                ;
            }
            else if (converter.FullName == "System.Windows.Markup.TypeTypeConverter")
            {
                string  prefix;
                TypeSig sig = ResolveType(rec.Value.Trim(), out prefix);
                if (sig != null && context.Modules.Contains((ModuleDefMD)sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module))
                {
                    var reference = new BAMLConverterTypeReference(xmlnsCtx, sig, rec);
                    AddTypeSigReference(sig, reference);
                }
            }
        }
예제 #8
0
        void ProcessConverter(PropertyWithConverterRecord rec, TypeDef type)
        {
            TypeDef converter = ResolveType(rec.ConverterTypeId);

            if (converter.FullName == "System.ComponentModel.EnumConverter")
            {
                if (type != null && context.Modules.Contains((ModuleDefMD)type.Module))
                {
                    FieldDef enumField = type.FindField(rec.Value);
                    if (enumField != null)
                    {
                        service.AddReference(enumField, new BAMLEnumReference(enumField, rec));
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Input.CommandConverter")
            {
                string cmd   = rec.Value.Trim();
                int    index = cmd.IndexOf('.');
                if (index != -1)
                {
                    string  typeName = cmd.Substring(0, index);
                    string  prefix;
                    TypeSig sig = ResolveType(typeName, out prefix);
                    if (sig != null)
                    {
                        string cmdName = cmd.Substring(index + 1);

                        TypeDef typeDef = sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow();
                        if (context.Modules.Contains((ModuleDefMD)typeDef.Module))
                        {
                            PropertyDef property = typeDef.FindProperty(cmdName);
                            if (property != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, property, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(property, RenameMode.Letters);
                                service.AddReference(property, reference);
                            }
                            FieldDef field = typeDef.FindField(cmdName);
                            if (field != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, field, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(field, RenameMode.Letters);
                                service.AddReference(field, reference);
                            }
                            if (property == null && field == null)
                            {
                                context.Logger.LogFormat("WARN: Could not resolve command '{0}' in '{1}'.", cmd, CurrentBAMLName);
                            }
                        }
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Markup.DependencyPropertyConverter")
            {
                // Umm... Again nothing to do, DP already won't be renamed.
            }
            else if (converter.FullName == "System.Windows.PropertyPathConverter")
            {
                AnalyzePropertyPath(rec.Value);
            }
            else if (converter.FullName == "System.Windows.Markup.RoutedEventConverter")
            {
                ;
            }
            else if (converter.FullName == "System.Windows.Markup.TypeTypeConverter")
            {
                string  prefix;
                TypeSig sig = ResolveType(rec.Value.Trim(), out prefix);
                if (sig != null && context.Modules.Contains((ModuleDefMD)sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module))
                {
                    var reference = new BAMLConverterTypeReference(xmlnsCtx, sig, rec);
                    AddTypeSigReference(sig, reference);
                }
            }

            var    attrInfo = ResolveAttribute(rec.AttributeId);
            string attrName = null;

            if (attrInfo.Item1 != null)
            {
                attrName = attrInfo.Item1.Name;
            }
            else if (attrInfo.Item2 != null)
            {
                attrName = attrInfo.Item2.Name;
            }

            if (attrName == "DisplayMemberPath")
            {
                AnalyzePropertyPath(rec.Value);
            }
            else if (attrName == "Source")
            {
                string declType = null;
                if (attrInfo.Item1 is IMemberDef)
                {
                    declType = ((IMemberDef)attrInfo.Item1).DeclaringType.FullName;
                }
                else if (attrInfo.Item2 != null)
                {
                    declType = ResolveType(attrInfo.Item2.OwnerTypeId).FullName;
                }
                if (declType == "System.Windows.ResourceDictionary")
                {
                    var src = rec.Value.ToUpperInvariant();
                    if (src.EndsWith(".BAML") || src.EndsWith(".XAML"))
                    {
                        var match = WPFAnalyzer.UriPattern.Match(src);
                        if (match.Success)
                        {
                            src = match.Groups[1].Value;
                        }
                        else if (rec.Value.Contains("/"))
                        {
                            context.Logger.LogFormat("WARN: Fail to extract XAML name from '{0}'.", rec.Value);
                        }

                        if (!src.Contains("//"))
                        {
                            var rel = new Uri(new Uri(packScheme + "application:,,,/" + CurrentBAMLName), src);
                            src = rel.LocalPath;
                        }
                        var reference = new BAMLPropertyReference(rec);
                        src = src.TrimStart('/');
                        var baml     = src.Substring(0, src.Length - 5) + ".BAML";
                        var xaml     = src.Substring(0, src.Length - 5) + ".XAML";
                        var bamlRefs = service.FindRenamer <WPFAnalyzer>().bamlRefs;
                        bamlRefs.AddListEntry(baml, reference);
                        bamlRefs.AddListEntry(xaml, reference);
                        bamlRefs.AddListEntry(Uri.EscapeUriString(baml), reference);
                        bamlRefs.AddListEntry(Uri.EscapeUriString(xaml), reference);
                    }
                }
            }
        }
예제 #9
0
        void ProcessConverter(PropertyWithConverterRecord rec, TypeDef type)
        {
            TypeDef converter = ResolveType(rec.ConverterTypeId);

            if (converter.FullName == "System.ComponentModel.EnumConverter")
            {
                if (type != null && context.Modules.Contains((ModuleDefMD)type.Module))
                {
                    FieldDef enumField = type.FindField(rec.Value);
                    if (enumField != null)
                    {
                        service.AddReference(enumField, new BAMLEnumReference(enumField, rec));
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Input.CommandConverter")
            {
                string cmd   = rec.Value.Trim();
                int    index = cmd.IndexOf('.');
                if (index != -1)
                {
                    string  typeName = cmd.Substring(0, index);
                    string  prefix;
                    TypeSig sig = ResolveType(typeName, out prefix);
                    if (sig != null)
                    {
                        string cmdName = cmd.Substring(index + 1);

                        TypeDef typeDef = sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow();
                        if (context.Modules.Contains((ModuleDefMD)typeDef.Module))
                        {
                            PropertyDef property = typeDef.FindProperty(cmdName);
                            if (property != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, property, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(property, RenameMode.Letters);
                                service.AddReference(property, reference);
                            }
                            FieldDef field = typeDef.FindField(cmdName);
                            if (field != null)
                            {
                                var reference = new BAMLConverterMemberReference(xmlnsCtx, sig, field, rec);
                                AddTypeSigReference(sig, reference);
                                service.ReduceRenameMode(field, RenameMode.Letters);
                                service.AddReference(field, reference);
                            }
                            if (property == null && field == null)
                            {
                                context.Logger.WarnFormat("Could not resolve command '{0}' in '{1}'.", cmd, CurrentBAMLName);
                            }
                        }
                    }
                }
            }
            else if (converter.FullName == "System.Windows.Markup.DependencyPropertyConverter")
            {
                // Umm... Again nothing to do, DP already won't be renamed.
            }
            else if (converter.FullName == "System.Windows.PropertyPathConverter")
            {
                AnalyzePropertyPath(rec.Value);
            }
            else if (converter.FullName == "System.Windows.Markup.RoutedEventConverter")
            {
                ;
            }
            else if (converter.FullName == "System.Windows.Markup.TypeTypeConverter")
            {
                string  prefix;
                TypeSig sig = ResolveType(rec.Value.Trim(), out prefix);
                if (sig != null && context.Modules.Contains((ModuleDefMD)sig.ToBasicTypeDefOrRef().ResolveTypeDefThrow().Module))
                {
                    var reference = new BAMLConverterTypeReference(xmlnsCtx, sig, rec);
                    AddTypeSigReference(sig, reference);
                }
            }

            var    attrInfo = ResolveAttribute(rec.AttributeId);
            string attrName = null;

            if (attrInfo.Item1 != null)
            {
                attrName = attrInfo.Item1.Name;
            }
            else if (attrInfo.Item2 != null)
            {
                attrName = attrInfo.Item2.Name;
            }

            if (attrName == "DisplayMemberPath")
            {
                AnalyzePropertyPath(rec.Value);
            }
            else if (attrName == "Source")
            {
                string declType = null;
                if (attrInfo.Item1 is IMemberDef)
                {
                    declType = ((IMemberDef)attrInfo.Item1).DeclaringType.FullName;
                }
                else if (attrInfo.Item2 != null)
                {
                    declType = ResolveType(attrInfo.Item2.OwnerTypeId).FullName;
                }
                if (declType == "System.Windows.ResourceDictionary")
                {
                    var src = rec.Value.ToUpperInvariant();
                    if (src.EndsWith(".BAML") || src.EndsWith(".XAML"))
                    {
                        var refModule = Module;
                        var match     = WPFAnalyzer.UriPattern.Match(src);
                        if (match.Success)
                        {
                            var resourceAssemblyName = match.Groups[1].Success ? match.Groups[1].Value : string.Empty;
                            // Check if the expression contains a resource name (group 1)
                            // If it does, check if it is this assembly.
                            if (!string.IsNullOrWhiteSpace(resourceAssemblyName) &&
                                !resourceAssemblyName.Equals(Module.Assembly.Name.String, StringComparison.OrdinalIgnoreCase))
                            {
                                // Let's see if we can find this assembly.
                                refModule = context.Modules.FirstOrDefault(m =>
                                                                           resourceAssemblyName.Equals(m.Assembly.Name.String,
                                                                                                       StringComparison.OrdinalIgnoreCase));

                                if (refModule == null)
                                {
                                    // This resource points to an assembly that is not part of the obfuscation.
                                    // Leave it alone!
                                    return;
                                }
                            }
                            src = match.Groups[2].Value;
                        }
                        else if (rec.Value.Contains("/"))
                        {
                            context.Logger.WarnFormat("Fail to extract XAML name from '{0}'.", rec.Value);
                        }

                        if (!src.StartsWith(packScheme, StringComparison.OrdinalIgnoreCase))
                        {
                            var rel = new Uri(new Uri(packScheme + "application:,,,/" + CurrentBAMLName), src);
                            src = rel.LocalPath;
                        }
                        var reference = new BAMLPropertyReference(refModule, rec);
                        src = WebUtility.UrlDecode(src.TrimStart('/'));
                        var baml     = src.Substring(0, src.Length - 5) + ".BAML";
                        var xaml     = src.Substring(0, src.Length - 5) + ".XAML";
                        var bamlRefs = service.FindRenamer <WPFAnalyzer>().bamlRefs;
                        bamlRefs.AddListEntry(baml, reference);
                        bamlRefs.AddListEntry(xaml, reference);
                    }
                }
            }
        }
예제 #10
0
        public void Analyze(ConfuserContext context, INameService service, IDnlibDef def)
        {
            var module = def as ModuleDefMD;

            if (module == null)
            {
                return;
            }

            MDTable table;
            uint    len;

            // MemberRef
            table = module.TablesStream.Get(Table.Method);
            len   = table.Rows;
            IEnumerable <MethodDef> methods = Enumerable.Range(1, (int)len)
                                              .Select(rid => module.ResolveMethod((uint)rid));

            foreach (MethodDef method in methods)
            {
                foreach (MethodOverride methodImpl in method.Overrides)
                {
                    if (methodImpl.MethodBody is MemberRef)
                    {
                        AnalyzeMemberRef(context, service, (MemberRef)methodImpl.MethodBody);
                    }
                    if (methodImpl.MethodDeclaration is MemberRef)
                    {
                        AnalyzeMemberRef(context, service, (MemberRef)methodImpl.MethodDeclaration);
                    }
                }
                if (!method.HasBody)
                {
                    continue;
                }
                foreach (Instruction instr in method.Body.Instructions)
                {
                    if (instr.Operand is MemberRef)
                    {
                        AnalyzeMemberRef(context, service, (MemberRef)instr.Operand);
                    }
                    else if (instr.Operand is MethodSpec)
                    {
                        var spec = (MethodSpec)instr.Operand;
                        if (spec.Method is MemberRef)
                        {
                            AnalyzeMemberRef(context, service, (MemberRef)spec.Method);
                        }
                    }
                }
            }


            // CustomAttribute
            table = module.TablesStream.Get(Table.CustomAttribute);
            len   = table.Rows;
            IEnumerable <CustomAttribute> attrs = Enumerable.Range(1, (int)len)
                                                  .Select(rid => module.ResolveHasCustomAttribute(module.TablesStream.ReadCustomAttributeRow((uint)rid).Parent))
                                                  .Distinct()
                                                  .SelectMany(owner => owner.CustomAttributes);

            foreach (CustomAttribute attr in attrs)
            {
                if (attr.Constructor is MemberRef)
                {
                    AnalyzeMemberRef(context, service, (MemberRef)attr.Constructor);
                }

                foreach (CAArgument arg in attr.ConstructorArguments)
                {
                    AnalyzeCAArgument(context, service, arg);
                }

                foreach (CANamedArgument arg in attr.Fields)
                {
                    AnalyzeCAArgument(context, service, arg.Argument);
                }

                foreach (CANamedArgument arg in attr.Properties)
                {
                    AnalyzeCAArgument(context, service, arg.Argument);
                }

                TypeDef attrType = attr.AttributeType.ResolveTypeDefThrow();
                if (!context.Modules.Contains((ModuleDefMD)attrType.Module))
                {
                    continue;
                }

                foreach (CANamedArgument fieldArg in attr.Fields)
                {
                    FieldDef field = attrType.FindField(fieldArg.Name, new FieldSig(fieldArg.Type));
                    if (field == null)
                    {
                        context.Logger.WarnFormat("Failed to resolve CA field '{0}::{1} : {2}'.", attrType, fieldArg.Name, fieldArg.Type);
                    }
                    else
                    {
                        service.AddReference(field, new CAMemberReference(fieldArg, field));
                    }
                }
                foreach (CANamedArgument propertyArg in attr.Properties)
                {
                    PropertyDef property = attrType.FindProperty(propertyArg.Name, new PropertySig(true, propertyArg.Type));
                    if (property == null)
                    {
                        context.Logger.WarnFormat("Failed to resolve CA property '{0}::{1} : {2}'.", attrType, propertyArg.Name, propertyArg.Type);
                    }
                    else
                    {
                        service.AddReference(property, new CAMemberReference(propertyArg, property));
                    }
                }
            }
        }
예제 #11
0
        private void AnalyzeMethod(ConfuserContext context, INameService service, MethodDef method)
        {
            var dpRegInstrs        = new List <Tuple <bool, Instruction> >();
            var routedEvtRegInstrs = new List <Instruction>();

            foreach (Instruction instr in method.Body.Instructions)
            {
                if ((instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt))
                {
                    var regMethod = (IMethod)instr.Operand;

                    if (regMethod.DeclaringType.FullName == "System.Windows.DependencyProperty" &&
                        regMethod.Name.String.StartsWith("Register"))
                    {
                        dpRegInstrs.Add(Tuple.Create(regMethod.Name.String.StartsWith("RegisterAttached"), instr));
                    }
                    else if (regMethod.DeclaringType.FullName == "System.Windows.EventManager" &&
                             regMethod.Name.String == "RegisterRoutedEvent")
                    {
                        routedEvtRegInstrs.Add(instr);
                    }
                }
            }

            if (dpRegInstrs.Count == 0)
            {
                return;
            }

            var         traceSrv = context.Registry.GetService <ITraceService>();
            MethodTrace trace    = traceSrv.Trace(method);

            bool erred = false;

            foreach (var instrInfo in dpRegInstrs)
            {
                int[] args = trace.TraceArguments(instrInfo.Item2);
                if (args == null)
                {
                    if (!erred)
                    {
                        context.Logger.WarnFormat("Failed to extract dependency property name in '{0}'.", method.FullName);
                    }
                    erred = true;
                    continue;
                }
                Instruction ldstr = method.Body.Instructions[args[0]];
                if (ldstr.OpCode.Code != Code.Ldstr)
                {
                    if (!erred)
                    {
                        context.Logger.WarnFormat("Failed to extract dependency property name in '{0}'.", method.FullName);
                    }
                    erred = true;
                    continue;
                }

                var     name     = (string)ldstr.Operand;
                TypeDef declType = method.DeclaringType;
                bool    found    = false;
                if (instrInfo.Item1)                 // Attached DP
                {
                    MethodDef accessor;
                    if ((accessor = declType.FindMethod("Get" + name)) != null && accessor.IsStatic)
                    {
                        service.SetCanRename(accessor, false);
                        found = true;
                    }
                    if ((accessor = declType.FindMethod("Set" + name)) != null && accessor.IsStatic)
                    {
                        service.SetCanRename(accessor, false);
                        found = true;
                    }
                }

                // Normal DP
                // Find CLR property for attached DP as well, because it seems attached DP can be use as normal DP as well.
                PropertyDef property = null;
                if ((property = declType.FindProperty(name)) != null)
                {
                    found = true;
                    if (property.GetMethod != null)
                    {
                        service.SetCanRename(property.GetMethod, false);
                    }

                    if (property.SetMethod != null)
                    {
                        service.SetCanRename(property.SetMethod, false);
                    }

                    if (property.HasOtherMethods)
                    {
                        foreach (MethodDef accessor in property.OtherMethods)
                        {
                            service.SetCanRename(accessor, false);
                        }
                    }
                }
                if (!found)
                {
                    if (instrInfo.Item1)
                    {
                        context.Logger.WarnFormat("Failed to find the accessors of attached dependency property '{0}' in type '{1}'.",
                                                  name, declType.FullName);
                    }
                    else
                    {
                        context.Logger.WarnFormat("Failed to find the CLR property of normal dependency property '{0}' in type '{1}'.",
                                                  name, declType.FullName);
                    }
                }
            }

            erred = false;
            foreach (Instruction instr in routedEvtRegInstrs)
            {
                int[] args = trace.TraceArguments(instr);
                if (args == null)
                {
                    if (!erred)
                    {
                        context.Logger.WarnFormat("Failed to extract routed event name in '{0}'.", method.FullName);
                    }
                    erred = true;
                    continue;
                }
                Instruction ldstr = method.Body.Instructions[args[0]];
                if (ldstr.OpCode.Code != Code.Ldstr)
                {
                    if (!erred)
                    {
                        context.Logger.WarnFormat("Failed to extract routed event name in '{0}'.", method.FullName);
                    }
                    erred = true;
                    continue;
                }

                var     name     = (string)ldstr.Operand;
                TypeDef declType = method.DeclaringType;

                EventDef eventDef = null;
                if ((eventDef = declType.FindEvent(name)) == null)
                {
                    context.Logger.WarnFormat("Failed to find the CLR event of routed event '{0}' in type '{1}'.",
                                              name, declType.FullName);
                    continue;
                }
                if (eventDef.AddMethod != null)
                {
                    service.SetCanRename(eventDef.AddMethod, false);
                }

                if (eventDef.RemoveMethod != null)
                {
                    service.SetCanRename(eventDef.RemoveMethod, false);
                }

                if (eventDef.InvokeMethod != null)
                {
                    service.SetCanRename(eventDef.InvokeMethod, false);
                }

                if (eventDef.HasOtherMethods)
                {
                    foreach (MethodDef accessor in eventDef.OtherMethods)
                    {
                        service.SetCanRename(accessor, false);
                    }
                }
            }
        }
        // Token: 0x06000044 RID: 68 RVA: 0x00004ED4 File Offset: 0x000030D4
        private void AnalyzeMethod(ConfuserContext context, INameService service, MethodDef method)
        {
            List <Tuple <bool, Instruction> > dpRegInstrs = new List <Tuple <bool, Instruction> >();
            List <Instruction> routedEvtRegInstrs         = new List <Instruction>();

            foreach (Instruction instr in method.Body.Instructions)
            {
                if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt)
                {
                    IMethod regMethod = (IMethod)instr.Operand;
                    if (regMethod.DeclaringType.FullName == "System.Windows.DependencyProperty" && regMethod.Name.String.StartsWith("Register"))
                    {
                        dpRegInstrs.Add(Tuple.Create <bool, Instruction>(regMethod.Name.String.StartsWith("RegisterAttached"), instr));
                    }
                    else if (regMethod.DeclaringType.FullName == "System.Windows.EventManager" && regMethod.Name.String == "RegisterRoutedEvent")
                    {
                        routedEvtRegInstrs.Add(instr);
                    }
                }
                else if (instr.OpCode == OpCodes.Ldstr)
                {
                    string operand = ((string)instr.Operand).ToUpperInvariant();
                    if (operand.EndsWith(".BAML") || operand.EndsWith(".XAML"))
                    {
                        Match match = WPFAnalyzer.UriPattern.Match(operand);
                        if (match.Success)
                        {
                            operand = match.Groups[1].Value;
                        }
                        BAMLStringReference reference = new BAMLStringReference(instr);
                        operand = operand.TrimStart(new char[]
                        {
                            '/'
                        });
                        string baml = operand.Substring(0, operand.Length - 5) + ".BAML";
                        string xaml = operand.Substring(0, operand.Length - 5) + ".XAML";
                        this.bamlRefs.AddListEntry(baml, reference);
                        this.bamlRefs.AddListEntry(xaml, reference);
                    }
                }
            }
            if (dpRegInstrs.Count == 0)
            {
                return;
            }
            ITraceService traceSrv = context.Registry.GetService <ITraceService>();
            MethodTrace   trace    = traceSrv.Trace(method);
            bool          erred    = false;

            foreach (Tuple <bool, Instruction> instrInfo in dpRegInstrs)
            {
                int[] args = trace.TraceArguments(instrInfo.Item2);
                if (args == null)
                {
                    if (!erred)
                    {
                        context.Logger.WarnFormat("Failed to extract dependency property name in '{0}'.", new object[]
                        {
                            method.FullName
                        });
                    }
                    erred = true;
                }
                else
                {
                    Instruction ldstr = method.Body.Instructions[args[0]];
                    if (ldstr.OpCode.Code != Code.Ldstr)
                    {
                        if (!erred)
                        {
                            context.Logger.WarnFormat("Failed to extract dependency property name in '{0}'.", new object[]
                            {
                                method.FullName
                            });
                        }
                        erred = true;
                    }
                    else
                    {
                        string  name     = (string)ldstr.Operand;
                        TypeDef declType = method.DeclaringType;
                        bool    found    = false;
                        if (instrInfo.Item1)
                        {
                            MethodDef accessor;
                            if ((accessor = declType.FindMethod("Get" + name)) != null && accessor.IsStatic)
                            {
                                service.SetCanRename(accessor, false);
                                found = true;
                            }
                            if ((accessor = declType.FindMethod("Set" + name)) != null && accessor.IsStatic)
                            {
                                service.SetCanRename(accessor, false);
                                found = true;
                            }
                        }
                        PropertyDef property;
                        if ((property = declType.FindProperty(name)) != null)
                        {
                            service.SetCanRename(property, false);
                            found = true;
                            if (property.GetMethod != null)
                            {
                                service.SetCanRename(property.GetMethod, false);
                            }
                            if (property.SetMethod != null)
                            {
                                service.SetCanRename(property.SetMethod, false);
                            }
                            if (property.HasOtherMethods)
                            {
                                foreach (MethodDef accessor2 in property.OtherMethods)
                                {
                                    service.SetCanRename(accessor2, false);
                                }
                            }
                        }
                        if (!found)
                        {
                            if (instrInfo.Item1)
                            {
                                context.Logger.WarnFormat("Failed to find the accessors of attached dependency property '{0}' in type '{1}'.", new object[]
                                {
                                    name,
                                    declType.FullName
                                });
                            }
                            else
                            {
                                context.Logger.WarnFormat("Failed to find the CLR property of normal dependency property '{0}' in type '{1}'.", new object[]
                                {
                                    name,
                                    declType.FullName
                                });
                            }
                        }
                    }
                }
            }
            erred = false;
            foreach (Instruction instr2 in routedEvtRegInstrs)
            {
                int[] args2 = trace.TraceArguments(instr2);
                if (args2 == null)
                {
                    if (!erred)
                    {
                        context.Logger.WarnFormat("Failed to extract routed event name in '{0}'.", new object[]
                        {
                            method.FullName
                        });
                    }
                    erred = true;
                }
                else
                {
                    Instruction ldstr2 = method.Body.Instructions[args2[0]];
                    if (ldstr2.OpCode.Code != Code.Ldstr)
                    {
                        if (!erred)
                        {
                            context.Logger.WarnFormat("Failed to extract routed event name in '{0}'.", new object[]
                            {
                                method.FullName
                            });
                        }
                        erred = true;
                    }
                    else
                    {
                        string   name2     = (string)ldstr2.Operand;
                        TypeDef  declType2 = method.DeclaringType;
                        EventDef eventDef;
                        if ((eventDef = declType2.FindEvent(name2)) == null)
                        {
                            context.Logger.WarnFormat("Failed to find the CLR event of routed event '{0}' in type '{1}'.", new object[]
                            {
                                name2,
                                declType2.FullName
                            });
                        }
                        else
                        {
                            service.SetCanRename(eventDef, false);
                            if (eventDef.AddMethod != null)
                            {
                                service.SetCanRename(eventDef.AddMethod, false);
                            }
                            if (eventDef.RemoveMethod != null)
                            {
                                service.SetCanRename(eventDef.RemoveMethod, false);
                            }
                            if (eventDef.InvokeMethod != null)
                            {
                                service.SetCanRename(eventDef.InvokeMethod, false);
                            }
                            if (eventDef.HasOtherMethods)
                            {
                                foreach (MethodDef accessor3 in eventDef.OtherMethods)
                                {
                                    service.SetCanRename(accessor3, false);
                                }
                            }
                        }
                    }
                }
            }
        }