/// <summary> /// Initializes a new instance of the <see cref="APIStore" /> class. /// </summary> /// <param name="context">The working context.</param> public APIStore(ConfuserContext context) { this.context = context; random = context.Registry.GetService<IRandomService>().GetRandomGenerator("APIStore"); dataStores = new SortedList<int, List<IDataStore>>(); predicates = new List<IOpaquePredicateDescriptor>(); }
public void PreRename(ConfuserContext context, INameService service, ProtectionParameters parameters, IDnlibDef def) { if (!(def is ModuleDefMD module) || !parameters.GetParameter <bool>(context, def, "renXaml", true)) { return; } Dictionary <string, Dictionary <string, BamlDocument> > wpfResInfo = context.Annotations.Get <Dictionary <string, Dictionary <string, BamlDocument> > >(module, BAMLKey); if (wpfResInfo == null) { return; } foreach (Dictionary <string, BamlDocument> res in wpfResInfo.Values) { foreach (BamlDocument doc in res.Values) { if (bamlRefs.TryGetValue(doc.DocumentName, out List <IBAMLReference> references)) { string newName = doc.DocumentName.ToUpperInvariant(); #region old code //if (newName.EndsWith(".BAML")) // newName = service.RandomName(RenameMode.Letters).ToLowerInvariant() + ".baml"; //else if (newName.EndsWith(".XAML")) // newName = service.RandomName(RenameMode.Letters).ToLowerInvariant() + ".xaml"; #endregion #region Niks patch fix /* * Nik's patch for maintaining relative paths. If the xaml file is referenced in this manner * "/some.namespace;component/somefolder/somecontrol.xaml" * then we want to keep the relative path and namespace intact. We should be obfuscating it like this - /some.namespace;component/somefolder/asjdjh2398498dswk.xaml * */ string[] completePath = newName.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries); string newShinyName = string.Empty; for (int i = 0; i <= completePath.Length - 2; i++) { newShinyName += completePath[i].ToLowerInvariant() + "/"; } if (newName.EndsWith(".BAML")) { newName = newShinyName + service.RandomName() + ".baml"; } else if (newName.EndsWith(".XAML")) { newName = newShinyName + service.RandomName() + ".xaml"; } context.Logger.Log(String.Format("Preserving virtual paths. Replaced {0} with {1}", doc.DocumentName, newName)); #endregion bool renameOk = true; foreach (IBAMLReference bamlRef in references) { if (!bamlRef.CanRename(doc.DocumentName, newName)) { renameOk = false; break; } } if (renameOk) { foreach (IBAMLReference bamlRef in references) { bamlRef.Rename(doc.DocumentName, newName); } doc.DocumentName = newName; } } } } }
public bool UpdateNameReference(ConfuserContext context, INameService service) { resource.Name = string.Format(format, typeDef.ReflectionFullName); return(true); }
public void ExcludeMethod(ConfuserContext context, MethodDef method) { ProtectionParameters.GetParameters(context, method).Remove(this); }
public void PostRename(ConfuserContext context, INameService service, ProtectionParameters parameters, IDnlibDef def) { // }
protected override void Initialize(ConfuserContext context) { context.Registry.RegisterService("Ki.MildRefProxy", typeof(IMildReferenceProxyService), this); }
protected override void Initialize(ConfuserContext context) { // }
private bool HandleTypeOf(ConfuserContext context, INameService service, MethodDef method, int index) { if (index + 1 >= method.Body.Instructions.Count) { return(true); } var gtfh = method.Body.Instructions[index + 1].Operand as IMethod; if (gtfh == null || gtfh.FullName != "System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)") { return(true); } if (index + 2 < method.Body.Instructions.Count) { Instruction instr = method.Body.Instructions[index + 2]; var operand = instr.Operand as IMethod; if (instr.OpCode == OpCodes.Newobj && operand.FullName == "System.Void System.ComponentModel.ComponentResourceManager::.ctor(System.Type)") { return(false); } if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt) { switch (operand.DeclaringType.FullName) { case "System.Runtime.InteropServices.Marshal": return(false); case "System.Type": if (operand.Name.StartsWith("Get") || operand.Name == "InvokeMember") { return(true); } if (operand.Name == "get_AssemblyQualifiedName" || operand.Name == "get_FullName" || operand.Name == "get_Namespace") { return(true); } return(false); case "System.Reflection.MemberInfo": return(operand.Name == "get_Name"); case "System.Object": return(operand.Name == "ToString"); } } } if (index + 3 < method.Body.Instructions.Count) { Instruction instr = method.Body.Instructions[index + 3]; var operand = instr.Operand as IMethod; if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt) { switch (operand.DeclaringType.FullName) { case "System.Runtime.InteropServices.Marshal": return(false); } } } return(true); }
public void Init(ConfuserContext ctx, RandomGenerator random) { // }
private void InjectStub(ConfuserContext context, CompressorContext compCtx, ProtectionParameters parameters, ModuleDef stubModule) { var rt = context.Registry.GetService <IRuntimeService>(); RandomGenerator random = context.Registry.GetService <IRandomService>().GetRandomGenerator(Id); var comp = context.Registry.GetService <ICompressionService>(); var rtType = rt.GetRuntimeType(compCtx.CompatMode ? "Confuser.Runtime.CompressorCompat" : "Confuser.Runtime.Compressor"); IEnumerable <ISDnlibDef> defs = InjectHelper.Inject(rtType, stubModule.GlobalType, stubModule); switch (parameters.GetParameter(context, context.CurrentModule, "key", Mode.Normal)) { case Mode.Normal: compCtx.Deriver = new NormalDeriver(); break; case Mode.Dynamic: compCtx.Deriver = new DynamicDeriver(); break; default: throw new UnreachableException(); } compCtx.Deriver.Init(context, random); context.Logger.Debug("Encrypting modules..."); // Main MethodDef entryPoint = defs.OfType <MethodDef>().Single(method => method.Name == "Main"); stubModule.EntryPoint = entryPoint; if (compCtx.EntryPoint.HasAttribute("System.STAThreadAttribute")) { var attrType = stubModule.CorLibTypes.GetTypeRef("System", "STAThreadAttribute"); var ctorSig = MethodSig.CreateInstance(stubModule.CorLibTypes.Void); entryPoint.CustomAttributes.Add(new CustomAttribute( new MemberRefUser(stubModule, ".ctor", ctorSig, attrType))); } else if (compCtx.EntryPoint.HasAttribute("System.MTAThreadAttribute")) { var attrType = stubModule.CorLibTypes.GetTypeRef("System", "MTAThreadAttribute"); var ctorSig = MethodSig.CreateInstance(stubModule.CorLibTypes.Void); entryPoint.CustomAttributes.Add(new CustomAttribute( new MemberRefUser(stubModule, ".ctor", ctorSig, attrType))); } uint seed = random.NextUInt32(); compCtx.OriginModule = context.OutputModules[compCtx.ModuleIndex]; byte[] encryptedModule = compCtx.Encrypt(comp, compCtx.OriginModule, seed, progress => context.Logger.Progress((int)(progress * 10000), 10000)); context.Logger.EndProgress(); context.CheckCancellation(); compCtx.EncryptedModule = encryptedModule; MutationHelper.InjectKeys(entryPoint, new[] { 0, 1 }, new[] { encryptedModule.Length >> 2, (int)seed }); InjectData(stubModule, entryPoint, encryptedModule); // Decrypt MethodDef decrypter = defs.OfType <MethodDef>().Single(method => method.Name == "Decrypt"); decrypter.Body.SimplifyMacros(decrypter.Parameters); List <Instruction> instrs = decrypter.Body.Instructions.ToList(); for (int i = 0; i < instrs.Count; i++) { Instruction instr = instrs[i]; if (instr.OpCode == OpCodes.Call) { var method = (IMethod)instr.Operand; if (method.DeclaringType.Name == "Mutation" && method.Name == "Crypt") { Instruction ldDst = instrs[i - 2]; Instruction ldSrc = instrs[i - 1]; Debug.Assert(ldDst.OpCode == OpCodes.Ldloc && ldSrc.OpCode == OpCodes.Ldloc); instrs.RemoveAt(i); instrs.RemoveAt(i - 1); instrs.RemoveAt(i - 2); instrs.InsertRange(i - 2, compCtx.Deriver.EmitDerivation(decrypter, context, (Local)ldDst.Operand, (Local)ldSrc.Operand)); } else if (method.DeclaringType.Name == "Lzma" && method.Name == "Decompress") { MethodDef decomp = comp.GetRuntimeDecompressor(stubModule, member => { }); instr.Operand = decomp; } } } decrypter.Body.Instructions.Clear(); foreach (Instruction instr in instrs) { decrypter.Body.Instructions.Add(instr); } // Pack modules PackModules(context, compCtx, stubModule, comp, random); }
private void PackModules(ConfuserContext context, CompressorContext compCtx, ModuleDef stubModule, ICompressionService comp, RandomGenerator random) { int maxLen = 0; var modules = new Dictionary <string, byte[]>(); for (int i = 0; i < context.OutputModules.Count; i++) { if (i == compCtx.ModuleIndex) { continue; } string id = GetId(context.Modules[i].Assembly); modules.Add(id, context.OutputModules[i]); int strLen = Encoding.UTF8.GetByteCount(id); if (strLen > maxLen) { maxLen = strLen; } } foreach (var extModule in context.ExternalModules) { var name = GetId(extModule).ToUpperInvariant(); modules.Add(name, extModule); int strLen = Encoding.UTF8.GetByteCount(name); if (strLen > maxLen) { maxLen = strLen; } } byte[] key = random.NextBytes(4 + maxLen); key[0] = (byte)(compCtx.EntryPointToken >> 0); key[1] = (byte)(compCtx.EntryPointToken >> 8); key[2] = (byte)(compCtx.EntryPointToken >> 16); key[3] = (byte)(compCtx.EntryPointToken >> 24); for (int i = 4; i < key.Length; i++) // no zero bytes { key[i] |= 1; } compCtx.KeySig = key; int moduleIndex = 0; foreach (var entry in modules) { byte[] name = Encoding.UTF8.GetBytes(entry.Key); for (int i = 0; i < name.Length; i++) { name[i] *= key[i + 4]; } uint state = 0x6fff61; foreach (byte chr in name) { state = state * 0x5e3f1f + chr; } byte[] encrypted = compCtx.Encrypt(comp, entry.Value, state, progress => { progress = (progress + moduleIndex) / modules.Count; context.Logger.Progress((int)(progress * 10000), 10000); }); context.CheckCancellation(); var resource = new EmbeddedResource(Convert.ToBase64String(name), encrypted, ManifestResourceAttributes.Private); stubModule.Resources.Add(resource); moduleIndex++; } context.Logger.EndProgress(); }
private void HandleEnum(ConfuserContext context, INameService service, MethodDef method, int index) { var target = (IMethod)method.Body.Instructions[index].Operand; if (target.FullName == "System.String System.Object::ToString()" || target.FullName == "System.String System.Enum::ToString(System.String)") { int prevIndex = index - 1; while (prevIndex >= 0 && method.Body.Instructions[prevIndex].OpCode.Code == Code.Nop) { prevIndex--; } if (prevIndex < 0) { return; } Instruction prevInstr = method.Body.Instructions[prevIndex]; TypeSig targetType; if (prevInstr.Operand is MemberRef) { var memberRef = (MemberRef)prevInstr.Operand; targetType = memberRef.IsFieldRef ? memberRef.FieldSig.Type : memberRef.MethodSig.RetType; } else if (prevInstr.Operand is IField) { targetType = ((IField)prevInstr.Operand).FieldSig.Type; } else if (prevInstr.Operand is IMethod) { targetType = ((IMethod)prevInstr.Operand).MethodSig.RetType; } else if (prevInstr.Operand is ITypeDefOrRef) { targetType = ((ITypeDefOrRef)prevInstr.Operand).ToTypeSig(); } else if (prevInstr.GetParameter(method.Parameters) != null) { targetType = prevInstr.GetParameter(method.Parameters).Type; } else if (prevInstr.GetLocal(method.Body.Variables) != null) { targetType = prevInstr.GetLocal(method.Body.Variables).Type; } else { return; } ITypeDefOrRef targetTypeRef = targetType.ToBasicTypeDefOrRef(); if (targetTypeRef == null) { return; } TypeDef targetTypeDef = targetTypeRef.ResolveTypeDefThrow(); if (targetTypeDef != null && targetTypeDef.IsEnum && context.Modules.Contains((ModuleDefMD)targetTypeDef.Module)) { DisableRename(service, targetTypeDef); } } }
public void PostRename(ConfuserContext context, INameService service, IDnlibDef def) { // }
public void Analyze(ConfuserContext context, INameService service, IDnlibDef def) { var method = def as MethodDef; if (method == null || !method.HasBody) { return; } // When a ldtoken instruction reference a definition, // most likely it would be used in reflection and thus probably should not be renamed. // Also, when ToString is invoked on enum, // the enum should not be renamed. for (int i = 0; i < method.Body.Instructions.Count; i++) { Instruction instr = method.Body.Instructions[i]; if (instr.OpCode.Code == Code.Ldtoken) { if (instr.Operand is MemberRef) { IMemberForwarded member = ((MemberRef)instr.Operand).ResolveThrow(); if (context.Modules.Contains((ModuleDefMD)member.Module)) { service.SetCanRename(member, false); } } else if (instr.Operand is IField) { FieldDef field = ((IField)instr.Operand).ResolveThrow(); if (context.Modules.Contains((ModuleDefMD)field.Module)) { service.SetCanRename(field, false); } } else if (instr.Operand is IMethod) { MethodDef m = ((IMethod)instr.Operand).ResolveThrow(); if (context.Modules.Contains((ModuleDefMD)m.Module)) { service.SetCanRename(method, false); } } else if (instr.Operand is ITypeDefOrRef) { if (!(instr.Operand is TypeSpec)) { TypeDef type = ((ITypeDefOrRef)instr.Operand).ResolveTypeDefThrow(); if (context.Modules.Contains((ModuleDefMD)type.Module) && HandleTypeOf(context, service, method, i)) { DisableRename(service, type, false); } } } else { throw new UnreachableException(); } } else if ((instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) && ((IMethod)instr.Operand).Name == "ToString") { HandleEnum(context, service, method, i); } else if (instr.OpCode.Code == Code.Ldstr) { TypeDef typeDef = method.Module.FindReflection((string)instr.Operand); if (typeDef != null) { service.AddReference(typeDef, new StringTypeReference(instr, typeDef)); } } } }
RPContext ParseParameters(MethodDef method, ConfuserContext context, ProtectionParameters parameters, RPStore store) { var ret = new RPContext(); ret.Mode = parameters.GetParameter(context, method, "mode", Mode.Mild); ret.Encoding = parameters.GetParameter(context, method, "encoding", EncodingType.Expression); ret.InternalAlso = parameters.GetParameter(context, method, "internal", true); ret.TypeErasure = parameters.GetParameter(context, method, "typeErasure", true); ret.Depth = parameters.GetParameter(context, method, "depth", 5); ret.Module = method.Module; ret.Method = method; ret.Body = method.Body; ret.BranchTargets = new HashSet <Instruction>( method.Body.Instructions .Select(instr => instr.Operand as Instruction) .Concat(method.Body.Instructions .Where(instr => instr.Operand is Instruction[]) .SelectMany(instr => (Instruction[])instr.Operand)) .Where(target => target != null)); ret.Protection = (MildReferenceProxyProtection)Parent; ret.Random = store.random; ret.Context = context; ret.Marker = context.Registry.GetService <IMarkerService>(); ret.DynCipher = context.Registry.GetService <IDynCipherService>(); ret.Name = context.Registry.GetService <INameService>(); ret.Delegates = store.delegates; switch (ret.Mode) { case Mode.Mild: ret.ModeHandler = store.mild ?? (store.mild = new MildMode()); break; case Mode.Strong: ret.ModeHandler = store.strong ?? (store.strong = new StrongMode()); break; default: throw new UnreachableException(); } switch (ret.Encoding) { case EncodingType.Normal: ret.EncodingHandler = store.normal ?? (store.normal = new NormalEncoding()); break; case EncodingType.Expression: ret.EncodingHandler = store.expression ?? (store.expression = new ExpressionEncoding()); break; case EncodingType.x86: ret.EncodingHandler = store.x86 ?? (store.x86 = new x86Encoding()); if ((context.CurrentModule.Cor20HeaderFlags & ComImageFlags.ILOnly) != 0) { context.CurrentModuleWriterOptions.Cor20HeaderOptions.Flags &= ~ComImageFlags.ILOnly; } break; default: throw new UnreachableException(); } return(ret); }
/// <summary> /// Initializes a new instance of the <see cref="MarkerService" /> class. /// </summary> /// <param name="context">The working context.</param> /// <param name="marker">The marker.</param> public MarkerService(ConfuserContext context, Marker marker) { this.context = context; this.marker = marker; }
public IEnumerable <Instruction> EmitDerivation(MethodDef method, ConfuserContext ctx, Local dst, Local src) { var state = seed; for (int i = 0; i < 0x10; i++) { yield return(Instruction.Create(OpCodes.Ldloc, dst)); yield return(Instruction.Create(OpCodes.Ldc_I4, i)); yield return(Instruction.Create(OpCodes.Ldloc, dst)); yield return(Instruction.Create(OpCodes.Ldc_I4, i)); yield return(Instruction.Create(OpCodes.Ldelem_U4)); yield return(Instruction.Create(OpCodes.Ldloc, src)); yield return(Instruction.Create(OpCodes.Ldc_I4, i)); yield return(Instruction.Create(OpCodes.Ldelem_U4)); switch (state % 3) { case 0: yield return(Instruction.Create(OpCodes.Xor)); break; case 1: yield return(Instruction.Create(OpCodes.Mul)); break; case 2: yield return(Instruction.Create(OpCodes.Add)); break; } state = (state * state) % 0x2E082D35; switch (state % 3) { case 0: yield return(Instruction.Create(OpCodes.Ldc_I4, (int)k1)); yield return(Instruction.Create(OpCodes.Add)); break; case 1: yield return(Instruction.Create(OpCodes.Ldc_I4, (int)k2)); yield return(Instruction.Create(OpCodes.Xor)); break; case 2: yield return(Instruction.Create(OpCodes.Ldc_I4, (int)k3)); yield return(Instruction.Create(OpCodes.Mul)); break; } state = (state * state) % 0x2E082D35; yield return(Instruction.Create(OpCodes.Stelem_I4)); } }
public void HandleInject(AntiTamperProtection parent, ConfuserContext context, ProtectionParameters parameters) { this.context = context; random = context.Registry.GetService <IRandomService>().GetRandomGenerator(parent.FullId); z = random.NextUInt32(); x = random.NextUInt32(); c = random.NextUInt32(); v = random.NextUInt32(); name1 = random.NextUInt32() & 0x7f7f7f7f; name2 = random.NextUInt32() & 0x7f7f7f7f; key = random.NextUInt32(); fieldLayout = new byte[6]; for (int i = 0; i < 6; i++) { int index = random.NextInt32(0, 6); while (fieldLayout[index] != 0) { index = random.NextInt32(0, 6); } fieldLayout[index] = (byte)i; } switch (parameters.GetParameter(context, context.CurrentModule, "key", Mode.Normal)) { case Mode.Normal: deriver = new NormalDeriver(); break; case Mode.Dynamic: deriver = new DynamicDeriver(); break; default: throw new UnreachableException(); } deriver.Init(context, random); var rt = context.Registry.GetService <IRuntimeService>(); TypeDef initType = rt.GetRuntimeType("Confuser.Runtime.AntiTamperJIT"); IEnumerable <ISDnlibDef> defs = InjectHelper.Inject(initType, context.CurrentModule.GlobalType, context.CurrentModule); initMethod = defs.OfType <MethodDef>().Single(method => method.Name == "Initialize"); initMethod.Body.SimplifyMacros(initMethod.Parameters); List <Instruction> instrs = initMethod.Body.Instructions.ToList(); for (int i = 0; i < instrs.Count; i++) { Instruction instr = instrs[i]; if (instr.OpCode == OpCodes.Ldtoken) { instr.Operand = context.CurrentModule.GlobalType; } else if (instr.OpCode == OpCodes.Call) { var method = (IMethod)instr.Operand; if (method.DeclaringType.Name == "Mutation" && method.Name == "Crypt") { Instruction ldDst = instrs[i - 2]; Instruction ldSrc = instrs[i - 1]; Debug.Assert(ldDst.OpCode == OpCodes.Ldloc && ldSrc.OpCode == OpCodes.Ldloc); instrs.RemoveAt(i); instrs.RemoveAt(i - 1); instrs.RemoveAt(i - 2); instrs.InsertRange(i - 2, deriver.EmitDerivation(initMethod, context, (Local)ldDst.Operand, (Local)ldSrc.Operand)); } } } initMethod.Body.Instructions.Clear(); foreach (Instruction instr in instrs) { initMethod.Body.Instructions.Add(instr); } MutationHelper.InjectKeys(initMethod, new[] { 0, 1, 2, 3, 4 }, new[] { (int)(name1 * name2), (int)z, (int)x, (int)c, (int)v }); var name = context.Registry.GetService <INameService>(); var marker = context.Registry.GetService <IMarkerService>(); cctor = context.CurrentModule.GlobalType.FindStaticConstructor(); cctorRepl = new MethodDefUser(name.RandomName(), MethodSig.CreateStatic(context.CurrentModule.CorLibTypes.Void)); cctorRepl.IsStatic = true; cctorRepl.Access = MethodAttributes.CompilerControlled; cctorRepl.Body = new CilBody(); cctorRepl.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); context.CurrentModule.GlobalType.Methods.Add(cctorRepl); name.MarkHelper(cctorRepl, marker, parent); MutationHelper.InjectKeys(defs.OfType <MethodDef>().Single(method => method.Name == "HookHandler"), new[] { 0 }, new[] { (int)key }); foreach (ISDnlibDef def in defs) { if (def.Name == "MethodData") { var dataType = (TypeDef)def; FieldDef[] fields = dataType.Fields.ToArray(); var layout = fieldLayout.Clone() as byte[]; Array.Sort(layout, fields); for (byte j = 0; j < 6; j++) { layout[j] = j; } Array.Sort(fieldLayout, layout); fieldLayout = layout; dataType.Fields.Clear(); foreach (FieldDef f in fields) { dataType.Fields.Add(f); } } name.MarkHelper(def, marker, parent); if (def is MethodDef) { parent.ExcludeMethod(context, (MethodDef)def); } } parent.ExcludeMethod(context, cctor); }
private void CreateFactories(TypeDefUser factpryParentClass, ITypeService service, ConfuserContext context, IFactory[] factories) { foreach (IFactory factory in factories) { factory.CreateFactories(service, context.CurrentModule); foreach (var generatedFactoryMethod in factory.FactoryMethods) { factpryParentClass.Methods.Add(generatedFactoryMethod); ProtectionParameters.SetParameters(context, generatedFactoryMethod, new ProtectionSettings()); } } }
/// <summary> /// Initializes a new instance of the <see cref="CompressionService" /> class. /// </summary> /// <param name="context">The working context.</param> public CompressionService(ConfuserContext context) { this.context = context; }
public void Analyze(ConfuserContext context, INameService service, ProtectionParameters parameters, IDnlibDef def) { VTable vTbl; if (def is TypeDef) { var type = (TypeDef)def; if (type.IsInterface) { return; } vTbl = service.GetVTables()[type]; foreach (var ifaceVTbl in vTbl.InterfaceSlots.Values) { foreach (var slot in ifaceVTbl) { if (slot.Overrides == null) { continue; } Debug.Assert(slot.Overrides.MethodDef.DeclaringType.IsInterface); // A method in base type can implements an interface method for a // derived type. If the base type/interface is not in our control, we should // not rename the methods. bool baseUnderCtrl = context.Modules.Contains(slot.MethodDef.DeclaringType.Module as ModuleDefMD); bool ifaceUnderCtrl = context.Modules.Contains(slot.Overrides.MethodDef.DeclaringType.Module as ModuleDefMD); if ((!baseUnderCtrl && ifaceUnderCtrl) || !service.CanRename(slot.MethodDef)) { service.SetCanRename(slot.Overrides.MethodDef, false); } else if (baseUnderCtrl && !ifaceUnderCtrl || !service.CanRename(slot.Overrides.MethodDef)) { service.SetCanRename(slot.MethodDef, false); } } } } else if (def is MethodDef) { var method = (MethodDef)def; if (!method.IsVirtual) { return; } vTbl = service.GetVTables()[method.DeclaringType]; VTableSignature sig = VTableSignature.FromMethod(method); var slots = vTbl.FindSlots(method); if (!method.IsAbstract) { foreach (var slot in slots) { if (slot.Overrides == null) { continue; } SetupOverwriteReferences(context, service, slot, method.Module); } } else { foreach (var slot in slots) { if (slot.Overrides == null) { continue; } service.SetCanRename(method, false); service.SetCanRename(slot.Overrides.MethodDef, false); } } } }
/// <summary> /// Initializes a new instance of the <see cref="MarkerService" /> class. /// </summary> /// <param name="context">The working context.</param> /// <param name="marker">The marker.</param> public MarkerService(ConfuserContext context, Marker marker) { this.context = context; this.marker = marker; helperParents = new Dictionary<IDnlibDef, ConfuserComponent>(); }
/// <summary> /// Initializes a new instance of the <see cref="MarkerService" /> class. /// </summary> /// <param name="context">The working context.</param> /// <param name="marker">The marker.</param> public MarkerService(ConfuserContext context, Marker marker) { this.context = context; this.marker = marker; helperParents = new Dictionary <ISDnlibDef, ConfuserComponent>(); }
protected override void Initialize(ConfuserContext context) { context.Registry.RegisterService(_ServiceId, typeof(IAntiTamperService), this); }
public bool UpdateNameReference(ConfuserContext context, INameService service) { namedArg.Name = definition.Name; return(true); }
public void PostRename(ConfuserContext context, INameService service, ProtectionParameters parameters, IDnlibDef def) { var module = def as ModuleDefMD; if (module == null) { return; } var wpfResInfo = context.Annotations.Get <Dictionary <string, Dictionary <string, BamlDocument> > >(module, BAMLKey); if (wpfResInfo == null) { return; } var newResources = new List <EmbeddedResource>(); foreach (EmbeddedResource res in module.Resources.OfType <EmbeddedResource>()) { Dictionary <string, BamlDocument> resInfo; if (!wpfResInfo.TryGetValue(res.Name, out resInfo)) { continue; } var stream = new MemoryStream(); var writer = new ResourceWriter(stream); var reader = new ResourceReader(res.CreateReader().AsStream()); IDictionaryEnumerator enumerator = reader.GetEnumerator(); while (enumerator.MoveNext()) { var name = (string)enumerator.Key; string typeName; byte[] data; reader.GetResourceData(name, out typeName, out data); BamlDocument document; if (resInfo.TryGetValue(name, out document)) { var docStream = new MemoryStream(); docStream.Position = 4; BamlWriter.WriteDocument(document, docStream); docStream.Position = 0; docStream.Write(BitConverter.GetBytes((int)docStream.Length - 4), 0, 4); data = docStream.ToArray(); name = document.DocumentName; } writer.AddResourceData(name, typeName, data); } writer.Generate(); newResources.Add(new EmbeddedResource(res.Name, stream.ToArray(), res.Attributes)); } foreach (EmbeddedResource res in newResources) { int index = module.Resources.IndexOfEmbeddedResource(res.Name); module.Resources[index] = res; } }
protected override void Execute(ConfuserContext context, ProtectionParameters parameters) { foreach (ModuleDef module in parameters.Targets.OfType <ModuleDef>()) { foreach (TypeDef type in module.Types.ToArray()) { foreach (MethodDef method in type.Methods.ToArray()) { if (method.HasBody) { if (method.Body.HasInstructions) { if (method.FullName.Contains("My.")) { continue; } if (method.FullName.Contains(".My")) { continue; } if (method.FullName.Contains("Costura")) { continue; } if (method.IsConstructor) { continue; } if (method.DeclaringType.IsGlobalModuleType) { continue; } for (int i = 0; i < method.Body.Instructions.Count - 1; i++) { try { if (method.Body.Instructions[i].ToString().Contains("ISupportInitialize")) { continue; } if (method.Body.Instructions[i].OpCode == OpCodes.Call || method.Body.Instructions[i].OpCode == OpCodes.Callvirt /* || method.Body.Instructions[i].OpCode == OpCodes.Ldloc_S*/) { try { MemberRef membertocalli = (MemberRef)method.Body.Instructions[i].Operand; method.Body.Instructions[i].OpCode = OpCodes.Calli; method.Body.Instructions[i].Operand = membertocalli.MethodSig; method.Body.Instructions.Insert(i, Instruction.Create(OpCodes.Ldftn, membertocalli)); } catch (Exception ex) { string str = ex.Message; } } } catch { } } } else { } } } foreach (MethodDef md in module.GlobalType.Methods) { if (md.Name == ".ctor") { module.GlobalType.Remove(md); break; } } } } }
void AnalyzeMethod(ConfuserContext context, INameService service, MethodDef method) { var dpRegInstrs = new List <Tuple <bool, Instruction> >(); var routedEvtRegInstrs = new List <Instruction>(); for (int i = 0; i < method.Body.Instructions.Count; i++) { Instruction instr = method.Body.Instructions[i]; if ((instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt)) { var regMethod = (IMethod)instr.Operand; if (regMethod.DeclaringType.FullName == "System.Windows.DependencyProperty" && regMethod.Name.String.StartsWith("Register")) { dpRegInstrs.Add(Tuple.Create(regMethod.Name.String.StartsWith("RegisterAttached"), instr)); } else if (regMethod.DeclaringType.FullName == "System.Windows.EventManager" && regMethod.Name.String == "RegisterRoutedEvent") { routedEvtRegInstrs.Add(instr); } } else if (instr.OpCode.Code == Code.Newobj) { var methodRef = (IMethod)instr.Operand; if (methodRef.DeclaringType.FullName == "System.Windows.Data.PropertyGroupDescription" && methodRef.Name == ".ctor" && i - 1 >= 0 && method.Body.Instructions[i - 1].OpCode.Code == Code.Ldstr) { foreach (PropertyDef property in analyzer.LookupProperty((string)method.Body.Instructions[i - 1].Operand)) { service.SetCanRename(property, false); } } } else if (instr.OpCode == OpCodes.Ldstr) { string operand = ((string)instr.Operand).ToUpperInvariant(); if (operand.EndsWith(".BAML") || operand.EndsWith(".XAML")) { Match match = UriPattern.Match(operand); if (match.Success) { operand = match.Groups[1].Value; } else if (operand.Contains("/")) { context.Logger.LogFormat("WARN: Fail to extract XAML name from '{0}'.", instr.Operand); } var reference = new BAMLStringReference(instr); operand = operand.TrimStart('/'); string baml = operand.Substring(0, operand.Length - 5) + ".BAML"; string xaml = operand.Substring(0, operand.Length - 5) + ".XAML"; bamlRefs.AddListEntry(baml, reference); bamlRefs.AddListEntry(xaml, reference); } } } if (dpRegInstrs.Count == 0) { return; } ITraceService traceSrv = context.Registry.GetService <ITraceService>(); MethodTrace trace = traceSrv.Trace(method); bool erred = false; foreach (Tuple <bool, Instruction> instrInfo in dpRegInstrs) { int[] args = trace.TraceArguments(instrInfo.Item2); if (args == null) { if (!erred) { context.Logger.LogFormat("WARN: Failed to extract dependency property name in '{0}'.", method.FullName); } erred = true; continue; } Instruction ldstr = method.Body.Instructions[args[0]]; if (ldstr.OpCode.Code != Code.Ldstr) { if (!erred) { context.Logger.LogFormat("WARN: Failed to extract dependency property name in '{0}'.", method.FullName); } erred = true; continue; } string name = (string)ldstr.Operand; TypeDef declType = method.DeclaringType; bool found = false; if (instrInfo.Item1) // Attached DP { MethodDef accessor; if ((accessor = declType.FindMethod("Get" + name)) != null && accessor.IsStatic) { service.SetCanRename(accessor, false); found = true; } if ((accessor = declType.FindMethod("Set" + name)) != null && accessor.IsStatic) { service.SetCanRename(accessor, false); found = true; } } // Normal DP // Find CLR property for attached DP as well, because it seems attached DP can be use as normal DP as well. PropertyDef property = null; if ((property = declType.FindProperty(name)) != null) { service.SetCanRename(property, false); found = true; if (property.GetMethod != null) { service.SetCanRename(property.GetMethod, false); } if (property.SetMethod != null) { service.SetCanRename(property.SetMethod, false); } if (property.HasOtherMethods) { foreach (MethodDef accessor in property.OtherMethods) { service.SetCanRename(accessor, false); } } } if (!found) { if (instrInfo.Item1) { context.Logger.LogFormat("WARN: Failed to find the accessors of attached dependency property '{0}' in type '{1}'.", name, declType.FullName); } else { context.Logger.LogFormat("WARN: Failed to find the CLR property of normal dependency property '{0}' in type '{1}'.", name, declType.FullName); } } } erred = false; foreach (Instruction instr in routedEvtRegInstrs) { int[] args = trace.TraceArguments(instr); if (args == null) { if (!erred) { context.Logger.LogFormat("WARN: Failed to extract routed event name in '{0}'.", method.FullName); } erred = true; continue; } Instruction ldstr = method.Body.Instructions[args[0]]; if (ldstr.OpCode.Code != Code.Ldstr) { if (!erred) { context.Logger.LogFormat("WARN: Failed to extract routed event name in '{0}'.", method.FullName); } erred = true; continue; } string name = (string)ldstr.Operand; TypeDef declType = method.DeclaringType; EventDef eventDef = null; if ((eventDef = declType.FindEvent(name)) == null) { context.Logger.LogFormat("WARN: Failed to find the CLR event of routed event '{0}' in type '{1}'.", name, declType.FullName); continue; } service.SetCanRename(eventDef, false); if (eventDef.AddMethod != null) { service.SetCanRename(eventDef.AddMethod, false); } if (eventDef.RemoveMethod != null) { service.SetCanRename(eventDef.RemoveMethod, false); } if (eventDef.InvokeMethod != null) { service.SetCanRename(eventDef.InvokeMethod, false); } if (eventDef.HasOtherMethods) { foreach (MethodDef accessor in eventDef.OtherMethods) { service.SetCanRename(accessor, false); } } } }
public void ExcludeTarget(ConfuserContext context, MethodDef method) { context.Annotations.Set(method, TargetExcluded, TargetExcluded); }
protected override void Execute(ConfuserContext context, ProtectionParameters parameters) { var moduleCtx = context.Annotations.Get <CEContext>(context.CurrentModule, ConstantProtection.ContextKey); if (!parameters.Targets.Any() || moduleCtx == null) { return; } var ldc = new Dictionary <object, List <Tuple <MethodDef, Instruction> > >(); var ldInit = new Dictionary <byte[], List <Tuple <MethodDef, Instruction> > >(new ByteArrayComparer()); // Extract constants ExtractConstants(context, parameters, moduleCtx, ldc, ldInit); // Encode constants moduleCtx.ReferenceRepl = new Dictionary <MethodDef, List <Tuple <Instruction, uint, IMethod> > >(); moduleCtx.EncodedBuffer = new List <uint>(); foreach (var entry in ldInit.WithProgress(context.Logger)) // Ensure the array length haven't been encoded yet { EncodeInitializer(moduleCtx, entry.Key, entry.Value); context.CheckCancellation(); } foreach (var entry in ldc.WithProgress(context.Logger)) { if (entry.Key is string) { EncodeString(moduleCtx, (string)entry.Key, entry.Value); } else if (entry.Key is int) { EncodeConstant32(moduleCtx, (uint)(int)entry.Key, context.CurrentModule.CorLibTypes.Int32, entry.Value); } else if (entry.Key is long) { EncodeConstant64(moduleCtx, (uint)((long)entry.Key >> 32), (uint)(long)entry.Key, context.CurrentModule.CorLibTypes.Int64, entry.Value); } else if (entry.Key is float) { var t = new RTransform(); t.R4 = (float)entry.Key; EncodeConstant32(moduleCtx, t.Lo, context.CurrentModule.CorLibTypes.Single, entry.Value); } else if (entry.Key is double) { var t = new RTransform(); t.R8 = (double)entry.Key; EncodeConstant64(moduleCtx, t.Hi, t.Lo, context.CurrentModule.CorLibTypes.Double, entry.Value); } else { throw new UnreachableException(); } context.CheckCancellation(); } ReferenceReplacer.ReplaceReference(moduleCtx, parameters); // compress var encodedBuff = new byte[moduleCtx.EncodedBuffer.Count * 4]; int buffIndex = 0; foreach (uint dat in moduleCtx.EncodedBuffer) { encodedBuff[buffIndex++] = (byte)((dat >> 0) & 0xff); encodedBuff[buffIndex++] = (byte)((dat >> 8) & 0xff); encodedBuff[buffIndex++] = (byte)((dat >> 16) & 0xff); encodedBuff[buffIndex++] = (byte)((dat >> 24) & 0xff); } Debug.Assert(buffIndex == encodedBuff.Length); encodedBuff = context.Registry.GetService <ICompressionService>().Compress(encodedBuff); context.CheckCancellation(); uint compressedLen = (uint)(encodedBuff.Length + 3) / 4; compressedLen = (compressedLen + 0xfu) & ~0xfu; var compressedBuff = new uint[compressedLen]; Buffer.BlockCopy(encodedBuff, 0, compressedBuff, 0, encodedBuff.Length); Debug.Assert(compressedLen % 0x10 == 0); // encrypt // uint dynamic_cp = EncryptionKey.Key; // 0x10 uint keySeed = moduleCtx.Random.NextUInt32(); var key = new uint[dynamic_cp]; uint state = keySeed; for (int i = 0; i < dynamic_cp; i++) { state ^= state >> 12; state ^= state << 25; state ^= state >> 27; key[i] = state; } var encryptedBuffer = new byte[compressedBuff.Length * 4]; buffIndex = 0; while (buffIndex < compressedBuff.Length) { uint[] enc = moduleCtx.ModeHandler.Encrypt(compressedBuff, buffIndex, key); for (int j = 0; j < dynamic_cp; j++) { key[j] ^= compressedBuff[buffIndex + j]; } Buffer.BlockCopy(enc, 0, encryptedBuffer, buffIndex * 4, (int)dynamic_cp * 4); buffIndex += (int)dynamic_cp; } Debug.Assert(buffIndex == compressedBuff.Length); moduleCtx.DataField.InitialValue = encryptedBuffer; moduleCtx.DataField.HasFieldRVA = true; moduleCtx.DataType.ClassLayout = new ClassLayoutUser(0, (uint)encryptedBuffer.Length); MutationHelper.InjectKeys(moduleCtx.InitMethod, new[] { 0, 1 }, new[] { encryptedBuffer.Length / 4, (int)keySeed }); MutationHelper.ReplacePlaceholder(moduleCtx.InitMethod, arg => { var repl = new List <Instruction>(); repl.AddRange(arg); repl.Add(Instruction.Create(OpCodes.Dup)); repl.Add(Instruction.Create(OpCodes.Ldtoken, moduleCtx.DataField)); repl.Add(Instruction.Create(OpCodes.Call, moduleCtx.Module.Import( typeof(RuntimeHelpers).GetMethod("InitializeArray")))); return(repl.ToArray()); }); }
public bool IsTargeted(ConfuserContext context, MethodDef method) { return(context.Annotations.Get <object>(method, Targeted) != null); }
protected override void Initialize(ConfuserContext context) { context.Registry.RegisterService(_ServiceId, typeof(IReferenceProxyService), this); }
/// <summary> /// Initializes a new instance of the <see cref="TraceService" /> class. /// </summary> /// <param name="context">The working context.</param> public TraceService(ConfuserContext context) { this.context = context; }
public bool UpdateNameReference(ConfuserContext context, INameService service) { rec.TypeFullName = sig.ReflectionFullName; return(true); }