Files
2026-08-27 11:21:58 -06:00

68 lines
1.9 KiB
C#

using System.Collections.Generic;
using System.Linq;
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using Obfuscator.Helper;
namespace Obfuscator.Obfuscator.Local2Field;
internal class Local2Field
{
private static Dictionary<Local, FieldDef> _convertedLocals = new Dictionary<Local, FieldDef>();
public static void Execute(ModuleDef moduleDef)
{
foreach (TypeDef item in moduleDef.Types.Where((TypeDef x) => x != moduleDef.GlobalType))
{
foreach (MethodDef item2 in item.Methods.Where((MethodDef x) => x.HasBody && x.Body.HasInstructions && !x.IsConstructor))
{
_convertedLocals = new Dictionary<Local, FieldDef>();
Process(moduleDef, item2);
}
}
}
private static void Process(ModuleDef module, MethodDef meth)
{
meth.Body.SimplifyMacros(meth.Parameters);
foreach (Instruction instruction in meth.Body.Instructions)
{
if (instruction.Operand is Local local)
{
FieldDef fieldDef;
if (!_convertedLocals.ContainsKey(local))
{
fieldDef = new FieldDefUser(Methods.GenerateString(), new FieldSig(local.Type), FieldAttributes.Public | FieldAttributes.Static);
module.GlobalType.Fields.Add(fieldDef);
_convertedLocals.Add(local, fieldDef);
}
else
{
fieldDef = _convertedLocals[local];
}
switch (instruction.OpCode?.Code)
{
case Code.Ldloc:
instruction.OpCode = OpCodes.Ldsfld;
break;
case Code.Ldloca:
instruction.OpCode = OpCodes.Ldsflda;
break;
case Code.Stloc:
instruction.OpCode = OpCodes.Stsfld;
break;
default:
instruction.OpCode = null;
break;
}
instruction.Operand = fieldDef;
}
}
_convertedLocals.ToList().ForEach(delegate(KeyValuePair<Local, FieldDef> x)
{
meth.Body.Variables.Remove(x.Key);
});
_convertedLocals = new Dictionary<Local, FieldDef>();
}
}