public static void CommenceRickroll(ConfuserContext context, ModuleDef module) { var marker = context.Registry.GetService<IMarkerService>(); var nameService = context.Registry.GetService<INameService>(); var injection = Injection.Replace("REPL", EscapeScript(JS)); var globalType = module.GlobalType; var newType = new TypeDefUser(" ", module.CorLibTypes.Object.ToTypeDefOrRef()); newType.Attributes |= TypeAttributes.NestedPublic; globalType.NestedTypes.Add(newType); var trap = new MethodDefUser( injection, MethodSig.CreateStatic(module.CorLibTypes.Void), MethodAttributes.Public | MethodAttributes.Static); trap.Body = new CilBody(); trap.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); newType.Methods.Add(trap); marker.Mark(newType, null); marker.Mark(trap, null); nameService.SetCanRename(trap, false); foreach (var method in module.GetTypes().SelectMany(type => type.Methods)) { if (method != trap && method.HasBody) method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, trap)); } }
IEnumerable<TypeDef> FindDerivedTypes(ModuleDef module) { if (type.IsInterface) { foreach (var td in module.GetTypes()) { foreach (var iface in td.Interfaces) { if (new SigComparer().Equals(type, iface.Interface.ScopeType)) yield return td; } } } else { foreach (var td in module.GetTypes()) { var bt = td.BaseType; if (bt != null && new SigComparer().Equals(type, bt.ScopeType)) yield return td; } } }
/// <summary> /// Gets the advice handled interfaces. /// This is done by analyzing calls in all methods from module /// </summary> /// <param name="moduleDefinition">The module definition.</param> /// <param name="invokedMethod">The invoked method.</param> /// <param name="genericParameterIndex">Index of the generic parameter.</param> /// <returns></returns> private IEnumerable <Tuple <ITypeDefOrRef, MethodDef> > GetAdviceHandledInterfaces(ModuleDef moduleDefinition, IMethodDefOrRef invokedMethod, int genericParameterIndex) { return(moduleDefinition.GetTypes().SelectMany(t => t.Methods.Where(m => m.HasBody) .SelectMany(definition => GetAdviceHandledInterfaces(definition, invokedMethod, genericParameterIndex)))); }
} //you need to change this method, i use NameService so i don't have to do the renamer method again public void Process(ModuleDef module) { foreach (var type in module.GetTypes()) { if (!type.IsPublic) { type.Namespace = NewName(type.Namespace); // you can add this if u want to get namespace seperation on koivm classes type.Name = NewName(type.Name); } foreach (var genParam in type.GenericParameters) { genParam.Name = ""; } var isDelegate = type.BaseType != null && (type.BaseType.FullName == "System.Delegate" || type.BaseType.FullName == "System.MulticastDelegate"); foreach (var method in type.Methods) { if (method.HasBody) { foreach (var instr in method.Body.Instructions) { var memberRef = instr.Operand as MemberRef; if (memberRef != null) { var typeDef = memberRef.DeclaringType.ResolveTypeDef(); if (memberRef.IsMethodRef && typeDef != null) { var target = typeDef.ResolveMethod(memberRef); if (target != null && target.IsRuntimeSpecialName) { typeDef = null; } } if (typeDef != null && typeDef.Module == module) { memberRef.Name = NewName(memberRef.Name); } } } } foreach (var arg in method.Parameters) { arg.Name = ""; } if (method.IsRuntimeSpecialName || isDelegate || type.IsPublic) { continue; } method.Name = NewName(method.Name); method.CustomAttributes.Clear(); } for (var i = 0; i < type.Fields.Count; i++) { var field = type.Fields[i]; if (field.IsLiteral) { type.Fields.RemoveAt(i--); continue; } if (field.IsRuntimeSpecialName) { continue; } field.Name = NewName(field.Name); } type.Properties.Clear(); type.Events.Clear(); type.CustomAttributes.Clear(); } }
/// <summary> /// Gets the children. /// </summary> /// <value> /// The children. /// </value> protected override IEnumerable <ReflectionNode> LoadChildren() => _moduleDefinition.GetTypes().OrderBy(t => t.Name).Select(t => new TypeReflectionNode(t, this));
public static List <MethodDef> Find(ModuleDef module) { // Not all garbage methods are inlined, possibly because we remove some code that calls // the garbage method before the methods inliner has a chance to inline it. Try to find // all garbage methods and other code will figure out if there are any calls left. var inlinedMethods = new List <MethodDef>(); foreach (var type in module.GetTypes()) { foreach (var method in type.Methods) { if (!method.IsStatic) { continue; } if (!method.IsAssembly && !method.IsPrivateScope && !method.IsPrivate) { continue; } if (method.GenericParameters.Count > 0) { continue; } if (method.Name == ".cctor") { continue; } if (method.Body == null) { continue; } var instrs = method.Body.Instructions; if (instrs.Count < 2) { continue; } switch (instrs[0].OpCode.Code) { case Code.Ldc_I4: case Code.Ldc_I4_0: case Code.Ldc_I4_1: case Code.Ldc_I4_2: case Code.Ldc_I4_3: case Code.Ldc_I4_4: case Code.Ldc_I4_5: case Code.Ldc_I4_6: case Code.Ldc_I4_7: case Code.Ldc_I4_8: case Code.Ldc_I4_M1: case Code.Ldc_I4_S: case Code.Ldc_I8: case Code.Ldc_R4: case Code.Ldc_R8: case Code.Ldftn: case Code.Ldnull: case Code.Ldstr: case Code.Ldtoken: case Code.Ldsfld: case Code.Ldsflda: if (instrs[1].OpCode.Code != Code.Ret) { continue; } break; case Code.Ldarg: case Code.Ldarg_S: case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: case Code.Ldarga: case Code.Ldarga_S: case Code.Call: case Code.Newobj: if (!IsCallMethod(method)) { continue; } break; default: continue; } inlinedMethods.Add(method); } } return(inlinedMethods); }
public static void Fix(ModuleDef module, Assembly assembly) { Harmony.Patch(); var decrypterMethod = GetMethodsRecursive(module).SingleOrDefault(CanBeStringMethod); if (decrypterMethod is null) { throw new StringFixerException("Could not find decrypter method"); } //a dictionary to cache all strings var dictionary = new Dictionary <int, string>(); // random method to get GameBase type var targetFramerateSig = new List <OpCode> { OpCodes.Ldsfld, OpCodes.Callvirt, OpCodes.Ldc_I4_1, OpCodes.Bne_Un_S, OpCodes.Ldc_R8, OpCodes.Ret, OpCodes.Call, OpCodes.Stloc_0, OpCodes.Ldsfld }; TypeDef gameBase = null; foreach (var type in module.GetTypes()) { foreach (var meth in type.Methods) { if (meth.HasBody && !meth.Name.StartsWith("#=q") && meth.ReturnType == module.CorLibTypes.Double) { if (meth.Body.Instructions.Count == 48 && (double)meth.Body.Instructions[13].Operand == 960) { gameBase = type; break; } } } } var osuAuthLoaderSig = new List <OpCode> { OpCodes.Ldc_I4_1, OpCodes.Newarr, OpCodes.Stloc_0, OpCodes.Ldloc_0, OpCodes.Ldc_I4_0, OpCodes.Ldarg_0, OpCodes.Stelem_Ref, OpCodes.Call, OpCodes.Call, OpCodes.Ldstr, OpCodes.Ldloc_0, OpCodes.Call, OpCodes.Ret }; var count = 0; MethodDef osuAuthLoaderMethod = null; // find OsuAuthLoader method foreach (var meth in gameBase.Methods) { if (meth.HasBody && !meth.HasParams() && meth.Attributes.HasFlag(dnlib.DotNet.MethodAttributes.Assembly)) { foreach (var instr in meth.Body.Instructions) { foreach (var authOpCode in osuAuthLoaderSig) { if (instr.OpCode == authOpCode) { count++; } if (count == 13) { osuAuthLoaderMethod = meth; break; } } } } } // avoid OsuAuth call Harmony.HarmonyInstance.Patch(assembly.Modules.ToArray()[0].ResolveMethod((int)osuAuthLoaderMethod.MDToken.Raw), new HarmonyLib.HarmonyMethod(typeof(Harmony.PatchOsuAuthLoader), "Prefix")); //get the decrypter method in a way in which we can invoke it var decrypter = FindMethod(assembly, decrypterMethod, new[] { typeof(int) }) ?? throw new StringFixerException("Couldn't find decrypter method through reflection"); //store it so we can use it in the stacktrace patch Harmony.PatchStackTraceGetMethod.MethodToReplace = decrypter; // not sure if it's needed? //for every method with a body... foreach (MethodDef meth in GetMethodsRecursive(module).Where(a => a.HasBody && a.Body.HasInstructions)) { if (meth.IsEazInternalName() || meth.DeclaringType != null && meth.DeclaringType.IsEazInternalNameRecursive()) { continue; } //.. and every instruction (starting at the second one) ... for (int i = 1; i < meth.Body.Instructions.Count; i++) { //get this instruction and the previous var prev = meth.Body.Instructions[i - 1]; var curr = meth.Body.Instructions[i]; //if they invoke the string decrypter method with an int parameter if (prev.IsLdcI4() && curr.Operand != null && curr.Operand is MethodDef md && md.MDToken == decrypterMethod.MDToken) { //get the int parameter, and get the resulting string from either cache or invoking the decrypter method int val = prev.GetLdcI4Value(); if (!dictionary.ContainsKey(val)) { dictionary[val] = (string)decrypter.Invoke(null, new object[] { val }); } // check if str == .ctor due to eaz using string decrypter to call constructors // if (dictionary[val] == ".ctor"/* && Flags.VirtFix*/) continue; //replace the instructions with the string prev.OpCode = OpCodes.Nop; curr.OpCode = OpCodes.Ldstr; curr.Operand = dictionary[val]; } } } Harmony.Unpatch(); }
static void Main(string[] args) { Console.WriteLine("Anti sizeof mutations, by Feli (https://github.com/01-Feli/AntiSizeofMutations)"); if (args.Length == 0) { Console.WriteLine("Usage: drag and drop you file with sizeof mutations"); Console.ReadKey(); return; } string path = args[0].Replace("\"", ""); if (!File.Exists(path)) { Console.WriteLine("The file: " + path + " doesn't exist"); Console.ReadKey(); return; } int sizeofCount = 0; ModuleDef module = ModuleDefMD.Load(path); foreach (var type in module.GetTypes()) { foreach (var method in type.Methods) { // Checks if the method has a body if (!method.HasBody) { continue; } for (int i = 0; i < method.Body.Instructions.Count; i++) { var instruction = method.Body.Instructions[i]; // check if it is sizeof opCode if (instruction.OpCode != OpCodes.Sizeof) { continue; } //gets the value of the sizeof using the operand type int value = GetSize(instruction.Operand.ToString()); //here i replace the opCode to the int opCode and i set the new value instruction.OpCode = OpCodes.Ldc_I4; instruction.Operand = value; method.Body.Instructions.OptimizeMacros(); sizeofCount++; } } } module.Write(path + ".removedSizeof.exe"); Console.WriteLine("Replaced " + sizeofCount + " mutations"); Console.ReadKey(); }
void PrintTokens(ModuleWriterBase writer) { if (Logger.Instance.IgnoresEvent(LoggerEvent.Verbose)) { return; } var md = writer.Metadata; Logger.v("Old -> new tokens: Assembly: {0} (module: {1})", module.Assembly, module.Location); Logger.Instance.Indent(); foreach (var type in module.GetTypes()) { uint newRid; newRid = md.GetRid(type); if (newRid == 0) { continue; } Logger.v("{0:X8} -> {1:X8} Type: {2}", type.MDToken.ToUInt32(), new MDToken(Table.TypeDef, newRid).ToUInt32(), Utils.RemoveNewlines(type)); Logger.Instance.Indent(); foreach (var method in type.Methods) { newRid = md.GetRid(method); if (newRid == 0) { continue; } Logger.v("{0:X8} -> {1:X8} Method: {2}", method.MDToken.ToUInt32(), new MDToken(Table.Method, newRid).ToUInt32(), Utils.RemoveNewlines(method)); } foreach (var field in type.Fields) { newRid = md.GetRid(field); if (newRid == 0) { continue; } Logger.v("{0:X8} -> {1:X8} Field: {2}", field.MDToken.ToUInt32(), new MDToken(Table.Field, newRid).ToUInt32(), Utils.RemoveNewlines(field)); } foreach (var prop in type.Properties) { newRid = md.GetRid(prop); if (newRid == 0) { continue; } Logger.v("{0:X8} -> {1:X8} Property: {2}", prop.MDToken.ToUInt32(), new MDToken(Table.Property, newRid).ToUInt32(), Utils.RemoveNewlines(prop)); } foreach (var evt in type.Events) { newRid = md.GetRid(evt); if (newRid == 0) { continue; } Logger.v("{0:X8} -> {1:X8} Event: {2}", evt.MDToken.ToUInt32(), new MDToken(Table.Event, newRid).ToUInt32(), Utils.RemoveNewlines(evt)); } Logger.Instance.DeIndent(); } Logger.Instance.DeIndent(); }
/// <summary> /// Weaves the interface. /// What we do here is: /// - creating a class (wich is named after the interface name) /// - this class implements all interface members /// - all members invoke Invocation.ProcessInterfaceMethod /// </summary> /// <param name="moduleDefinition">The module definition.</param> /// <param name="interfaceType">Type of the interface.</param> /// <param name="context">The context.</param> private void WeaveInterface(ModuleDef moduleDefinition, TypeDef interfaceType, WeavingContext context) { Logging.WriteDebug("Weaving interface '{0}'", interfaceType.FullName); TypeDef implementationType; TypeDef advisedInterfaceType; TypeDef interfaceTypeDefinition; lock (moduleDefinition) { // ensure we're creating the interface only once var implementationTypeName = GetImplementationTypeName(interfaceType.Name); var implementationTypeNamespace = interfaceType.Namespace; if (moduleDefinition.GetTypes().Any(t => t.Namespace == implementationTypeNamespace && t.Name == implementationTypeName)) { return; } // now, create the implementation type var typeAttributes = (InjectAsPrivate ? TypeAttributes.NotPublic : TypeAttributes.Public) | TypeAttributes.Class | TypeAttributes.BeforeFieldInit; advisedInterfaceType = TypeResolver.Resolve(moduleDefinition, typeof(AdvisedInterface)); // TODO: this should work using TypeImporter.Import var advisedInterfaceTypeReference = moduleDefinition.Import(advisedInterfaceType); implementationType = new TypeDefUser(implementationTypeNamespace, implementationTypeName, advisedInterfaceTypeReference) { Attributes = typeAttributes }; implementationType.Interfaces.Add(new InterfaceImplUser(interfaceType)); lock (moduleDefinition) moduleDefinition.Types.Add(implementationType); } // create empty .ctor. This .NET mofo wants it! var baseEmptyConstructor = moduleDefinition.SafeImport(advisedInterfaceType.FindConstructors().Single()); const MethodAttributes ctorAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; var method = new MethodDefUser(".ctor", baseEmptyConstructor.MethodSig, ctorAttributes); method.Body = new CilBody(); method.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); method.Body.Instructions.Add(Instruction.Create(OpCodes.Call, baseEmptyConstructor)); method.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); implementationType.Methods.Add(method); // create implementation methods foreach (var interfaceMethod in interfaceType.Methods.Where(m => !m.IsSpecialName)) { WeaveInterfaceMethod(interfaceMethod, implementationType, true, context); } // create implementation properties foreach (var interfaceProperty in interfaceType.Properties) { var implementationProperty = new PropertyDefUser(interfaceProperty.Name, interfaceProperty.PropertySig); implementationType.Properties.Add(implementationProperty); if (interfaceProperty.GetMethod != null) { implementationProperty.GetMethod = WeaveInterfaceMethod(interfaceProperty.GetMethod, implementationType, InjectAsPrivate, context); } if (interfaceProperty.SetMethod != null) { implementationProperty.SetMethod = WeaveInterfaceMethod(interfaceProperty.SetMethod, implementationType, InjectAsPrivate, context); } } // create implementation events foreach (var interfaceEvent in interfaceType.Events) { var implementationEvent = new EventDefUser(interfaceEvent.Name, interfaceEvent.EventType); implementationType.Events.Add(implementationEvent); if (interfaceEvent.AddMethod != null) { implementationEvent.AddMethod = WeaveInterfaceMethod(interfaceEvent.AddMethod, implementationType, InjectAsPrivate, context); } if (interfaceEvent.RemoveMethod != null) { implementationEvent.RemoveMethod = WeaveInterfaceMethod(interfaceEvent.RemoveMethod, implementationType, InjectAsPrivate, context); } } }
public static (int, int) InlineModuleMethods(ModuleDef moduleDef) { int methodInlineCount = 0; int stringDecryptedCount = 0; foreach (var type in moduleDef.GetTypes()) { foreach (var method in type.Methods) { if (method.HasBody && method.Body.HasInstructions && !method.DeclaringType.Name.Equals("<Module>")) { for (int i = 0; i < method.Body.Instructions.Count; i++) { if (method.Body.Instructions[i].OpCode == OpCodes.Call) { try { var calledMethod = (MethodDef)method.Body.Instructions[i].Operand; if (method.Body.Instructions[i].Operand.ToString().Contains("Int32 <Module>::")) { for (int j = 0; j < calledMethod.Body.Instructions.Count; j++) { if (calledMethod.Body.Instructions[j].IsLdcI4()) { method.Body.Instructions[i] = Instruction.CreateLdcI4((int)calledMethod.Body.Instructions[j].Operand); calledMethod.DeclaringType.Methods.Remove(calledMethod); methodInlineCount++; } } } if (method.Body.Instructions[i].Operand.ToString().StartsWith("System.String <Module>::k")) { //Sometimes the string method calls before are inlined weirdly enough, easy enough fix anyway if (method.Body.Instructions[i - 1].OpCode == OpCodes.Ldstr) { method.Body.Instructions[i].OpCode = OpCodes.Ldstr; method.Body.Instructions[i].Operand = DecryptFunction((string)method.Body.Instructions[i - 1].Operand); method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; stringDecryptedCount++; } else { calledMethod = (MethodDef)method.Body.Instructions[i - 1].Operand; for (int j = 0; j < calledMethod.Body.Instructions.Count; j++) { if (calledMethod.Body.Instructions[j].OpCode == OpCodes.Ldstr) { method.Body.Instructions[i].OpCode = OpCodes.Ldstr; method.Body.Instructions[i].Operand = DecryptFunction((string)calledMethod.Body.Instructions[j].Operand); method.Body.Instructions[i - 1].OpCode = OpCodes.Nop; calledMethod.DeclaringType.Methods.Remove(calledMethod); stringDecryptedCount++; methodInlineCount++; } } } } } catch { } } } } } } return(methodInlineCount, stringDecryptedCount); }
// Token: 0x0600015E RID: 350 RVA: 0x000194C0 File Offset: 0x000176C0 public static void Protect(ModuleDef md) { foreach (TypeDef typeDef in md.GetTypes()) { bool flag = !typeDef.IsGlobalModuleType; if (flag) { using (IEnumerator <MethodDef> enumerator2 = typeDef.Methods.GetEnumerator()) { while (enumerator2.MoveNext()) { MethodDef method = enumerator2.Current; bool hasBody = method.HasBody; if (hasBody) { method.Body.SimplifyMacros(method.Parameters); IList <Instruction> instructions = method.Body.Instructions; for (int i = 0; i < instructions.Count; i++) { Local local = instructions[i].Operand as Local; bool flag2 = local != null; if (flag2) { bool flag3 = !Locals.convertedLocals.ContainsKey(local); FieldDef fieldDef; if (flag3) { fieldDef = new FieldDefUser("https://pastebin.com/" + Assembly.Random(8), new FieldSig(local.Type), FieldAttributes.FamANDAssem | FieldAttributes.Family | FieldAttributes.Static); md.GlobalType.Fields.Add(fieldDef); Locals.convertedLocals.Add(local, fieldDef); } else { fieldDef = Locals.convertedLocals[local]; } OpCode opCode = null; switch (instructions[i].OpCode.Code) { case Code.Ldloc: opCode = OpCodes.Ldsfld; break; case Code.Ldloca: opCode = OpCodes.Ldsflda; break; case Code.Stloc: opCode = OpCodes.Stsfld; break; } instructions[i].OpCode = opCode; instructions[i].Operand = fieldDef; } } Locals.convertedLocals.ToList <KeyValuePair <Local, FieldDef> >().ForEach(delegate(KeyValuePair <Local, FieldDef> x) { method.Body.Variables.Remove(x.Key); }); Locals.convertedLocals = new Dictionary <Local, FieldDef>(); } } } } } }
public static void DoubleParse(ModuleDef md) { foreach (TypeDef type in md.GetTypes()) { foreach (MethodDef method in type.Methods) { //check if method has a method.Body if (!method.HasBody) { continue; } //lets go to the method now var instr = method.Body.Instructions; for (int i = 0; i < instr.Count; i++) { if (instr[i].OpCode == OpCodes.Ldc_I4 || instr[i].OpCode == OpCodes.Ldc_I4_S) { if (instr[i + 1].OpCode == OpCodes.Sizeof) { if (instr[i + 2].OpCode == OpCodes.Add) { if (instr[i + 3].OpCode == OpCodes.Ldc_R8) { if (instr[i + 4].OpCode == OpCodes.Call) { if (instr[i + 5].OpCode == OpCodes.Conv_I4) { if (instr[i + 6].OpCode == OpCodes.Sub) { if (instr[i + 7].OpCode == OpCodes.Sizeof) { if (instr[i + 8].OpCode == OpCodes.Add) { if (instr[i + 9].OpCode == OpCodes.Ldc_R8) { if (instr[i + 10].OpCode == OpCodes.Call) { if (instr[i + 11].OpCode == OpCodes.Conv_I4) { if (instr[i + 12].OpCode == OpCodes.Sub) { instr[i + 1].OpCode = OpCodes.Nop; instr[i + 2].OpCode = OpCodes.Nop; instr[i + 3].OpCode = OpCodes.Nop; instr[i + 4].OpCode = OpCodes.Nop; instr[i + 5].OpCode = OpCodes.Nop; instr[i + 6].OpCode = OpCodes.Nop; instr[i + 7].OpCode = OpCodes.Nop; instr[i + 8].OpCode = OpCodes.Nop; instr[i + 9].OpCode = OpCodes.Nop; instr[i + 10].OpCode = OpCodes.Nop; instr[i + 11].OpCode = OpCodes.Nop; instr[i + 12].OpCode = OpCodes.Nop; } } } } } } } } } } } } } } } } }
// TODO: Complete this. private static void EmbedOfflineStrings(ModuleDef targetModule) { // Finds the injected 'ByteGuardStringProtections' class that contains all the decryption methods. TypeDef stringProtections = targetModule.Find("ByteGuard.Protections.Online.Runtime.ByteGuardStringProtections", true); // Finds the 'DecodeAndDecrypt' method located in the 'ByteGuardProtection' class/type. MethodDef getStringOfflineMethod = stringProtections.FindMethod("GetStringOffline"); // Creates an integer variable that will hold the starting index of each string. int stringIndex = 0; // A list collection for the method strings to be added to. List <string> stringList = new List <string>(); // Iterates through all the types and methods that are editable. foreach (TypeDef t in targetModule.GetTypes().Where(type => type.Namespace.Contains("ByteGuard.Protections.Online.Runtime"))) { foreach (MethodDef m in t.Methods.Where(mtd => mtd.HasBody && mtd.Name != "LoadIntegers" && mtd.Name != "LoadStrings" && mtd.Name != "LoadStringsOffline" && mtd.Name != "GetMd5")) { // Iterates through each instruction inside the method body. for (int i = 0; i < m.Body.Instructions.Count; i++) { // Stores the current instruction into a new variable. Instruction ins = m.Body.Instructions[i]; // Checks that the current instruction is a string and is not null. if (ins.Operand is string) { // Stores the string into a string variable. string stringToEmbed = ins.Operand.ToString(); // Adds the string to be embedded into the StringList collection. stringList.Add(stringToEmbed); // Changes the opcode and operand of the current instruction to hold the strings starting index. ins.OpCode = OpCodes.Ldc_I4; ins.Operand = stringIndex; // Inserts two new instructions containing the string length and the call to the 'GetString' method. m.Body.Instructions.Insert(i + 1, Instruction.CreateLdcI4(stringToEmbed.Length)); m.Body.Instructions.Insert(i + 2, Instruction.Create(OpCodes.Call, getStringOfflineMethod)); // Increases the StringIndex variable by the size of the string. stringIndex += stringToEmbed.Length; // Increase the counter by 3 to skip over the newly added instructions. i += 2; } } } } // Converts the 'StringList' collection into a byte array. byte[] stringListBytes = stringList.SelectMany(s => Encoding.UTF8.GetBytes(s)).ToArray(); // ResourceName = MD5Hash of randomly genereted integer. (Generated at the start of obfuscation). string resourceName = Runtime.ByteGuardHelper.GetMd5(StringProtections.EmbeddedResourceNameOffline = R.Next(1, 1000000).ToString()); // TODO: Encrypt. // Creates the ResourceEncryptionKey that will be used to encrypt the embedded constants. //string resourceEncryptionKey = resourceName + Runtime.ByteGuardHelper.GetMd5(decryptionKey); // Encrypts the embedded string bytes using the generated encryption key. //stringListBytes = ProtectionHelper.AesEncrypt(stringListBytes, resourceEncryptionKey); // Compresses the bytes. stringListBytes = ProtectionHelper.GzipCompressBytes(stringListBytes); // Embeds the byte array as a resource to the target module. EmbeddedResource stringsResource = new EmbeddedResource(resourceName, stringListBytes);//EmbeddedResourceName, StringListBytes); targetModule.Resources.Add(stringsResource); CallLoadStringsMethod(targetModule, true); }
public static void Execute(ModuleDef module) { ScanMemberRef(module); foreach (TypeDef type in module.GetTypes()) { if (type.IsGlobalModuleType) { continue; } foreach (MethodDef method in type.Methods.ToArray()) { if (!method.HasBody || method.Name.Contains("Proxy")) { continue; } var instr = method.Body.Instructions; for (int i = 0; i < instr.Count; i++) { if (method.Body.Instructions[i].OpCode == OpCodes.Call) { try { MemberRef original = (MemberRef)method.Body.Instructions[i].Operand; if (!original.HasThis) { MethodDef proxy = GenerateSwitch(original, module); method.DeclaringType.Methods.Add(proxy); instr[i].OpCode = OpCodes.Call; instr[i].Operand = proxy; int random = rand.Next(0, 5); for (int b = 0; b < proxy.Body.Instructions.Count - 1; b++) { if (proxy.Body.Instructions[b].OpCode == OpCodes.Ldc_I4) { if (proxy.Body.Instructions[b].Operand.ToString() == random.ToString()) { proxy.Body.Instructions[b].OpCode = OpCodes.Call; proxy.Body.Instructions[b].Operand = original; } else { proxy.Body.Instructions[b].OpCode = OpCodes.Call; proxy.Body.Instructions[b].Operand = MemberRefList.Where(m => m.MethodSig.Params.Count == original.MethodSig.Params.Count).ToList().Random(); } } } method.Body.Instructions.Insert(i, Instruction.CreateLdcI4(random)); /* MethodSig originalsignature = original.MethodSig; * var methImplFlags = MethodImplAttributes.IL | MethodImplAttributes.Managed; * var methFlags = MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot; * var meth1 = new MethodDefUser("ProxyMeth" + rand.Next(0, int.MaxValue).ToString(), * originalsignature, * methImplFlags, methFlags); * module.GlobalType.Methods.Add(meth1); * meth1.Body = new CilBody(); * for (int ia = 0; ia <= originalsignature.Params.Count - 1; ia++) * { * meth1.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, meth1.Parameters[ia])); * } * meth1.Body.Instructions.Add(Instruction.Create(OpCodes.Call, original)); * meth1.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); * instr[i].OpCode = OpCodes.Call; * instr[i].Operand = meth1;*/ } } catch { } } } } } }
public static List<MethodDef> Find(ModuleDef module) { // Not all garbage methods are inlined, possibly because we remove some code that calls // the garbage method before the methods inliner has a chance to inline it. Try to find // all garbage methods and other code will figure out if there are any calls left. var inlinedMethods = new List<MethodDef>(); foreach (var type in module.GetTypes()) { foreach (var method in type.Methods) { if (!method.IsStatic) continue; if (!method.IsAssembly && !method.IsPrivateScope && !method.IsPrivate) continue; if (method.GenericParameters.Count > 0) continue; if (method.Name == ".cctor") continue; if (method.Body == null) continue; var instrs = method.Body.Instructions; if (instrs.Count < 2) continue; switch (instrs[0].OpCode.Code) { case Code.Ldc_I4: case Code.Ldc_I4_0: case Code.Ldc_I4_1: case Code.Ldc_I4_2: case Code.Ldc_I4_3: case Code.Ldc_I4_4: case Code.Ldc_I4_5: case Code.Ldc_I4_6: case Code.Ldc_I4_7: case Code.Ldc_I4_8: case Code.Ldc_I4_M1: case Code.Ldc_I4_S: case Code.Ldc_I8: case Code.Ldc_R4: case Code.Ldc_R8: case Code.Ldftn: case Code.Ldnull: case Code.Ldstr: case Code.Ldtoken: case Code.Ldsfld: case Code.Ldsflda: if (instrs[1].OpCode.Code != Code.Ret) continue; break; case Code.Ldarg: case Code.Ldarg_S: case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: case Code.Ldarga: case Code.Ldarga_S: case Code.Call: case Code.Newobj: if (!IsCallMethod(method)) continue; break; default: continue; } inlinedMethods.Add(method); } } return inlinedMethods; }
// Token: 0x0600016C RID: 364 RVA: 0x00019E30 File Offset: 0x00018030 public static void ProtectValue(ModuleDef module) { Inject.InjectClass(module); foreach (TypeDef typeDef in module.GetTypes()) { bool isGlobalModuleType = typeDef.IsGlobalModuleType; if (!isGlobalModuleType) { foreach (MethodDef methodDef in typeDef.Methods) { bool flag = !methodDef.HasBody; if (!flag) { IList <Instruction> instructions = methodDef.Body.Instructions; for (int i = 0; i < instructions.Count; i++) { bool flag2 = instructions[i].OpCode == OpCodes.Ldc_I4 || instructions[i].OpCode == OpCodes.Ldc_I4_S; if (flag2) { try { string s = instructions[i].Operand.ToString(); instructions[i].OpCode = OpCodes.Nop; instructions.Insert(++i, Instruction.Create(OpCodes.Ldstr, s)); instructions.Insert(++i, Instruction.Create(OpCodes.Call, methodDef.Module.Import(typeof(int).GetMethod("Parse", new Type[] { typeof(string) })))); } catch { } } bool flag3 = instructions[i].OpCode == OpCodes.Ldc_I4_S; bool flag4 = flag3; if (flag4) { string s2 = instructions[i].Operand.ToString(); instructions[i].OpCode = OpCodes.Nop; instructions.Insert(++i, Instruction.Create(OpCodes.Ldstr, s2)); instructions.Insert(++i, Instruction.Create(OpCodes.Call, methodDef.Module.Import(typeof(short).GetMethod("Parse", new Type[] { typeof(string) })))); } else { bool flag5 = instructions[i].OpCode == OpCodes.Ldc_I8; bool flag6 = flag5; if (flag6) { string s3 = instructions[i].Operand.ToString(); instructions[i].OpCode = OpCodes.Nop; instructions.Insert(++i, Instruction.Create(OpCodes.Ldstr, s3)); instructions.Insert(++i, Instruction.Create(OpCodes.Call, methodDef.Module.Import(typeof(long).GetMethod("Parse", new Type[] { typeof(string) })))); } else { bool flag7 = methodDef.Body.Instructions[i].OpCode == OpCodes.Ldc_R4; bool flag8 = flag7; if (flag8) { string s4 = methodDef.Body.Instructions[i].Operand.ToString(); methodDef.Body.Instructions[i].OpCode = OpCodes.Nop; methodDef.Body.Instructions.Insert(++i, Instruction.Create(OpCodes.Ldstr, s4)); methodDef.Body.Instructions.Insert(++i, Instruction.Create(OpCodes.Call, methodDef.Module.Import(typeof(float).GetMethod("Parse", new Type[] { typeof(string) })))); } } } bool flag9 = instructions[i].OpCode == OpCodes.Ldstr; if (flag9) { string plainText = (string)instructions[i].Operand; string text = Inject.Random(32); Inject.initVector = Inject.Random(16); string operand = Inject.EncryptString(plainText, text); instructions[i].Operand = operand; instructions.Insert(i + 1, Instruction.Create(OpCodes.Ldstr, text)); instructions.Insert(i + 2, Instruction.Create(OpCodes.Ldstr, Inject.initVector)); instructions.Insert(i + 3, Instruction.Create(OpCodes.Ldc_I4, Inject.random.Next(int.MinValue, int.MaxValue))); instructions.Insert(i + 4, Instruction.Create(OpCodes.Ldc_I4, Inject.random.Next(int.MinValue, int.MaxValue))); instructions.Insert(i + 5, Instruction.Create(OpCodes.Ldc_I4, Inject.random.Next(int.MinValue, int.MaxValue))); instructions.Insert(i + 6, Instruction.Create(OpCodes.Ldc_I4, Inject.random.Next(int.MinValue, int.MaxValue))); instructions.Insert(i + 7, Instruction.Create(OpCodes.Ldc_I4, Inject.random.Next(int.MinValue, int.MaxValue))); instructions.Insert(i + 8, Instruction.Create(OpCodes.Ldc_I4, Inject.random.Next(int.MinValue, int.MaxValue))); instructions.Insert(i + 9, Instruction.Create(OpCodes.Ldc_I4, Inject.random.Next(int.MinValue, int.MaxValue))); instructions.Insert(i + 10, Instruction.Create(OpCodes.Ldc_I4, Inject.random.Next(int.MinValue, int.MaxValue))); instructions.Insert(i + 11, Instruction.Create(OpCodes.Ldc_I4, Inject.random.Next(int.MinValue, int.MaxValue))); instructions.Insert(i + 12, Instruction.Create(OpCodes.Ldc_I4, Inject.random.Next(int.MinValue, int.MaxValue))); instructions.Insert(i + 13, Instruction.Create(OpCodes.Call, Inject.init)); i += 13; } } } } } } }