From 83598d6805ca0d17d44ab1203e25e836234fe296 Mon Sep 17 00:00:00 2001 From: walon Date: Thu, 12 Jun 2025 09:49:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E7=B2=BE=E7=A1=AE=E5=9C=B0=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E8=99=9A=E5=87=BD=E6=95=B0override=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=EF=BC=8C=E6=A3=80=E6=9F=A5=E8=BF=94=E5=9B=9E=E5=80=BC=E5=92=8C?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=9A=84=E5=8C=B9=E9=85=8D=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VirtualMethodGroupCalculator.cs | 133 +++++++++++++++++- 1 file changed, 132 insertions(+), 1 deletion(-) diff --git a/Editor/ObfusPasses/SymbolObfus/VirtualMethodGroupCalculator.cs b/Editor/ObfusPasses/SymbolObfus/VirtualMethodGroupCalculator.cs index 033e3b0..05d9858 100644 --- a/Editor/ObfusPasses/SymbolObfus/VirtualMethodGroupCalculator.cs +++ b/Editor/ObfusPasses/SymbolObfus/VirtualMethodGroupCalculator.cs @@ -48,11 +48,142 @@ namespace Obfuz.ObfusPasses.SymbolObfus public HashSet flatMethods = new HashSet(); + private bool IsFinalTypeSig(TypeSig type) + { + switch (type.ElementType) + { + case ElementType.Void: + case ElementType.Boolean: + case ElementType.Char: + case ElementType.I1: + case ElementType.I2: + case ElementType.I4: + case ElementType.I8: + case ElementType.U1: + case ElementType.U2: + case ElementType.U4: + case ElementType.U8: + case ElementType.R4: + case ElementType.R8: + case ElementType.String: + case ElementType.Object: + case ElementType.Class: + case ElementType.ValueType: + return true; + default: return false; + } + } + + private bool IsVarType(TypeSig t) + { + return t.ElementType == ElementType.MVar || t.ElementType == ElementType.Var; + } + + private bool IsClassOrValueType(TypeSig t) + { + return t.ElementType == ElementType.Class || t.ElementType == ElementType.ValueType; + } + + private bool IsLooseTypeSigMatch(TypeSig t1, TypeSig t2) + { + t1 = t1.RemovePinnedAndModifiers(); + t2 = t2.RemovePinnedAndModifiers(); + + if (t1.ElementType != t2.ElementType) + { + return IsVarType(t1) || IsVarType(t2); + } + + switch (t1.ElementType) + { + case ElementType.Void: + case ElementType.Boolean: + case ElementType.Char: + case ElementType.I1: + case ElementType.I2: + case ElementType.I4: + case ElementType.I8: + case ElementType.U1: + case ElementType.U2: + case ElementType.U4: + case ElementType.U8: + case ElementType.R4: + case ElementType.R8: + case ElementType.I: + case ElementType.U: + case ElementType.R: + case ElementType.String: + case ElementType.Object: + case ElementType.TypedByRef: + return true; + case ElementType.Class: + case ElementType.ValueType: + { + return t1.AssemblyQualifiedName == t2.AssemblyQualifiedName; + } + case ElementType.Ptr: + case ElementType.ByRef: + case ElementType.SZArray: + { + break; + } + case ElementType.Array: + { + var a1 = (ArraySig)t1; + var a2 = (ArraySig)t2; + if (a1.Rank != a2.Rank) + { + return false; + } + break; + } + case ElementType.Var: + case ElementType.MVar: + { + //var v1 = (GenericSig)t1; + //var v2 = (GenericSig)t2; + //return v1.Number == v2.Number; + return true; + } + default: return true; + } + if (t1.Next != null && t2.Next != null) + { + return IsLooseTypeSigMatch(t1.Next, t2.Next); + } + return true; + } + + private bool IsLooseMatch(MethodDef method1, MethodDef method2) + { + if (method1.Name != method2.Name) + { + return false; + } + if (method1.GetParamCount() != method2.GetParamCount()) + { + return false; + } + if (!IsLooseTypeSigMatch(method1.ReturnType, method2.ReturnType)) + { + return false; + } + for (int i = 0, n = method1.GetParamCount(); i < n; i++) + { + if (!IsLooseTypeSigMatch(method1.GetParam(i), method2.GetParam(i))) + { + return false; + } + } + + return true; + } + public bool TryFindMatchVirtualMethod(MethodDef method, out MethodDef matchMethodDef) { foreach (var parentOrInterfaceMethod in flatMethods) { - if (parentOrInterfaceMethod.Name == method.Name && parentOrInterfaceMethod.GetParamCount() == method.GetParamCount()) + if (IsLooseMatch(method, parentOrInterfaceMethod)) { matchMethodDef = parentOrInterfaceMethod; return true;