类型注入:无 DLL 依赖的运行时交付
设计哲学零外部依赖许多保护工具要求用户分发运行时 DLL如 VMProtectSDK32.dll。我们的设计所有运行时类型在保护时完整克隆到目标程序集。InjectHelperdnlib 深度克隆引擎public static class InjectHelper{// 入口 1克隆整个类型到目标模块 public static TypeDef Inject(TypeDef typeDef, ModuleDef target){var ctx new InjectContext(typeDef.Module, target);return (TypeDef)ctx.Import(typeDef);}// 入口 2克隆单个方法 public static MethodDef Inject(MethodDef methodDef, ModuleDef target){var ctx new InjectContext(methodDef.Module, target);return (MethodDef)ctx.Import(methodDef);}// 入口 3批量克隆共享上下文处理交叉引用 public static List InjectMany(IEnumerable typeDefs, ModuleDef target){var ctx new InjectContext(typeDefs.First().Module, target);return typeDefs.Select(t (TypeDef)ctx.Import(t)).ToList();}}克隆管道浅拷贝 → 深拷贝 → 签名修复class InjectContext : ImportMapper{// 映射表origin → cloneDictionaryIMemberRef, IMemberRef _map new();IMemberRef Import(IMemberRef member){// 1. 已克隆→ 直接返回映射if (_map.TryGetValue(member, out var mapped))return mapped;// 2. 根据类型深度克隆 return member switch { TypeDef td Clone(td), MethodDef md Clone(md), FieldDef fd Clone(fd), TypeRef tr TargetModule.Import(tr), MemberRef mr TargetModule.Import(mr), _ member };}TypeDef Clone(TypeDef origin){var clone new TypeDefUser(origin.Namespace, origin.Name){Attributes origin.Attributes,BaseType Import(origin.BaseType)};// 记录映射 _map[origin] clone; // 克隆接口 foreach (var iface in origin.Interfaces) clone.Interfaces.Add(new InterfaceImplUser(Import(iface.Interface))); // 克隆属性 foreach (var prop in origin.Properties) clone.Properties.Add(Clone(prop)); // 克隆字段 foreach (var field in origin.Fields) clone.Fields.Add(Clone(field)); // 克隆方法含方法体 IL foreach (var method in origin.Methods) clone.Methods.Add(Clone(method)); return clone;}MethodDef Clone(MethodDef origin){var clone new MethodDefUser(origin.Name,Import(origin.MethodSig),origin.ImplAttributes,origin.Attributes);_map[origin] clone; // 克隆方法体IL 指令、局部变量、异常处理器 if (origin.HasBody) { clone.Body new CilBody(); clone.Body.InitLocals origin.Body.InitLocals; clone.Body.MaxStack origin.Body.MaxStack; // 复制局部变量 foreach (var local in origin.Body.Variables) clone.Body.Variables.Add(new Local(Import(local.Type))); // 复制 IL 指令映射操作数 foreach (var instr in origin.Body.Instructions) { var cloneInstr new Instruction( instr.OpCode, MapOperand(instr.Operand)); clone.Body.Instructions.Add(cloneInstr); } // 复制异常处理器 foreach (var eh in origin.Body.ExceptionHandlers) { clone.Body.ExceptionHandlers.Add(new ExceptionHandler(eh.HandlerType) { CatchType Import(eh.CatchType), TryStart Map(eh.TryStart), TryEnd Map(eh.TryEnd), HandlerStart Map(eh.HandlerStart), HandlerEnd Map(eh.HandlerEnd), }); } } return clone;}}InjectContextImportMapper 与框架重定向.NET Core 的 UI 外观程序集System.Runtime.dll 等需要重定向到核心库public override IMemberRef Map(IMemberRef member){var asm member.DeclaringType?.DefinitionAssembly;if (asm null) return base.Map(member);// 0a. .NET Framework 目标遇到 System.Private.CoreLib → 重定向到 mscorlib if (!TargetIsNetCore IsCoreLib(asm)) return RedirectTo(asm, TargetModule.CorLibTypes.AssemblyRef); // 0. 外观程序集 → 重定向到 System.Private.CoreLib 或 mscorlib if (IsFacadeAssembly(asm)) { var corlib TargetModule.CorLibTypes.AssemblyRef; return RedirectTo(asm, corlib); } // 1. 目标模块已有同名引用→ 使用已有的 var existingRef TargetModule.GetAssemblyRef(asm.Name); if (existingRef ! null existingRef.Version asm.Version) return existingRef; return base.Map(member);}static readonly HashSet _facadeAsmNames new(){“System.Runtime”, “System.IO”, “System.Linq”, “System.Collections”,“System.Threading”, “System.Reflection”, “System.Diagnostics”,“netstandard”, “System.Net.Http”, “System.ComponentModel”,// … 40 个框架外观程序集};4. MutationHelper占位符替换引擎public static class MutationHelper{// 映射Mutation 字段名 → key 索引static readonly Dictionarystring, int field2index new(){{ “KeyI0”, 0 }, { “KeyI1”, 1 }, { “KeyI2”, 2 }, { “KeyI3”, 3 },{ “KeyI4”, 4 }, { “KeyI5”, 5 }, { “KeyI6”, 6 }, { “KeyI7”, 7 },{ “KeyI8”, 8 }, { “KeyI9”, 9 }, { “KeyI10”, 10 }, { “KeyI11”, 11 },{ “KeyI12”, 12 }, { “KeyI13”, 13 }, { “KeyI14”, 14 }, { “KeyI15”, 15 },};// 替换 Key 占位符 public static void InjectKey(MethodDef method, int keyId, int value) { foreach (var instr in method.Body.Instructions) { if (instr.OpCode ! OpCodes.Ldsfld) continue; var field (IField)instr.Operand; // TWSoft.Runtime.Mutation.KeyI0 → ldc.i4 value if (field.DeclaringType.Name Mutation field2index.TryGetValue(field.Name, out int id) id keyId) { instr.OpCode OpCodes.Ldc_I4; instr.Operand value; } } } // 替换 Placeholder 调用 public static void ReplacePlaceholder( MethodDef method, FuncInstruction[], Instruction[] repl) { foreach (var instr in method.Body.Instructions.ToList()) { if (instr.OpCode ! OpCodes.Call) continue; var called (IMethod)instr.Operand; // Mutation.PlaceholderT(T val) → 替换为真实指令序列 if (called.Name Placeholder) { // 追踪参数来源 Instruction[] argInstructions TraceArguments(instr); // 移除原 call 指令 int index method.Body.Instructions.IndexOf(instr); method.Body.Instructions.RemoveAt(index); // 插入替换指令 var replacement repl(argInstructions); foreach (var replInstr in replacement.Reverse()) method.Body.Instructions.Insert(index, replInstr); } } }}