/* Copyright (C) 2011-2015 de4dot@gmail.com This file is part of de4dot. de4dot is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. de4dot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with de4dot. If not, see . */ using System; using System.Collections.Generic; using System.Text.RegularExpressions; using dnlib.DotNet; using dnlib.DotNet.Emit; using de4dot.code.renamer.asmmodules; using de4dot.blocks; namespace de4dot.code.renamer { public class TypeInfo : MemberInfo { public string oldNamespace; public string newNamespace; public VariableNameState variableNameState = VariableNameState.Create(); public MTypeDef type; MemberInfos memberInfos; public INameChecker NameChecker { get { return type.Module.ObfuscatedFile.NameChecker; } } public TypeInfo(MTypeDef typeDef, MemberInfos memberInfos) : base(typeDef) { this.type = typeDef; this.memberInfos = memberInfos; oldNamespace = typeDef.TypeDef.Namespace.String; } bool IsWinFormsClass() { return memberInfos.IsWinFormsClass(type); } public PropertyInfo Property(MPropertyDef prop) { return memberInfos.Property(prop); } public EventInfo Event(MEventDef evt) { return memberInfos.Event(evt); } public FieldInfo Field(MFieldDef field) { return memberInfos.Field(field); } public MethodInfo Method(MMethodDef method) { return memberInfos.Method(method); } public GenericParamInfo GenericParam(MGenericParamDef gparam) { return memberInfos.GenericParam(gparam); } public ParamInfo Param(MParamDef param) { return memberInfos.Param(param); } TypeInfo GetBase() { if (type.baseType == null) return null; TypeInfo baseInfo; memberInfos.TryGetType(type.baseType.typeDef, out baseInfo); return baseInfo; } bool IsModuleType() { return type.TypeDef.IsGlobalModuleType; } public void PrepareRenameTypes(TypeRenamerState state) { var checker = NameChecker; if (newNamespace == null && oldNamespace != "") { if (type.TypeDef.IsNested) newNamespace = ""; else if (!checker.IsValidNamespaceName(oldNamespace)) newNamespace = state.CreateNamespace(this.type.TypeDef, oldNamespace); } string origClassName = null; if (IsWinFormsClass()) origClassName = FindWindowsFormsClassName(type); if (IsModuleType()) { if (oldNamespace != "") newNamespace = ""; Rename(""); } else if (!checker.IsValidTypeName(oldName)) { if (origClassName != null && checker.IsValidTypeName(origClassName)) Rename(state.GetTypeName(oldName, origClassName)); else { ITypeNameCreator nameCreator = type.IsGlobalType() ? state.globalTypeNameCreator : state.internalTypeNameCreator; string newBaseType = null; TypeInfo baseInfo = GetBase(); if (baseInfo != null && baseInfo.renamed) newBaseType = baseInfo.newName; Rename(nameCreator.Create(type.TypeDef, newBaseType)); } } PrepareRenameGenericParams(type.GenericParams, checker); } public void MergeState() { foreach (var ifaceInfo in type.interfaces) MergeState(ifaceInfo.typeDef); if (type.baseType != null) MergeState(type.baseType.typeDef); } void MergeState(MTypeDef other) { if (other == null) return; TypeInfo otherInfo; if (!memberInfos.TryGetType(other, out otherInfo)) return; variableNameState.Merge(otherInfo.variableNameState); } public void PrepareRenameMembers() { MergeState(); foreach (var fieldDef in type.AllFields) variableNameState.AddFieldName(Field(fieldDef).oldName); foreach (var eventDef in type.AllEvents) variableNameState.AddEventName(Event(eventDef).oldName); foreach (var propDef in type.AllProperties) variableNameState.AddPropertyName(Property(propDef).oldName); foreach (var methodDef in type.AllMethods) variableNameState.AddMethodName(Method(methodDef).oldName); if (IsWinFormsClass()) InitializeWindowsFormsFieldsAndProps(); PrepareRenameFields(); } public void PrepareRenamePropsAndEvents() { MergeState(); PrepareRenameProperties(); PrepareRenameEvents(); } void PrepareRenameFields() { var checker = NameChecker; if (type.TypeDef.IsEnum) { var instanceFields = GetInstanceFields(); if (instanceFields.Count == 1) Field(instanceFields[0]).Rename("value__"); int i = 0; string nameFormat = HasFlagsAttribute() ? "flag_{0}" : "const_{0}"; foreach (var fieldDef in type.AllFieldsSorted) { var fieldInfo = Field(fieldDef); if (fieldInfo.renamed) continue; if (!fieldDef.FieldDef.IsStatic || !fieldDef.FieldDef.IsLiteral) continue; if (!checker.IsValidFieldName(fieldInfo.oldName)) fieldInfo.Rename(string.Format(nameFormat, i)); i++; } } foreach (var fieldDef in type.AllFieldsSorted) { var fieldInfo = Field(fieldDef); if (fieldInfo.renamed) continue; if (!checker.IsValidFieldName(fieldInfo.oldName)) fieldInfo.Rename(fieldInfo.suggestedName ?? variableNameState.GetNewFieldName(fieldDef.FieldDef)); } } List GetInstanceFields() { var fields = new List(); foreach (var fieldDef in type.AllFields) { if (!fieldDef.FieldDef.IsStatic) fields.Add(fieldDef); } return fields; } bool HasFlagsAttribute() { foreach (var attr in type.TypeDef.CustomAttributes) { if (attr.AttributeType.FullName == "System.FlagsAttribute") return true; } return false; } void PrepareRenameProperties() { foreach (var propDef in type.AllPropertiesSorted) { if (propDef.IsVirtual()) continue; PrepareRenameProperty(propDef); } } void PrepareRenameProperty(MPropertyDef propDef) { if (propDef.IsVirtual()) throw new ApplicationException("Can't rename virtual props here"); var propInfo = Property(propDef); if (propInfo.renamed) return; string propName = propInfo.oldName; if (!NameChecker.IsValidPropertyName(propName)) propName = propInfo.suggestedName; if (!NameChecker.IsValidPropertyName(propName)) { if (propDef.IsItemProperty()) propName = "Item"; else propName = variableNameState.GetNewPropertyName(propDef.PropertyDef); } variableNameState.AddPropertyName(propName); propInfo.Rename(propName); RenameSpecialMethod(propDef.GetMethod, "get_" + propName); RenameSpecialMethod(propDef.SetMethod, "set_" + propName); } void PrepareRenameEvents() { foreach (var eventDef in type.AllEventsSorted) { if (eventDef.IsVirtual()) continue; PrepareRenameEvent(eventDef); } } void PrepareRenameEvent(MEventDef eventDef) { if (eventDef.IsVirtual()) throw new ApplicationException("Can't rename virtual events here"); var eventInfo = Event(eventDef); if (eventInfo.renamed) return; string eventName = eventInfo.oldName; if (!NameChecker.IsValidEventName(eventName)) eventName = eventInfo.suggestedName; if (!NameChecker.IsValidEventName(eventName)) eventName = variableNameState.GetNewEventName(eventDef.EventDef); variableNameState.AddEventName(eventName); eventInfo.Rename(eventName); RenameSpecialMethod(eventDef.AddMethod, "add_" + eventName); RenameSpecialMethod(eventDef.RemoveMethod, "remove_" + eventName); RenameSpecialMethod(eventDef.RaiseMethod, "raise_" + eventName); } void RenameSpecialMethod(MMethodDef methodDef, string newName) { if (methodDef == null) return; if (methodDef.IsVirtual()) return; RenameMethod(methodDef, newName); } public void PrepareRenameMethods() { MergeState(); foreach (var methodDef in type.AllMethodsSorted) { if (methodDef.IsVirtual()) continue; RenameMethod(methodDef); } } public void PrepareRenameMethods2() { var checker = NameChecker; foreach (var methodDef in type.AllMethodsSorted) { PrepareRenameMethodArgs(methodDef); PrepareRenameGenericParams(methodDef.GenericParams, checker, methodDef.Owner == null ? null : methodDef.Owner.GenericParams); } } void PrepareRenameMethodArgs(MMethodDef methodDef) { VariableNameState newVariableNameState = null; ParamInfo info; if (methodDef.VisibleParameterCount > 0) { if (IsEventHandler(methodDef)) { info = Param(methodDef.ParamDefs[methodDef.VisibleParameterBaseIndex]); if (!info.GotNewName()) info.newName = "sender"; info = Param(methodDef.ParamDefs[methodDef.VisibleParameterBaseIndex + 1]); if (!info.GotNewName()) info.newName = "e"; } else { newVariableNameState = variableNameState.CloneParamsOnly(); var checker = NameChecker; foreach (var paramDef in methodDef.ParamDefs) { if (paramDef.IsHiddenThisParameter) continue; info = Param(paramDef); if (info.GotNewName()) continue; if (!checker.IsValidMethodArgName(info.oldName)) info.newName = newVariableNameState.GetNewParamName(info.oldName, paramDef.ParameterDef); } } } info = Param(methodDef.ReturnParamDef); if (!info.GotNewName()) { if (!NameChecker.IsValidMethodReturnArgName(info.oldName)) { if (newVariableNameState == null) newVariableNameState = variableNameState.CloneParamsOnly(); info.newName = newVariableNameState.GetNewParamName(info.oldName, methodDef.ReturnParamDef.ParameterDef); } } if ((methodDef.Property != null && methodDef == methodDef.Property.SetMethod) || (methodDef.Event != null && (methodDef == methodDef.Event.AddMethod || methodDef == methodDef.Event.RemoveMethod))) { if (methodDef.VisibleParameterCount > 0) { var paramDef = methodDef.ParamDefs[methodDef.ParamDefs.Count - 1]; Param(paramDef).newName = "value"; } } } bool CanRenameMethod(MMethodDef methodDef) { var methodInfo = Method(methodDef); if (methodDef.IsStatic()) { if (methodInfo.oldName == ".cctor") return false; } else if (methodDef.IsVirtual()) { if (DotNetUtils.DerivesFromDelegate(type.TypeDef)) { switch (methodInfo.oldName) { case "BeginInvoke": case "EndInvoke": case "Invoke": return false; } } } else { if (methodInfo.oldName == ".ctor") return false; } return true; } public void RenameMethod(MMethodDef methodDef, string methodName) { if (!CanRenameMethod(methodDef)) return; var methodInfo = Method(methodDef); variableNameState.AddMethodName(methodName); methodInfo.Rename(methodName); } void RenameMethod(MMethodDef methodDef) { if (methodDef.IsVirtual()) throw new ApplicationException("Can't rename virtual methods here"); if (!CanRenameMethod(methodDef)) return; var info = Method(methodDef); if (info.renamed) return; info.renamed = true; var checker = NameChecker; // PInvoke methods' EntryPoint is always valid. It has to, so always rename. bool isValidName = NameChecker.IsValidMethodName(info.oldName); bool isExternPInvoke = methodDef.MethodDef.ImplMap != null && methodDef.MethodDef.RVA == 0; if (!isValidName || isExternPInvoke) { INameCreator nameCreator = null; string newName = info.suggestedName; string newName2; if (methodDef.MethodDef.ImplMap != null && !string.IsNullOrEmpty(newName2 = GetPinvokeName(methodDef))) newName = newName2; else if (methodDef.IsStatic()) nameCreator = variableNameState.staticMethodNameCreator; else nameCreator = variableNameState.instanceMethodNameCreator; if (!string.IsNullOrEmpty(newName)) nameCreator = new NameCreator2(newName); RenameMethod(methodDef, variableNameState.GetNewMethodName(info.oldName, nameCreator)); } } string GetPinvokeName(MMethodDef methodDef) { var entryPoint = methodDef.MethodDef.ImplMap.Name.String; if (Regex.IsMatch(entryPoint, @"^#\d+$")) entryPoint = DotNetUtils.GetDllName(methodDef.MethodDef.ImplMap.Module.Name.String) + "_" + entryPoint.Substring(1); return entryPoint; } static bool IsEventHandler(MMethodDef methodDef) { var sig = methodDef.MethodDef.MethodSig; if (sig == null || sig.Params.Count != 2) return false; if (sig.RetType.ElementType != ElementType.Void) return false; if (sig.Params[0].ElementType != ElementType.Object) return false; if (!sig.Params[1].FullName.Contains("EventArgs")) return false; return true; } void PrepareRenameGenericParams(IEnumerable genericParams, INameChecker checker) { PrepareRenameGenericParams(genericParams, checker, null); } void PrepareRenameGenericParams(IEnumerable genericParams, INameChecker checker, IEnumerable otherGenericParams) { var usedNames = new Dictionary(StringComparer.Ordinal); var nameCreator = new GenericParamNameCreator(); if (otherGenericParams != null) { foreach (var param in otherGenericParams) { var gpInfo = memberInfos.GenericParam(param); usedNames[gpInfo.newName] = true; } } foreach (var param in genericParams) { var gpInfo = memberInfos.GenericParam(param); if (!checker.IsValidGenericParamName(gpInfo.oldName) || usedNames.ContainsKey(gpInfo.oldName)) { string newName; do { newName = nameCreator.Create(); } while (usedNames.ContainsKey(newName)); usedNames[newName] = true; gpInfo.Rename(newName); } } } void InitializeWindowsFormsFieldsAndProps() { var checker = NameChecker; var ourFields = new FieldDefAndDeclaringTypeDict(); foreach (var fieldDef in type.AllFields) ourFields.Add(fieldDef.FieldDef, fieldDef); var ourMethods = new MethodDefAndDeclaringTypeDict(); foreach (var methodDef in type.AllMethods) ourMethods.Add(methodDef.MethodDef, methodDef); foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDef.Body == null) continue; if (methodDef.MethodDef.IsStatic || methodDef.MethodDef.IsVirtual) continue; var instructions = methodDef.MethodDef.Body.Instructions; for (int i = 2; i < instructions.Count; i++) { var call = instructions[i]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) continue; if (!IsWindowsFormsSetNameMethod(call.Operand as IMethod)) continue; var ldstr = instructions[i - 1]; if (ldstr.OpCode.Code != Code.Ldstr) continue; var fieldName = ldstr.Operand as string; if (fieldName == null || !checker.IsValidFieldName(fieldName)) continue; var instr = instructions[i - 2]; IField fieldRef = null; if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) { var calledMethod = instr.Operand as IMethod; if (calledMethod == null) continue; var calledMethodDef = ourMethods.Find(calledMethod); if (calledMethodDef == null) continue; fieldRef = GetFieldRef(calledMethodDef.MethodDef); var propDef = calledMethodDef.Property; if (propDef == null) continue; memberInfos.Property(propDef).suggestedName = fieldName; fieldName = "_" + fieldName; } else if (instr.OpCode.Code == Code.Ldfld) { fieldRef = instr.Operand as IField; } if (fieldRef == null) continue; var fieldDef = ourFields.Find(fieldRef); if (fieldDef == null) continue; var fieldInfo = memberInfos.Field(fieldDef); if (fieldInfo.renamed) continue; fieldInfo.suggestedName = variableNameState.GetNewFieldName(fieldInfo.oldName, new NameCreator2(fieldName)); } } } static IField GetFieldRef(MethodDef method) { if (method == null || method.Body == null) return null; var instructions = method.Body.Instructions; int index = 0; var ldarg0 = DotNetUtils.GetInstruction(instructions, ref index); if (ldarg0 == null || ldarg0.GetParameterIndex() != 0) return null; var ldfld = DotNetUtils.GetInstruction(instructions, ref index); if (ldfld == null || ldfld.OpCode.Code != Code.Ldfld) return null; var ret = DotNetUtils.GetInstruction(instructions, ref index); if (ret == null) return null; if (ret.IsStloc()) { var local = ret.GetLocal(method.Body.Variables); ret = DotNetUtils.GetInstruction(instructions, ref index); if (ret == null || !ret.IsLdloc()) return null; if (ret.GetLocal(method.Body.Variables) != local) return null; ret = DotNetUtils.GetInstruction(instructions, ref index); } if (ret == null || ret.OpCode.Code != Code.Ret) return null; return ldfld.Operand as IField; } public void InitializeEventHandlerNames() { var ourFields = new FieldDefAndDeclaringTypeDict(); foreach (var fieldDef in type.AllFields) ourFields.Add(fieldDef.FieldDef, fieldDef); var ourMethods = new MethodDefAndDeclaringTypeDict(); foreach (var methodDef in type.AllMethods) ourMethods.Add(methodDef.MethodDef, methodDef); InitVbEventHandlers(ourFields, ourMethods); InitFieldEventHandlers(ourFields, ourMethods); InitTypeEventHandlers(ourFields, ourMethods); } // VB initializes the handlers in the property setter, where it first removes the handler // from the previous control, and then adds the handler to the new control. void InitVbEventHandlers(FieldDefAndDeclaringTypeDict ourFields, MethodDefAndDeclaringTypeDict ourMethods) { var checker = NameChecker; foreach (var propDef in type.AllProperties) { var setterDef = propDef.SetMethod; if (setterDef == null) continue; string eventName; var handler = GetVbHandler(setterDef.MethodDef, out eventName); if (handler == null) continue; var handlerDef = ourMethods.Find(handler); if (handlerDef == null) continue; if (!checker.IsValidEventName(eventName)) continue; memberInfos.Method(handlerDef).suggestedName = string.Format("{0}_{1}", memberInfos.Property(propDef).newName, eventName); } } static IMethod GetVbHandler(MethodDef method, out string eventName) { eventName = null; if (method.Body == null) return null; var sig = method.MethodSig; if (sig == null) return null; if (sig.RetType.ElementType != ElementType.Void) return null; if (sig.Params.Count != 1) return null; if (method.Body.Variables.Count != 1) return null; if (!IsEventHandlerType(method.Body.Variables[0].Type)) return null; var instructions = method.Body.Instructions; int index = 0; int newobjIndex = FindInstruction(instructions, index, Code.Newobj); if (newobjIndex == -1 || FindInstruction(instructions, newobjIndex + 1, Code.Newobj) != -1) return null; if (!IsEventHandlerCtor(instructions[newobjIndex].Operand as IMethod)) return null; if (newobjIndex < 1) return null; var ldvirtftn = instructions[newobjIndex - 1]; if (ldvirtftn.OpCode.Code != Code.Ldvirtftn && ldvirtftn.OpCode.Code != Code.Ldftn) return null; var handlerMethod = ldvirtftn.Operand as IMethod; if (handlerMethod == null) return null; if (!new SigComparer().Equals(method.DeclaringType, handlerMethod.DeclaringType)) return null; index = newobjIndex; IField addField, removeField; IMethod addMethod, removeMethod; if (!FindEventCall(instructions, ref index, out removeField, out removeMethod)) return null; if (!FindEventCall(instructions, ref index, out addField, out addMethod)) return null; if (FindInstruction(instructions, index, Code.Callvirt) != -1) return null; if (!new SigComparer().Equals(addField, removeField)) return null; if (!new SigComparer().Equals(method.DeclaringType, addField.DeclaringType)) return null; if (!new SigComparer().Equals(addMethod.DeclaringType, removeMethod.DeclaringType)) return null; if (!Utils.StartsWith(addMethod.Name.String, "add_", StringComparison.Ordinal)) return null; if (!Utils.StartsWith(removeMethod.Name.String, "remove_", StringComparison.Ordinal)) return null; eventName = addMethod.Name.String.Substring(4); if (eventName != removeMethod.Name.String.Substring(7)) return null; if (eventName == "") return null; return handlerMethod; } static bool FindEventCall(IList instructions, ref int index, out IField field, out IMethod calledMethod) { field = null; calledMethod = null; int callvirt = FindInstruction(instructions, index, Code.Callvirt); if (callvirt < 2) return false; index = callvirt + 1; var ldloc = instructions[callvirt - 1]; if (ldloc.OpCode.Code != Code.Ldloc_0) return false; var ldfld = instructions[callvirt - 2]; if (ldfld.OpCode.Code != Code.Ldfld) return false; field = ldfld.Operand as IField; calledMethod = instructions[callvirt].Operand as IMethod; return field != null && calledMethod != null; } static int FindInstruction(IList instructions, int index, Code code) { for (int i = index; i < instructions.Count; i++) { if (instructions[i].OpCode.Code == code) return i; } return -1; } void InitFieldEventHandlers(FieldDefAndDeclaringTypeDict ourFields, MethodDefAndDeclaringTypeDict ourMethods) { var checker = NameChecker; foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDef.Body == null) continue; if (methodDef.MethodDef.IsStatic) continue; var instructions = methodDef.MethodDef.Body.Instructions; for (int i = 0; i < instructions.Count - 6; i++) { // We're looking for this code pattern: // ldarg.0 // ldfld field // ldarg.0 // ldftn method / ldarg.0 + ldvirtftn // newobj event_handler_ctor // callvirt add_SomeEvent if (instructions[i].GetParameterIndex() != 0) continue; int index = i + 1; var ldfld = instructions[index++]; if (ldfld.OpCode.Code != Code.Ldfld) continue; var fieldRef = ldfld.Operand as IField; if (fieldRef == null) continue; var fieldDef = ourFields.Find(fieldRef); if (fieldDef == null) continue; if (instructions[index++].GetParameterIndex() != 0) continue; IMethod methodRef; var instr = instructions[index + 1]; if (instr.OpCode.Code == Code.Ldvirtftn) { if (!IsThisOrDup(instructions[index++])) continue; var ldvirtftn = instructions[index++]; methodRef = ldvirtftn.Operand as IMethod; } else { var ldftn = instructions[index++]; if (ldftn.OpCode.Code != Code.Ldftn) continue; methodRef = ldftn.Operand as IMethod; } if (methodRef == null) continue; var handlerMethod = ourMethods.Find(methodRef); if (handlerMethod == null) continue; var newobj = instructions[index++]; if (newobj.OpCode.Code != Code.Newobj) continue; if (!IsEventHandlerCtor(newobj.Operand as IMethod)) continue; var call = instructions[index++]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) continue; var addHandler = call.Operand as IMethod; if (addHandler == null) continue; if (!Utils.StartsWith(addHandler.Name.String, "add_", StringComparison.Ordinal)) continue; var eventName = addHandler.Name.String.Substring(4); if (!checker.IsValidEventName(eventName)) continue; memberInfos.Method(handlerMethod).suggestedName = string.Format("{0}_{1}", memberInfos.Field(fieldDef).newName, eventName); } } } void InitTypeEventHandlers(FieldDefAndDeclaringTypeDict ourFields, MethodDefAndDeclaringTypeDict ourMethods) { var checker = NameChecker; foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDef.Body == null) continue; if (methodDef.MethodDef.IsStatic) continue; var method = methodDef.MethodDef; var instructions = method.Body.Instructions; for (int i = 0; i < instructions.Count - 5; i++) { // ldarg.0 // ldarg.0 / dup // ldarg.0 / dup // ldvirtftn handler // newobj event handler ctor // call add_Xyz if (instructions[i].GetParameterIndex() != 0) continue; int index = i + 1; if (!IsThisOrDup(instructions[index++])) continue; IMethod handler; if (instructions[index].OpCode.Code == Code.Ldftn) { handler = instructions[index++].Operand as IMethod; } else { if (!IsThisOrDup(instructions[index++])) continue; var instr = instructions[index++]; if (instr.OpCode.Code != Code.Ldvirtftn) continue; handler = instr.Operand as IMethod; } if (handler == null) continue; var handlerDef = ourMethods.Find(handler); if (handlerDef == null) continue; var newobj = instructions[index++]; if (newobj.OpCode.Code != Code.Newobj) continue; if (!IsEventHandlerCtor(newobj.Operand as IMethod)) continue; var call = instructions[index++]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) continue; var addMethod = call.Operand as IMethod; if (addMethod == null) continue; if (!Utils.StartsWith(addMethod.Name.String, "add_", StringComparison.Ordinal)) continue; var eventName = addMethod.Name.String.Substring(4); if (!checker.IsValidEventName(eventName)) continue; memberInfos.Method(handlerDef).suggestedName = string.Format("{0}_{1}", newName, eventName); } } } static bool IsThisOrDup(Instruction instr) { return instr.GetParameterIndex() == 0 || instr.OpCode.Code == Code.Dup; } static bool IsEventHandlerCtor(IMethod method) { if (method == null) return false; if (method.Name != ".ctor") return false; if (!DotNetUtils.IsMethod(method, "System.Void", "(System.Object,System.IntPtr)")) return false; if (!IsEventHandlerType(method.DeclaringType)) return false; return true; } static bool IsEventHandlerType(IType type) { return type.FullName.EndsWith("EventHandler", StringComparison.Ordinal); } string FindWindowsFormsClassName(MTypeDef type) { foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDef.Body == null) continue; if (methodDef.MethodDef.IsStatic || methodDef.MethodDef.IsVirtual) continue; var instructions = methodDef.MethodDef.Body.Instructions; for (int i = 2; i < instructions.Count; i++) { var call = instructions[i]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) continue; if (!IsWindowsFormsSetNameMethod(call.Operand as IMethod)) continue; var ldstr = instructions[i - 1]; if (ldstr.OpCode.Code != Code.Ldstr) continue; var className = ldstr.Operand as string; if (className == null) continue; if (instructions[i - 2].GetParameterIndex() != 0) continue; FindInitializeComponentMethod(type, methodDef); return className; } } return null; } void FindInitializeComponentMethod(MTypeDef type, MMethodDef possibleInitMethod) { foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDef.Name != ".ctor") continue; if (methodDef.MethodDef.Body == null) continue; foreach (var instr in methodDef.MethodDef.Body.Instructions) { if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt) continue; if (!MethodEqualityComparer.CompareDeclaringTypes.Equals(possibleInitMethod.MethodDef, instr.Operand as IMethod)) continue; memberInfos.Method(possibleInitMethod).suggestedName = "InitializeComponent"; return; } } } static bool IsWindowsFormsSetNameMethod(IMethod method) { if (method == null) return false; if (method.Name.String != "set_Name") return false; var sig = method.MethodSig; if (sig == null) return false; if (sig.RetType.ElementType != ElementType.Void) return false; if (sig.Params.Count != 1) return false; if (sig.Params[0].ElementType != ElementType.String) return false; return true; } } }