68 lines
1.9 KiB
C#
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>();
|
|
}
|
|
}
|