/* Copyright (C) 2011 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 Mono.Cecil; using Mono.Cecil.Cil; using de4dot.code.renamer.asmmodules; using de4dot.blocks; namespace de4dot.code.renamer { class TypeInfo : MemberInfo { public string oldNamespace; public string newNamespace; public VariableNameState variableNameState = new VariableNameState(); public TypeDef type; MemberInfos memberInfos; public INameChecker NameChecker { get { return type.Module.ObfuscatedFile.NameChecker; } } public TypeInfo(TypeDef typeDef, MemberInfos memberInfos) : base(typeDef) { this.type = typeDef; this.memberInfos = memberInfos; oldNamespace = typeDef.TypeDefinition.Namespace; } bool isWinFormsClass() { return memberInfos.isWinFormsClass(type); } public PropertyInfo prop(PropertyDef prop) { return memberInfos.prop(prop); } public EventInfo evt(EventDef evt) { return memberInfos.evt(evt); } public FieldInfo field(FieldDef field) { return memberInfos.field(field); } public MethodInfo method(MethodDef method) { return memberInfos.method(method); } public GenericParamInfo gparam(GenericParamDef gparam) { return memberInfos.gparam(gparam); } public ParamInfo param(ParamDef param) { return memberInfos.param(param); } TypeInfo getBase() { if (type.baseType == null) return null; TypeInfo baseInfo; memberInfos.tryGetType(type.baseType.typeDef, out baseInfo); return baseInfo; } public void prepareRenameTypes(TypeRenamerState state) { var checker = NameChecker; if (newNamespace == null && oldNamespace != "") { if (!checker.isValidNamespaceName(oldNamespace)) { newNamespace = state.createNamespace(oldNamespace); } } string origClassName = null; if (isWinFormsClass()) origClassName = findWindowsFormsClassName(type); if (oldFullName != "" && !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.TypeDefinition, 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(TypeDef 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(evt(eventDef).oldName); foreach (var propDef in type.AllProperties) variableNameState.addPropertyName(prop(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.TypeDefinition.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.FieldDefinition.IsStatic || !fieldDef.FieldDefinition.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.FieldDefinition)); } } List getInstanceFields() { var fields = new List(); foreach (var fieldDef in type.AllFields) { if (!fieldDef.FieldDefinition.IsStatic) fields.Add(fieldDef); } return fields; } bool hasFlagsAttribute() { foreach (var attr in type.TypeDefinition.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(PropertyDef propDef) { if (propDef.isVirtual()) throw new ApplicationException("Can't rename virtual props here"); var propInfo = prop(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.PropertyDefinition); } 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(EventDef eventDef) { if (eventDef.isVirtual()) throw new ApplicationException("Can't rename virtual events here"); var eventInfo = evt(eventDef); if (eventInfo.renamed) return; string eventName = eventInfo.oldName; if (!NameChecker.isValidEventName(eventName)) eventName = eventInfo.suggestedName; if (!NameChecker.isValidEventName(eventName)) eventName = variableNameState.getNewEventName(eventDef.EventDefinition); variableNameState.addEventName(eventName); eventInfo.rename(eventName); renameSpecialMethod(eventDef.AddMethod, "add_" + eventName); renameSpecialMethod(eventDef.RemoveMethod, "remove_" + eventName); renameSpecialMethod(eventDef.RaiseMethod, "raise_" + eventName); } void renameSpecialMethod(MethodDef 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(MethodDef methodDef) { if (methodDef.ParamDefs.Count > 0) { if (isEventHandler(methodDef)) { param(methodDef.ParamDefs[0]).newName = "sender"; param(methodDef.ParamDefs[1]).newName = "e"; } else { var newVariableNameState = variableNameState.clone(); var checker = NameChecker; foreach (var paramDef in methodDef.ParamDefs) { var info = param(paramDef); if (info.gotNewName()) continue; if (!checker.isValidMethodArgName(info.oldName)) info.newName = newVariableNameState.getNewParamName(info.oldName, paramDef.ParameterDefinition); } } } if ((methodDef.Property != null && methodDef == methodDef.Property.SetMethod) || (methodDef.Event != null && (methodDef == methodDef.Event.AddMethod || methodDef == methodDef.Event.RemoveMethod))) { if (methodDef.ParamDefs.Count > 0) { var paramDef = methodDef.ParamDefs[methodDef.ParamDefs.Count - 1]; param(paramDef).newName = "value"; } } } bool canRenameMethod(MethodDef methodDef) { var methodInfo = method(methodDef); if (methodDef.isStatic()) { if (methodInfo.oldName == ".cctor") return false; } else if (methodDef.isVirtual()) { if (DotNetUtils.derivesFromDelegate(type.TypeDefinition)) { switch (methodInfo.oldName) { case "BeginInvoke": case "EndInvoke": case "Invoke": return false; } } } else { if (methodInfo.oldName == ".ctor") return false; } return true; } public void renameMethod(MethodDef methodDef, string methodName) { if (!canRenameMethod(methodDef)) return; var methodInfo = method(methodDef); variableNameState.addMethodName(methodName); methodInfo.rename(methodName); } void renameMethod(MethodDef 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. if (!NameChecker.isValidMethodName(info.oldName) || methodDef.MethodDefinition.PInvokeInfo != null) { INameCreator nameCreator = null; string newName = info.suggestedName; if (methodDef.MethodDefinition.PInvokeInfo != null) newName = getPinvokeName(methodDef); else if (methodDef.isStatic()) nameCreator = variableNameState.staticMethodNameCreator; else nameCreator = variableNameState.instanceMethodNameCreator; if (newName != null) nameCreator = new NameCreator2(newName); renameMethod(methodDef, variableNameState.getNewMethodName(info.oldName, nameCreator)); } } string getPinvokeName(MethodDef methodDef) { var entryPoint = methodDef.MethodDefinition.PInvokeInfo.EntryPoint; if (Regex.IsMatch(entryPoint, @"^#\d+$")) entryPoint = DotNetUtils.getDllName(methodDef.MethodDefinition.PInvokeInfo.Module.Name) + "_" + entryPoint.Substring(1); return entryPoint; } static bool isEventHandler(MethodDef methodDef) { if (methodDef.MethodDefinition.Parameters.Count != 2) return false; if (methodDef.MethodDefinition.MethodReturnType.ReturnType.FullName != "System.Void") return false; if (methodDef.MethodDefinition.Parameters[0].ParameterType.FullName != "System.Object") return false; if (!methodDef.MethodDefinition.Parameters[1].ParameterType.FullName.Contains("EventArgs")) return false; return true; } void prepareRenameGenericParams(IEnumerable genericParams, INameChecker checker, IEnumerable otherGenericParams = null) { var usedNames = new Dictionary(StringComparer.Ordinal); var nameCreator = new GenericParamNameCreator(); if (otherGenericParams != null) { foreach (var param in otherGenericParams) { var gpInfo = memberInfos.gparam(param); usedNames[gpInfo.newName] = true; } } foreach (var param in genericParams) { var gpInfo = memberInfos.gparam(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 Dictionary(); foreach (var fieldDef in type.AllFields) ourFields[new FieldReferenceAndDeclaringTypeKey(fieldDef.FieldDefinition)] = fieldDef; var ourMethods = new Dictionary(); foreach (var methodDef in type.AllMethods) ourMethods[new MethodReferenceAndDeclaringTypeKey(methodDef.MethodDefinition)] = methodDef; foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDefinition.Body == null) continue; if (methodDef.MethodDefinition.IsStatic || methodDef.MethodDefinition.IsVirtual) continue; var instructions = methodDef.MethodDefinition.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 MethodReference)) 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]; FieldReference fieldRef = null; if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) { var calledMethod = instr.Operand as MethodReference; if (calledMethod == null) continue; MethodDef calledMethodDef; if (!ourMethods.TryGetValue(new MethodReferenceAndDeclaringTypeKey(calledMethod), out calledMethodDef)) continue; fieldRef = getFieldReference(calledMethodDef.MethodDefinition); if (fieldRef == null) continue; var propDef = calledMethodDef.Property; if (propDef == null) continue; memberInfos.prop(propDef).suggestedName = fieldName; fieldName = "_" + fieldName; } else if (instr.OpCode.Code == Code.Ldfld) { fieldRef = instr.Operand as FieldReference; } if (fieldRef == null) continue; FieldDef fieldDef; if (!ourFields.TryGetValue(new FieldReferenceAndDeclaringTypeKey(fieldRef), out fieldDef)) continue; var fieldInfo = memberInfos.field(fieldDef); if (fieldInfo.renamed) continue; fieldInfo.suggestedName = variableNameState.getNewFieldName(fieldInfo.oldName, new NameCreator2(fieldName)); } } } static FieldReference getFieldReference(MethodDefinition 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 || DotNetUtils.getArgIndex(method, ldarg0) != 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 || ret.OpCode.Code != Code.Ret) return null; return ldfld.Operand as FieldReference; } public void initializeEventHandlerNames() { var ourFields = new Dictionary(); foreach (var fieldDef in type.AllFields) ourFields[new FieldReferenceAndDeclaringTypeKey(fieldDef.FieldDefinition)] = fieldDef; var ourMethods = new Dictionary(); foreach (var methodDef in type.AllMethods) ourMethods[new MethodReferenceAndDeclaringTypeKey(methodDef.MethodDefinition)] = 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(Dictionary ourFields, Dictionary ourMethods) { var checker = NameChecker; foreach (var propDef in type.AllProperties) { var setter = propDef.PropertyDefinition.SetMethod; if (setter == null) continue; var setterDef = type.find(setter); if (setterDef == null) continue; string eventName; var handler = getVbHandler(setterDef.MethodDefinition, out eventName); if (handler == null) continue; MethodDef handlerDef; if (!ourMethods.TryGetValue(new MethodReferenceAndDeclaringTypeKey(handler), out handlerDef)) continue; if (!checker.isValidEventName(eventName)) continue; memberInfos.method(handlerDef).suggestedName = string.Format("{0}_{1}", memberInfos.prop(propDef).newName, eventName); } } static MethodReference getVbHandler(MethodDefinition method, out string eventName) { eventName = null; if (method.Body == null) return null; if (method.MethodReturnType.ReturnType.FullName != "System.Void") return null; if (method.Parameters.Count != 1) return null; if (method.Body.Variables.Count != 1) return null; if (!isEventHandlerType(method.Body.Variables[0].VariableType)) 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 MethodReference)) 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 MethodReference; if (handlerMethod == null) return null; if (!MemberReferenceHelper.compareTypes(method.DeclaringType, handlerMethod.DeclaringType)) return null; index = newobjIndex; FieldReference addField, removeField; MethodReference 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 (!MemberReferenceHelper.compareFieldReference(addField, removeField)) return null; if (!MemberReferenceHelper.compareTypes(method.DeclaringType, addField.DeclaringType)) return null; if (!MemberReferenceHelper.compareTypes(addMethod.DeclaringType, removeMethod.DeclaringType)) return null; if (!Utils.StartsWith(addMethod.Name, "add_", StringComparison.Ordinal)) return null; if (!Utils.StartsWith(removeMethod.Name, "remove_", StringComparison.Ordinal)) return null; eventName = addMethod.Name.Substring(4); if (eventName != removeMethod.Name.Substring(7)) return null; if (eventName == "") return null; return handlerMethod; } static bool findEventCall(IList instructions, ref int index, out FieldReference field, out MethodReference 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 FieldReference; calledMethod = instructions[callvirt].Operand as MethodReference; 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(Dictionary ourFields, Dictionary ourMethods) { var checker = NameChecker; foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDefinition.Body == null) continue; if (methodDef.MethodDefinition.IsStatic) continue; var instructions = methodDef.MethodDefinition.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 (DotNetUtils.getArgIndex(methodDef.MethodDefinition, instructions[i]) != 0) continue; int index = i + 1; var ldfld = instructions[index++]; if (ldfld.OpCode.Code != Code.Ldfld) continue; var fieldRef = ldfld.Operand as FieldReference; if (fieldRef == null) continue; FieldDef fieldDef; if (!ourFields.TryGetValue(new FieldReferenceAndDeclaringTypeKey(fieldRef), out fieldDef)) continue; if (DotNetUtils.getArgIndex(methodDef.MethodDefinition, instructions[index++]) != 0) continue; MethodReference methodRef; var instr = instructions[index + 1]; if (instr.OpCode.Code == Code.Ldvirtftn) { if (!isThisOrDup(methodDef.MethodDefinition, instructions[index++])) continue; var ldvirtftn = instructions[index++]; methodRef = ldvirtftn.Operand as MethodReference; } else { var ldftn = instructions[index++]; if (ldftn.OpCode.Code != Code.Ldftn) continue; methodRef = ldftn.Operand as MethodReference; } if (methodRef == null) continue; MethodDef handlerMethod; if (!ourMethods.TryGetValue(new MethodReferenceAndDeclaringTypeKey(methodRef), out handlerMethod)) continue; var newobj = instructions[index++]; if (newobj.OpCode.Code != Code.Newobj) continue; if (!isEventHandlerCtor(newobj.Operand as MethodReference)) continue; var call = instructions[index++]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) continue; var addHandler = call.Operand as MethodReference; if (addHandler == null) continue; if (!Utils.StartsWith(addHandler.Name, "add_", StringComparison.Ordinal)) continue; var eventName = addHandler.Name.Substring(4); if (!checker.isValidEventName(eventName)) continue; memberInfos.method(handlerMethod).suggestedName = string.Format("{0}_{1}", memberInfos.field(fieldDef).newName, eventName); } } } void initTypeEventHandlers(Dictionary ourFields, Dictionary ourMethods) { var checker = NameChecker; foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDefinition.Body == null) continue; if (methodDef.MethodDefinition.IsStatic) continue; var method = methodDef.MethodDefinition; 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 (DotNetUtils.getArgIndex(method, instructions[i]) != 0) continue; int index = i + 1; if (!isThisOrDup(method, instructions[index++])) continue; MethodReference handler; if (instructions[index].OpCode.Code == Code.Ldftn) { handler = instructions[index++].Operand as MethodReference; } else { if (!isThisOrDup(method, instructions[index++])) continue; var instr = instructions[index++]; if (instr.OpCode.Code != Code.Ldvirtftn) continue; handler = instr.Operand as MethodReference; } if (handler == null) continue; MethodDef handlerDef; if (!ourMethods.TryGetValue(new MethodReferenceAndDeclaringTypeKey(handler), out handlerDef)) continue; var newobj = instructions[index++]; if (newobj.OpCode.Code != Code.Newobj) continue; if (!isEventHandlerCtor(newobj.Operand as MethodReference)) continue; var call = instructions[index++]; if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt) continue; var addMethod = call.Operand as MethodReference; if (addMethod == null) continue; if (!Utils.StartsWith(addMethod.Name, "add_", StringComparison.Ordinal)) continue; var eventName = addMethod.Name.Substring(4); if (!checker.isValidEventName(eventName)) continue; memberInfos.method(handlerDef).suggestedName = string.Format("{0}_{1}", newName, eventName); } } } static bool isThisOrDup(MethodReference method, Instruction instr) { return DotNetUtils.getArgIndex(method, instr) == 0 || instr.OpCode.Code == Code.Dup; } static bool isEventHandlerCtor(MethodReference 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(TypeReference type) { return type.FullName.EndsWith("EventHandler", StringComparison.Ordinal); } static MethodReference getOverrideMethod(MethodDefinition meth) { if (meth == null || !meth.HasOverrides) return null; return meth.Overrides[0]; } string findWindowsFormsClassName(TypeDef type) { foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDefinition.Body == null) continue; if (methodDef.MethodDefinition.IsStatic || methodDef.MethodDefinition.IsVirtual) continue; var instructions = methodDef.MethodDefinition.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 MethodReference)) continue; var ldstr = instructions[i - 1]; if (ldstr.OpCode.Code != Code.Ldstr) continue; var className = ldstr.Operand as string; if (className == null) continue; if (DotNetUtils.getArgIndex(methodDef.MethodDefinition, instructions[i - 2]) != 0) continue; findInitializeComponentMethod(type, methodDef); return className; } } return null; } void findInitializeComponentMethod(TypeDef type, MethodDef possibleInitMethod) { foreach (var methodDef in type.AllMethods) { if (methodDef.MethodDefinition.Name != ".ctor") continue; if (methodDef.MethodDefinition.Body == null) continue; foreach (var instr in methodDef.MethodDefinition.Body.Instructions) { if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt) continue; if (!MemberReferenceHelper.compareMethodReferenceAndDeclaringType(possibleInitMethod.MethodDefinition, instr.Operand as MethodReference)) continue; memberInfos.method(possibleInitMethod).suggestedName = "InitializeComponent"; return; } } } static bool isWindowsFormsSetNameMethod(MethodReference method) { if (method == null) return false; if (method.Name != "set_Name") return false; if (method.MethodReturnType.ReturnType.FullName != "System.Void") return false; if (method.Parameters.Count != 1) return false; if (method.Parameters[0].ParameterType.FullName != "System.String") return false; return true; } } }