Pin field order on base types of serializable types

pull/36/head
olivato 2026-09-01 16:29:28 +01:00
parent 7ea47268d4
commit 1236b2fbf7
1 changed files with 26 additions and 1 deletions

View File

@ -30,6 +30,7 @@ namespace Obfuz.ObfusPasses.SymbolObfus
{ {
private readonly Random _random; private readonly Random _random;
private readonly IObfuscationPolicy _renamePolicy; private readonly IObfuscationPolicy _renamePolicy;
private readonly HashSet<TypeDef> _serializedLayoutBases = new HashSet<TypeDef>();
public MemberReorder(int seed, IObfuscationPolicy renamePolicy) public MemberReorder(int seed, IObfuscationPolicy renamePolicy)
{ {
@ -43,6 +44,16 @@ namespace Obfuz.ObfusPasses.SymbolObfus
public void Process(List<ModuleDef> modules) public void Process(List<ModuleDef> modules)
{ {
foreach (ModuleDef mod in modules)
{
foreach (TypeDef type in mod.GetTypes())
{
if (type.IsSerializable)
{
PinBaseLayout(type);
}
}
}
foreach (ModuleDef mod in modules) foreach (ModuleDef mod in modules)
{ {
Reorder(mod.Types, t => t.IsGlobalModuleType || IsPositionPinnedType(t)); Reorder(mod.Types, t => t.IsGlobalModuleType || IsPositionPinnedType(t));
@ -59,6 +70,20 @@ namespace Obfuz.ObfusPasses.SymbolObfus
} }
} }
private void PinBaseLayout(TypeDef type)
{
for (ITypeDefOrRef baseType = type.BaseType; baseType != null; )
{
TypeDef baseTypeDef = baseType.ResolveTypeDef()
?? (baseType as TypeSpec)?.TypeSig.ToGenericInstSig()?.GenericType?.TypeDefOrRef?.ResolveTypeDef();
if (baseTypeDef == null || !_serializedLayoutBases.Add(baseTypeDef))
{
return;
}
baseType = baseTypeDef.BaseType;
}
}
private bool IsPositionPinnedType(TypeDef type) private bool IsPositionPinnedType(TypeDef type)
{ {
if (!_renamePolicy.NeedRename(type)) if (!_renamePolicy.NeedRename(type))
@ -89,7 +114,7 @@ namespace Obfuz.ObfusPasses.SymbolObfus
private bool MayReorderFields(TypeDef type) private bool MayReorderFields(TypeDef type)
{ {
if (!_renamePolicy.NeedRename(type)) if (!_renamePolicy.NeedRename(type) || _serializedLayoutBases.Contains(type))
{ {
return false; return false;
} }