支持虚函数重命名
parent
225c613763
commit
23009867ca
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Obfuz
|
||||||
|
{
|
||||||
|
public static class CollectionExtensions
|
||||||
|
{
|
||||||
|
public static void AddRange<T>(this HashSet<T> values, IEnumerable<T> newValues)
|
||||||
|
{
|
||||||
|
foreach (var value in newValues)
|
||||||
|
{
|
||||||
|
values.Add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "Obfuz.Editor",
|
"name": "Obfuz",
|
||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [
|
"references": [
|
||||||
"GUID:167b4b7f91c16bb4183f7298af665076"
|
"GUID:167b4b7f91c16bb4183f7298af665076"
|
||||||
|
|
|
@ -28,9 +28,11 @@ namespace Obfuz.Rename
|
||||||
|
|
||||||
public class NameMaker : INameMaker
|
public class NameMaker : INameMaker
|
||||||
{
|
{
|
||||||
|
private int _nextIndex;
|
||||||
|
|
||||||
private string GetDefaultNewName(string originName)
|
private string GetDefaultNewName(string originName)
|
||||||
{
|
{
|
||||||
return originName + "_xxx__";
|
return $"{originName}>{_nextIndex++}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetNewName(ModuleDefMD mod, string originalName)
|
public string GetNewName(ModuleDefMD mod, string originalName)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
|
using Obfuz.Rename;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Obfuz
|
namespace Obfuz
|
||||||
|
@ -24,6 +25,7 @@ namespace Obfuz
|
||||||
private readonly Dictionary<FieldDef, RenameRecord> _fieldRenames = new Dictionary<FieldDef, RenameRecord>();
|
private readonly Dictionary<FieldDef, RenameRecord> _fieldRenames = new Dictionary<FieldDef, RenameRecord>();
|
||||||
private readonly Dictionary<PropertyDef, RenameRecord> _propertyRenames = new Dictionary<PropertyDef, RenameRecord>();
|
private readonly Dictionary<PropertyDef, RenameRecord> _propertyRenames = new Dictionary<PropertyDef, RenameRecord>();
|
||||||
private readonly Dictionary<EventDef, RenameRecord> _eventRenames = new Dictionary<EventDef, RenameRecord>();
|
private readonly Dictionary<EventDef, RenameRecord> _eventRenames = new Dictionary<EventDef, RenameRecord>();
|
||||||
|
private readonly Dictionary<VirtualMethodGroup, RenameRecord> _virtualMethodGroups = new Dictionary<VirtualMethodGroup, RenameRecord>();
|
||||||
|
|
||||||
|
|
||||||
public void AddRenameRecord(ModuleDefMD mod, string oldName, string newName)
|
public void AddRenameRecord(ModuleDefMD mod, string oldName, string newName)
|
||||||
|
@ -56,6 +58,29 @@ namespace Obfuz
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddRenameRecord(VirtualMethodGroup methodGroup, string oldName, string newName)
|
||||||
|
{
|
||||||
|
_virtualMethodGroups.Add(methodGroup, new RenameRecord
|
||||||
|
{
|
||||||
|
status = RenameStatus.Renamed,
|
||||||
|
oldName = oldName,
|
||||||
|
newName = newName
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetRenameRecord(VirtualMethodGroup group, out string oldName, out string newName)
|
||||||
|
{
|
||||||
|
if (_virtualMethodGroups.TryGetValue(group, out var record))
|
||||||
|
{
|
||||||
|
oldName = record.oldName;
|
||||||
|
newName = record.newName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
oldName = null;
|
||||||
|
newName = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void AddRenameRecord(FieldDef field, string oldName, string newName)
|
public void AddRenameRecord(FieldDef field, string oldName, string newName)
|
||||||
{
|
{
|
||||||
_fieldRenames.Add(field, new RenameRecord
|
_fieldRenames.Add(field, new RenameRecord
|
||||||
|
@ -116,6 +141,16 @@ namespace Obfuz
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddUnRenameRecord(VirtualMethodGroup methodGroup)
|
||||||
|
{
|
||||||
|
_virtualMethodGroups.Add(methodGroup, new RenameRecord
|
||||||
|
{
|
||||||
|
status = RenameStatus.NotRenamed,
|
||||||
|
oldName = methodGroup.methods[0].Name,
|
||||||
|
newName = null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void AddUnRenameRecord(FieldDef fieldDef)
|
public void AddUnRenameRecord(FieldDef fieldDef)
|
||||||
{
|
{
|
||||||
_fieldRenames.Add(fieldDef, new RenameRecord
|
_fieldRenames.Add(fieldDef, new RenameRecord
|
||||||
|
|
|
@ -17,10 +17,12 @@ namespace Obfuz
|
||||||
{
|
{
|
||||||
private readonly ObfuscatorContext _ctx;
|
private readonly ObfuscatorContext _ctx;
|
||||||
|
|
||||||
|
private readonly HashSet<ModuleDef> _obfuscatedModules = new HashSet<ModuleDef>();
|
||||||
private readonly IRenamePolicy _renamePolicy;
|
private readonly IRenamePolicy _renamePolicy;
|
||||||
private readonly INameMaker _nameMaker;
|
private readonly INameMaker _nameMaker;
|
||||||
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 = new RenameRecordMap();
|
private readonly RenameRecordMap _renameRecordMap = new RenameRecordMap();
|
||||||
|
private readonly VirtualMethodGroupCalculator _virtualMethodGroupCalculator = new VirtualMethodGroupCalculator();
|
||||||
|
|
||||||
class CustomAttributeInfo
|
class CustomAttributeInfo
|
||||||
{
|
{
|
||||||
|
@ -34,6 +36,11 @@ namespace Obfuz
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
_renamePolicy = ctx.renamePolicy;
|
_renamePolicy = ctx.renamePolicy;
|
||||||
_nameMaker = ctx.nameMaker;
|
_nameMaker = ctx.nameMaker;
|
||||||
|
|
||||||
|
foreach (var mod in ctx.assemblies)
|
||||||
|
{
|
||||||
|
_obfuscatedModules.Add(mod.module);
|
||||||
|
}
|
||||||
BuildCustomAttributeArguments();
|
BuildCustomAttributeArguments();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +113,7 @@ namespace Obfuz
|
||||||
|
|
||||||
public void Process()
|
public void Process()
|
||||||
{
|
{
|
||||||
|
var virtualMethods = new List<MethodDef>();
|
||||||
foreach (ObfuzAssemblyInfo ass in _ctx.assemblies)
|
foreach (ObfuzAssemblyInfo ass in _ctx.assemblies)
|
||||||
{
|
{
|
||||||
if (_renamePolicy.NeedRename(ass.module))
|
if (_renamePolicy.NeedRename(ass.module))
|
||||||
|
@ -118,6 +126,7 @@ namespace Obfuz
|
||||||
}
|
}
|
||||||
foreach (TypeDef type in ass.module.GetTypes())
|
foreach (TypeDef type in ass.module.GetTypes())
|
||||||
{
|
{
|
||||||
|
_virtualMethodGroupCalculator.CalculateType(type);
|
||||||
if (_renamePolicy.NeedRename(type))
|
if (_renamePolicy.NeedRename(type))
|
||||||
{
|
{
|
||||||
Rename(type);
|
Rename(type);
|
||||||
|
@ -139,6 +148,11 @@ namespace Obfuz
|
||||||
}
|
}
|
||||||
foreach (MethodDef method in type.Methods)
|
foreach (MethodDef method in type.Methods)
|
||||||
{
|
{
|
||||||
|
if (method.IsVirtual)
|
||||||
|
{
|
||||||
|
virtualMethods.Add(method);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (_renamePolicy.NeedRename(method))
|
if (_renamePolicy.NeedRename(method))
|
||||||
{
|
{
|
||||||
Rename(method);
|
Rename(method);
|
||||||
|
@ -179,6 +193,43 @@ namespace Obfuz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var visitedVirtualMethods = new HashSet<MethodDef>();
|
||||||
|
var groupNeedRenames = new Dictionary<VirtualMethodGroup, bool>();
|
||||||
|
foreach (var method in virtualMethods)
|
||||||
|
{
|
||||||
|
if (!visitedVirtualMethods.Add(method))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
VirtualMethodGroup group = _virtualMethodGroupCalculator.GetMethodGroup(method);
|
||||||
|
if (!groupNeedRenames.TryGetValue(group, out var needRename))
|
||||||
|
{
|
||||||
|
needRename = group.methods.All(m => _obfuscatedModules.Contains(m.DeclaringType.Module) && _renamePolicy.NeedRename(m));
|
||||||
|
groupNeedRenames.Add(group, needRename);
|
||||||
|
if (needRename)
|
||||||
|
{
|
||||||
|
_renameRecordMap.AddRenameRecord(group, method.Name, _nameMaker.GetNewName(method, method.Name));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_renameRecordMap.AddUnRenameRecord(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!needRename)
|
||||||
|
{
|
||||||
|
_renameRecordMap.AddUnRenameRecord(method);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (_renameRecordMap.TryGetRenameRecord(group, out var oldName, out var newName))
|
||||||
|
{
|
||||||
|
Rename(method, oldName, newName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"group:{group} method:{method} not found in rename record map");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ObfuzAssemblyInfo> GetReferenceMeAssemblies(ModuleDef mod)
|
private List<ObfuzAssemblyInfo> GetReferenceMeAssemblies(ModuleDef mod)
|
||||||
|
@ -597,6 +648,11 @@ namespace Obfuz
|
||||||
{
|
{
|
||||||
string oldName = method.Name;
|
string oldName = method.Name;
|
||||||
string newName = _nameMaker.GetNewName(method, oldName);
|
string newName = _nameMaker.GetNewName(method, oldName);
|
||||||
|
Rename(method, oldName, newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Rename(MethodDef method, string oldName, string newName)
|
||||||
|
{
|
||||||
|
|
||||||
ModuleDefMD mod = (ModuleDefMD)method.DeclaringType.Module;
|
ModuleDefMD mod = (ModuleDefMD)method.DeclaringType.Module;
|
||||||
RenameMethodBody(method);
|
RenameMethodBody(method);
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
using dnlib.DotNet;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Obfuz.Rename
|
||||||
|
{
|
||||||
|
|
||||||
|
public class VirtualMethodGroup
|
||||||
|
{
|
||||||
|
public List<MethodDef> methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VirtualMethodGroupCalculator
|
||||||
|
{
|
||||||
|
|
||||||
|
private class TypeFlatMethods
|
||||||
|
{
|
||||||
|
public HashSet<MethodDef> flatMethods = new HashSet<MethodDef>();
|
||||||
|
|
||||||
|
|
||||||
|
public bool TryFindMatchVirtualMethod(MethodDef method, out MethodDef matchMethodDef)
|
||||||
|
{
|
||||||
|
foreach (var parentOrInterfaceMethod in flatMethods)
|
||||||
|
{
|
||||||
|
if (parentOrInterfaceMethod.Name == method.Name && parentOrInterfaceMethod.GetParamCount() == method.GetParamCount())
|
||||||
|
{
|
||||||
|
matchMethodDef = parentOrInterfaceMethod;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matchMethodDef = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private readonly Dictionary<MethodDef, VirtualMethodGroup> _methodGroups = new Dictionary<MethodDef, VirtualMethodGroup>();
|
||||||
|
private readonly Dictionary<TypeDef, TypeFlatMethods> _visitedTypes = new Dictionary<TypeDef, TypeFlatMethods>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public VirtualMethodGroup GetMethodGroup(MethodDef methodDef)
|
||||||
|
{
|
||||||
|
if (_methodGroups.TryGetValue(methodDef, out var group))
|
||||||
|
{
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CalculateType(TypeDef typeDef)
|
||||||
|
{
|
||||||
|
if (_visitedTypes.ContainsKey(typeDef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeMethods = new TypeFlatMethods();
|
||||||
|
|
||||||
|
if (typeDef.BaseType != null)
|
||||||
|
{
|
||||||
|
TypeDef baseTypeDef = MetaUtil.GetTypeDefOrGenericTypeBase(typeDef.BaseType);
|
||||||
|
CalculateType(baseTypeDef);
|
||||||
|
typeMethods.flatMethods.AddRange(_visitedTypes[baseTypeDef].flatMethods);
|
||||||
|
foreach (var intfType in typeDef.Interfaces)
|
||||||
|
{
|
||||||
|
TypeDef intfTypeDef = MetaUtil.GetTypeDefOrGenericTypeBase(intfType.Interface);
|
||||||
|
CalculateType(intfTypeDef);
|
||||||
|
typeMethods.flatMethods.AddRange(_visitedTypes[intfTypeDef].flatMethods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var method in typeDef.Methods)
|
||||||
|
{
|
||||||
|
if (!method.IsVirtual)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (typeMethods.TryFindMatchVirtualMethod(method, out var matchMethodDef))
|
||||||
|
{
|
||||||
|
var group = _methodGroups[matchMethodDef];
|
||||||
|
group.methods.Add(method);
|
||||||
|
_methodGroups.Add(method, group);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_methodGroups.Add(method, new VirtualMethodGroup() { methods = new List<MethodDef> { method } });
|
||||||
|
}
|
||||||
|
if (method.IsNewSlot)
|
||||||
|
{
|
||||||
|
typeMethods.flatMethods.Add(method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_visitedTypes.Add(typeDef, typeMethods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue