using dnlib.DotNet;
using dnlib.DotNet.Emit;
using System.Collections.Generic;
using System.Linq;
namespace Server.RenamingObfuscation.Classes
{
public static class InjectHelper
{
///
/// Clones the specified origin TypeDef.
///
/// The origin TypeDef.
/// The cloned TypeDef.
static TypeDefUser Clone(TypeDef origin)
{
var ret = new TypeDefUser(origin.Namespace, origin.Name);
ret.Attributes = origin.Attributes;
if (origin.ClassLayout != null)
ret.ClassLayout = new ClassLayoutUser(origin.ClassLayout.PackingSize, origin.ClassSize);
foreach (GenericParam genericParam in origin.GenericParameters)
ret.GenericParameters.Add(new GenericParamUser(genericParam.Number, genericParam.Flags, "-"));
return ret;
}
///
/// Clones the specified origin MethodDef.
///
/// The origin MethodDef.
/// The cloned MethodDef.
static MethodDefUser Clone(MethodDef origin)
{
var ret = new MethodDefUser(origin.Name, null, origin.ImplAttributes, origin.Attributes);
foreach (GenericParam genericParam in origin.GenericParameters)
ret.GenericParameters.Add(new GenericParamUser(genericParam.Number, genericParam.Flags, "-"));
return ret;
}
///
/// Clones the specified origin FieldDef.
///
/// The origin FieldDef.
/// The cloned FieldDef.
static FieldDefUser Clone(FieldDef origin)
{
var ret = new FieldDefUser(origin.Name, null, origin.Attributes);
return ret;
}
///
/// Populates the context mappings.
///
/// The origin TypeDef.
/// The injection context.
/// The new TypeDef.
static TypeDef PopulateContext(TypeDef typeDef, InjectContext ctx)
{
TypeDef ret;
IDnlibDef existing;
if (!ctx.Map.TryGetValue(typeDef, out existing))
{
ret = Clone(typeDef);
ctx.Map[typeDef] = ret;
}
else
ret = (TypeDef)existing;
foreach (TypeDef nestedType in typeDef.NestedTypes)
ret.NestedTypes.Add(PopulateContext(nestedType, ctx));
foreach (MethodDef method in typeDef.Methods)
ret.Methods.Add((MethodDef)(ctx.Map[method] = Clone(method)));
foreach (FieldDef field in typeDef.Fields)
ret.Fields.Add((FieldDef)(ctx.Map[field] = Clone(field)));
return ret;
}
///
/// Copies the information from the origin type to injected type.
///
/// The origin TypeDef.
/// The injection context.
static void CopyTypeDef(TypeDef typeDef, InjectContext ctx)
{
var newTypeDef = (TypeDef)ctx.Map[typeDef];
newTypeDef.BaseType = (ITypeDefOrRef)ctx.Importer.Import(typeDef.BaseType);
foreach (InterfaceImpl iface in typeDef.Interfaces)
newTypeDef.Interfaces.Add(new InterfaceImplUser((ITypeDefOrRef)ctx.Importer.Import(iface.Interface)));
}
///
/// Copies the information from the origin method to injected method.
///
/// The origin MethodDef.
/// The injection context.
static void CopyMethodDef(MethodDef methodDef, InjectContext ctx)
{
var newMethodDef = (MethodDef)ctx.Map[methodDef];
newMethodDef.Signature = ctx.Importer.Import(methodDef.Signature);
newMethodDef.Parameters.UpdateParameterTypes();
if (methodDef.ImplMap != null)
newMethodDef.ImplMap = new ImplMapUser(new ModuleRefUser(ctx.TargetModule, methodDef.ImplMap.Module.Name), methodDef.ImplMap.Name, methodDef.ImplMap.Attributes);
foreach (CustomAttribute ca in methodDef.CustomAttributes)
newMethodDef.CustomAttributes.Add(new CustomAttribute((ICustomAttributeType)ctx.Importer.Import(ca.Constructor)));
if (methodDef.HasBody)
{
newMethodDef.Body = new CilBody(methodDef.Body.InitLocals, new List(), new List(), new List());
newMethodDef.Body.MaxStack = methodDef.Body.MaxStack;
var bodyMap = new Dictionary