fix: fix VirtualMethodGroupCalculator.TypeFlatMethods::IsLooseTypeSigMatch treats type and forward type as different type by type.AssemblyQualifiedName which leads same-virtual-slot virtual methods are grouped to different virtual method group. see [issue-32](https://github.com/focus-creative-games/obfuz/issues/32)

copilot/analyze-obfuscation-level
walon 2026-07-19 13:02:21 +08:00
parent 977779c8b7
commit fa2345017a
2 changed files with 32 additions and 19 deletions

View File

@ -49,6 +49,7 @@ namespace Obfuz.ObfusPasses.SymbolObfus
private readonly Dictionary<ModuleDef, List<CustomAttributeInfo>> _customAttributeArgumentsWithTypeByMods = new Dictionary<ModuleDef, List<CustomAttributeInfo>>(); private readonly Dictionary<ModuleDef, List<CustomAttributeInfo>> _customAttributeArgumentsWithTypeByMods = new Dictionary<ModuleDef, List<CustomAttributeInfo>>();
private readonly RenameRecordMap _renameRecordMap; private readonly RenameRecordMap _renameRecordMap;
private readonly VirtualMethodGroupCalculator _virtualMethodGroupCalculator; private readonly VirtualMethodGroupCalculator _virtualMethodGroupCalculator;
private readonly List<MethodDef> _virtualMethods = new List<MethodDef>();
private readonly List<Type> _customPolicyTypes; private readonly List<Type> _customPolicyTypes;
class CustomAttributeInfo class CustomAttributeInfo
@ -205,6 +206,7 @@ namespace Obfuz.ObfusPasses.SymbolObfus
public void Process() public void Process()
{ {
_renameRecordMap.Init(_toObfuscatedModules, _nameMaker); _renameRecordMap.Init(_toObfuscatedModules, _nameMaker);
BuildVirtualMethodGroup();
RenameTypes(); RenameTypes();
RenameFields(); RenameFields();
RenameMethods(); RenameMethods();
@ -525,11 +527,28 @@ namespace Obfuz.ObfusPasses.SymbolObfus
} }
} }
private void BuildVirtualMethodGroup()
{
foreach (ModuleDef mod in _obfuscatedAndNotObfuscatedModules)
{
foreach (TypeDef type in mod.GetTypes())
{
_virtualMethodGroupCalculator.CalculateType(type);
foreach (MethodDef method in type.Methods)
{
if (method.IsVirtual)
{
_virtualMethods.Add(method);
}
}
}
}
}
private void RenameMethods() private void RenameMethods()
{ {
//Debug.Log("Rename methods begin"); //Debug.Log("Rename methods begin");
//Debug.Log("Rename not virtual methods begin"); //Debug.Log("Rename not virtual methods begin");
var virtualMethods = new List<MethodDef>();
var refMethodMetasMap = new Dictionary<MethodDef, RefMethodMetas>(); var refMethodMetasMap = new Dictionary<MethodDef, RefMethodMetas>();
BuildRefMethodMetasMap(refMethodMetasMap); BuildRefMethodMetasMap(refMethodMetasMap);
foreach (ModuleDef mod in _toObfuscatedModules) foreach (ModuleDef mod in _toObfuscatedModules)
@ -552,28 +571,13 @@ namespace Obfuz.ObfusPasses.SymbolObfus
} }
} }
foreach (ModuleDef mod in _obfuscatedAndNotObfuscatedModules)
{
foreach (TypeDef type in mod.GetTypes())
{
_virtualMethodGroupCalculator.CalculateType(type);
foreach (MethodDef method in type.Methods)
{
if (method.IsVirtual)
{
virtualMethods.Add(method);
}
}
}
}
//Debug.Log("Rename not virtual methods end"); //Debug.Log("Rename not virtual methods end");
//Debug.Log("Rename virtual methods begin"); //Debug.Log("Rename virtual methods begin");
var visitedVirtualMethods = new HashSet<MethodDef>(); var visitedVirtualMethods = new HashSet<MethodDef>();
var groupNeedRenames = new Dictionary<VirtualMethodGroup, bool>(); var groupNeedRenames = new Dictionary<VirtualMethodGroup, bool>();
foreach (var method in virtualMethods) foreach (var method in _virtualMethods)
{ {
if (!visitedVirtualMethods.Add(method)) if (!visitedVirtualMethods.Add(method))
{ {
@ -753,7 +757,8 @@ namespace Obfuz.ObfusPasses.SymbolObfus
foreach (TypeRef typeRef in refTypeDefMeta.typeRefs) foreach (TypeRef typeRef in refTypeDefMeta.typeRefs)
{ {
Assert.AreEqual(typeRef.FullName, oldFullName); Assert.AreEqual(typeRef.FullName, oldFullName);
Assert.IsTrue(typeRef.DefinitionAssembly.Name == moduleName); // Assert fail when typeRef to a fowarded type
// Assert.IsTrue(typeRef.DefinitionAssembly.Name == moduleName);
if (!string.IsNullOrEmpty(oldNamespace)) if (!string.IsNullOrEmpty(oldNamespace))
{ {
typeRef.Namespace = newNamespace; typeRef.Namespace = newNamespace;

View File

@ -160,7 +160,15 @@ namespace Obfuz.ObfusPasses.SymbolObfus
case ElementType.Class: case ElementType.Class:
case ElementType.ValueType: case ElementType.ValueType:
{ {
return t1.AssemblyQualifiedName == t2.AssemblyQualifiedName; if (t1.AssemblyQualifiedName == t2.AssemblyQualifiedName)
{
return true;
}
if (t1.FullName == t2.FullName)
{
return t1.ToTypeDefOrRef().ResolveTypeDefThrow() == t2.ToTypeDefOrRef().ResolveTypeDefThrow();
}
return false;
} }
case ElementType.Ptr: case ElementType.Ptr:
case ElementType.ByRef: case ElementType.ByRef: