Files
Liberium-1.8-Source-Code/Obfuscator.Obfuscator.ImportProtect/ImportProtect.cs
T

157 lines
6.1 KiB
C#
Raw Normal View History

2026-08-27 11:21:58 -06:00
using System.Collections.Generic;
using System.Linq;
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using Obfuscator.Helper;
namespace Obfuscator.Obfuscator.ImportProtect;
internal class ImportProtect
{
public static FieldDefUser CreateField(FieldSig sig)
{
return new FieldDefUser(Methods.GenerateString(), sig, FieldAttributes.Public | FieldAttributes.Static);
}
public static void Execute(ModuleDef module)
{
Dictionary<IMethod, MethodDef> dictionary = new Dictionary<IMethod, MethodDef>();
Dictionary<IMethod, TypeDef> dictionary2 = new Dictionary<IMethod, TypeDef>();
FieldDefUser fieldDefUser = CreateField(new FieldSig(module.ImportAsTypeSig(typeof(object[]))));
MethodDef methodDef = module.GlobalType.FindOrCreateStaticConstructor();
TypeDef[] array = module.GetTypes().ToArray();
foreach (TypeDef typeDef in array)
{
if (typeDef.IsDelegate || typeDef.IsGlobalModuleType || typeDef.Namespace == "Costura")
{
continue;
}
MethodDef[] array2 = typeDef.Methods.ToArray();
foreach (MethodDef methodDef2 in array2)
{
if (!methodDef2.HasBody || !methodDef2.Body.HasInstructions || methodDef2.IsConstructor)
{
continue;
}
IList<Instruction> instructions = methodDef2.Body.Instructions;
for (int k = 0; k < instructions.Count; k++)
{
if ((instructions[k].OpCode != OpCodes.Call && instructions[k].OpCode == OpCodes.Callvirt) || !(instructions[k].Operand is IMethod { IsMethodDef: not false } method))
{
continue;
}
MethodDef methodDef3 = method.ResolveMethodDef();
if (methodDef3 == null || methodDef3.HasThis)
{
continue;
}
if (dictionary.ContainsKey(method))
{
instructions[k].OpCode = OpCodes.Call;
instructions[k].Operand = dictionary[method];
continue;
}
MethodSig methodSig = CreateProxySignature(module, methodDef3);
TypeDef typeDef2 = CreateDelegateType(module, methodSig);
module.Types.Add(typeDef2);
MethodImplAttributes implFlags = MethodImplAttributes.IL;
MethodAttributes flags = MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig;
MethodDefUser methodDefUser = new MethodDefUser(Methods.GenerateString(), methodSig, implFlags, flags);
methodDefUser.Body = new CilBody();
methodDefUser.Body.Instructions.Add(OpCodes.Ldsfld.ToInstruction(fieldDefUser));
methodDefUser.Body.Instructions.Add(OpCodes.Ldc_I4.ToInstruction(dictionary2.Count));
methodDefUser.Body.Instructions.Add(OpCodes.Ldelem_Ref.ToInstruction());
foreach (Parameter parameter in methodDefUser.Parameters)
{
parameter.Name = Methods.GenerateString();
methodDefUser.Body.Instructions.Add(OpCodes.Ldarg.ToInstruction(parameter));
}
methodDefUser.Body.Instructions.Add(OpCodes.Call.ToInstruction(typeDef2.Methods[1]));
methodDefUser.Body.Instructions.Add(OpCodes.Ret.ToInstruction());
typeDef2.Methods.Add(methodDefUser);
instructions[k].OpCode = OpCodes.Call;
instructions[k].Operand = methodDefUser;
if (method.IsMethodDef)
{
dictionary2.Add(methodDef3, typeDef2);
}
else if (method.IsMemberRef)
{
dictionary2.Add(method as MemberRef, typeDef2);
}
dictionary.Add(method, methodDefUser);
}
}
}
module.GlobalType.Fields.Add(fieldDefUser);
List<Instruction> list = new List<Instruction>();
List<Instruction> list2 = methodDef.Body.Instructions.ToList();
methodDef.Body.Instructions.Clear();
list.Add(OpCodes.Ldc_I4.ToInstruction(dictionary2.Count));
list.Add(OpCodes.Newarr.ToInstruction(module.CorLibTypes.Object));
list.Add(OpCodes.Dup.ToInstruction());
int num = 0;
foreach (KeyValuePair<IMethod, TypeDef> item in dictionary2)
{
list.Add(OpCodes.Ldc_I4.ToInstruction(num));
list.Add(OpCodes.Ldnull.ToInstruction());
list.Add(OpCodes.Ldftn.ToInstruction(item.Key));
list.Add(OpCodes.Newobj.ToInstruction(item.Value.Methods[0]));
list.Add(OpCodes.Stelem_Ref.ToInstruction());
list.Add(OpCodes.Dup.ToInstruction());
num++;
}
list.Add(OpCodes.Pop.ToInstruction());
list.Add(OpCodes.Stsfld.ToInstruction(fieldDefUser));
foreach (Instruction item2 in list)
{
methodDef.Body.Instructions.Add(item2);
}
foreach (Instruction item3 in list2)
{
methodDef.Body.Instructions.Add(item3);
}
}
public static TypeDef CreateDelegateType(ModuleDef module, MethodSig sig)
{
TypeDefUser obj = new TypeDefUser(Methods.GenerateString(), module.CorLibTypes.GetTypeRef("System", "MulticastDelegate"))
{
Attributes = (TypeAttributes.Public | TypeAttributes.Sealed)
};
MethodDefUser item = new MethodDefUser(".ctor", MethodSig.CreateInstance(module.CorLibTypes.Void, module.CorLibTypes.Object, module.CorLibTypes.IntPtr))
{
Attributes = (MethodAttributes.Assembly | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName),
ImplAttributes = MethodImplAttributes.CodeTypeMask
};
obj.Methods.Add(item);
MethodDefUser item2 = new MethodDefUser("Invoke", sig.Clone())
{
MethodSig =
{
HasThis = true
},
Attributes = (MethodAttributes.Assembly | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.VtableLayoutMask),
ImplAttributes = MethodImplAttributes.CodeTypeMask
};
obj.Methods.Add(item2);
return obj;
}
public static MethodSig CreateProxySignature(ModuleDef module, IMethod method)
{
IEnumerable<TypeSig> enumerable = method.MethodSig.Params.Select((TypeSig type) => (type.IsClassSig && method.MethodSig.HasThis) ? module.CorLibTypes.Object : type);
if (method.MethodSig.HasThis && !method.MethodSig.ExplicitThis)
{
TypeDef typeDef = method.DeclaringType.ResolveTypeDefThrow();
enumerable = (typeDef.IsValueType ? new TypeSig[1] { typeDef.ToTypeSig() }.Concat(enumerable) : new CorLibTypeSig[1] { module.CorLibTypes.Object }.Concat(enumerable));
}
TypeSig typeSig = method.MethodSig.RetType;
if (typeSig.IsClassSig)
{
typeSig = module.CorLibTypes.Object;
}
return MethodSig.CreateStatic(typeSig, enumerable.ToArray());
}
}