public void PreRename(ConfuserContext context, INameService service, IDnlibDef def) { var method = def as MethodDef; if (method == null || !method.IsVirtual) { return; } VTable vTbl = service.GetVTables()[method.DeclaringType]; if (vTbl == null) // This case occurs at late injected types, like delegates { return; } VTableSignature sig = VTableSignature.FromMethod(method); VTableSlot slot = vTbl.FindSlot(method); Debug.Assert(slot != null); // Can't rename virtual methods which implement an interface method or override a method declared in a base type, // when the interface or base type is declared in an assembly that is not currently being processed if (slot.Overrides.Any(slotOverride => !context.Modules.Any(module => module.Assembly.FullName == slotOverride.MethodDef.DeclaringType.DefinitionAssembly.FullName))) { service.SetCanRename(method, false); } }
public void Analyze(ConfuserContext context, INameService service, IDnlibDef def) { var method = def as MethodDef; if (method == null || !method.IsVirtual) { return; } VTable vTbl = service.GetVTables()[method.DeclaringType]; VTableSignature sig = VTableSignature.FromMethod(method); VTableSlot slot = vTbl.FindSlot(method); Debug.Assert(slot != null); if (!method.IsAbstract) { foreach (VTableSlot baseSlot in slot.Overrides) { // Better on safe side, add references to both methods. service.AddReference(method, new OverrideDirectiveReference(slot, baseSlot)); service.AddReference(baseSlot.MethodDef, new OverrideDirectiveReference(slot, baseSlot)); } } }
private static void SetupOverwriteReferences(INameService service, ICollection <ModuleDefMD> modules, VTableSlot slot, ModuleDef module) { var methodDef = slot.MethodDef; var baseSlot = slot.Overrides; var baseMethodDef = baseSlot.MethodDef; var overrideRef = new OverrideDirectiveReference(slot, baseSlot); service.AddReference(methodDef, overrideRef); service.AddReference(slot.Overrides.MethodDef, overrideRef); var importer = new Importer(module, ImporterOptions.TryToUseTypeDefs); IMethodDefOrRef target; if (baseSlot.MethodDefDeclType is GenericInstSig declType) { MemberRef targetRef = new MemberRefUser(module, baseMethodDef.Name, baseMethodDef.MethodSig, declType.ToTypeDefOrRef()); targetRef = importer.Import(targetRef); service.AddReference(baseMethodDef, new MemberRefReference(targetRef, baseMethodDef)); SetupSignatureReferences(service, modules, module, targetRef.DeclaringType.ToTypeSig() as GenericInstSig); target = targetRef; } else { target = baseMethodDef; if (target.Module != module) { target = (IMethodDefOrRef)importer.Import(baseMethodDef); if (target is MemberRef memberRef) { service.AddReference(baseMethodDef, new MemberRefReference(memberRef, baseMethodDef)); } } } if (target is MemberRef methodRef) { AddImportReference(service, modules, module, baseMethodDef, methodRef); } if (methodDef.Overrides.Any(impl => IsMatchingOverride(impl, target))) { return; } methodDef.Overrides.Add(new MethodOverride(methodDef, target)); }
public OverrideDirectiveReference(VTableSlot thisSlot, VTableSlot baseSlot) { this.thisSlot = thisSlot; this.baseSlot = baseSlot; }
private static void SetupOverwriteReferences(INameService service, ICollection <ModuleDefMD> modules, VTableSlot slot, TypeDef thisType) { var module = thisType.Module; var methodDef = slot.MethodDef; var baseSlot = slot.Overrides; var baseMethodDef = baseSlot.MethodDef; var overrideRef = new OverrideDirectiveReference(slot, baseSlot); service.AddReference(methodDef, overrideRef); service.AddReference(slot.Overrides.MethodDef, overrideRef); var importer = new Importer(module, ImporterOptions.TryToUseTypeDefs); IMethodDefOrRef target; if (baseSlot.MethodDefDeclType is GenericInstSig declType) { MemberRef targetRef = new MemberRefUser(module, baseMethodDef.Name, baseMethodDef.MethodSig, declType.ToTypeDefOrRef()); targetRef = importer.Import(targetRef); service.AddReference(baseMethodDef, new MemberRefReference(targetRef, baseMethodDef)); SetupSignatureReferences(service, modules, module, targetRef.DeclaringType.ToTypeSig() as GenericInstSig); target = targetRef; } else { target = baseMethodDef; if (target.Module != module) { target = (IMethodDefOrRef)importer.Import(baseMethodDef); if (target is MemberRef memberRef) { service.AddReference(baseMethodDef, new MemberRefReference(memberRef, baseMethodDef)); } } } if (target is MemberRef methodRef) { AddImportReference(service, modules, module, baseMethodDef, methodRef); } if (TypeEqualityComparer.Instance.Equals(methodDef.DeclaringType, thisType)) { if (methodDef.Overrides.Any(impl => IsMatchingOverride(impl, target))) { return; } methodDef.Overrides.Add(new MethodOverride(methodDef, target)); } else if (target is IMemberDef targetDef) { // Reaching this place means that a slot of the base type is overwritten by a specific interface. // In case the this type is implementing the interface responsible for this, we need to declare // this as an override reference. If the base type is implementing the interface (as well), this // declaration is redundant. var overrideRefRequired = true; if (targetDef.DeclaringType.IsInterface) { var baseTypeDef = thisType.BaseType?.ResolveTypeDef(); if (!(baseTypeDef is null)) { var baseTypeVTable = service.GetVTables()[baseTypeDef]; if (baseTypeVTable.InterfaceSlots.TryGetValue(targetDef.DeclaringType.ToTypeSig(), out var ifcSlots)) { overrideRefRequired = !ifcSlots.Contains(slot); } } } if (overrideRefRequired) { CreateOverrideReference(service, methodDef, targetDef); } } }
private static void SetupOverwriteReferences(ConfuserContext context, INameService service, VTableSlot slot, ModuleDef module) { var methodDef = slot.MethodDef; var baseSlot = slot.Overrides; var baseMethodDef = baseSlot.MethodDef; var overrideRef = new OverrideDirectiveReference(slot, baseSlot); service.AddReference(methodDef, overrideRef); service.AddReference(slot.Overrides.MethodDef, overrideRef); var importer = new Importer(module, ImporterOptions.TryToUseTypeDefs); IMethod target; if (baseSlot.MethodDefDeclType is GenericInstSig declType) { var signature = SetupSignatureReferences(context, service, module, declType); MemberRef targetRef = new MemberRefUser(module, baseMethodDef.Name, baseMethodDef.MethodSig, signature.ToTypeDefOrRef()); targetRef = importer.Import(targetRef); service.AddReference(baseMethodDef, new MemberRefReference(targetRef, baseMethodDef)); target = targetRef; } else { target = baseMethodDef; if (target.Module != module) { target = importer.Import(baseMethodDef); if (target is MemberRef memberRef) { service.AddReference(baseMethodDef, new MemberRefReference(memberRef, baseMethodDef)); } } } target.MethodSig = importer.Import(methodDef.MethodSig); if (target is MemberRef methodRef) { AddImportReference(context, service, module, baseMethodDef, methodRef); } if (methodDef.Overrides.Any(impl => new SigComparer().Equals(impl.MethodDeclaration.MethodSig, target.MethodSig) && new SigComparer().Equals(impl.MethodDeclaration.DeclaringType.ResolveTypeDef(), target.DeclaringType.ResolveTypeDef()))) { return; } methodDef.Overrides.Add(new MethodOverride(methodDef, (IMethodDefOrRef)target)); }
// Token: 0x06000032 RID: 50 RVA: 0x000041C0 File Offset: 0x000023C0 public void Analyze(ConfuserContext context, INameService service, ProtectionParameters parameters, IDnlibDef def) { if (def is TypeDef) { TypeDef type = (TypeDef)def; if (type.IsInterface) { return; } VTable vTbl = service.GetVTables()[type]; using (IEnumerator <IList <VTableSlot> > enumerator = vTbl.InterfaceSlots.Values.GetEnumerator()) { while (enumerator.MoveNext()) { IList <VTableSlot> ifaceVTbl = enumerator.Current; foreach (VTableSlot slot in ifaceVTbl) { if (slot.Overrides != null) { bool baseUnderCtrl = context.Modules.Contains(slot.MethodDef.DeclaringType.Module as ModuleDefMD); bool ifaceUnderCtrl = context.Modules.Contains(slot.Overrides.MethodDef.DeclaringType.Module as ModuleDefMD); if ((!baseUnderCtrl && ifaceUnderCtrl) || !service.CanRename(slot.MethodDef)) { service.SetCanRename(slot.Overrides.MethodDef, false); } else if ((baseUnderCtrl && !ifaceUnderCtrl) || !service.CanRename(slot.Overrides.MethodDef)) { service.SetCanRename(slot.MethodDef, false); } } } } return; } } if (def is MethodDef) { MethodDef method = (MethodDef)def; if (!method.IsVirtual) { return; } VTable vTbl = service.GetVTables()[method.DeclaringType]; VTableSignature.FromMethod(method); IEnumerable <VTableSlot> slots = vTbl.FindSlots(method); if (!method.IsAbstract) { using (IEnumerator <VTableSlot> enumerator3 = slots.GetEnumerator()) { while (enumerator3.MoveNext()) { VTableSlot slot2 = enumerator3.Current; if (slot2.Overrides != null) { service.AddReference <MethodDef>(method, new OverrideDirectiveReference(slot2, slot2.Overrides)); service.AddReference <MethodDef>(slot2.Overrides.MethodDef, new OverrideDirectiveReference(slot2, slot2.Overrides)); } } return; } } foreach (VTableSlot slot3 in slots) { if (slot3.Overrides != null) { service.SetCanRename(method, false); service.SetCanRename(slot3.Overrides.MethodDef, false); } } } }