/// <summary> /// Generates the xor decryption method. /// </summary> /// <param name="assembly">The assembly.</param> /// <param name="body">The body.</param> private static void GenerateXorDecryptionMethod(AssemblyDefinition assembly, MethodBody body) { var worker = body.GetILProcessor(); //Generate the decryption method //Since this is XOR it is the same as the encryption method //In reality its a bit of a joke calling this encryption as its really //just obfusaction /* char[] characters = value.ToCharArray(); for (int i = 0; i < characters.Length; i++) { characters[i] = (char)(characters[i] ^ salt); } return new String(characters); */ //Declare a local to store the char array body.InitLocals = true; body.Method.AddLocal(typeof(char[])); body.Method.AddLocal(typeof(int)); body.Method.AddLocal(typeof(string)); body.Method.AddLocal(typeof(bool)); //Start with a nop worker.Append(worker.Create(OpCodes.Nop)); //Load the first argument into the register Instruction ldArg0 = worker.Create(OpCodes.Ldarg_0); worker.Append(ldArg0); //Call ToCharArray on this -- need to find it first var toCharArrayMethodRef = assembly.Import(typeof(string).GetMethod("ToCharArray", Type.EmptyTypes)); //Import the method first toCharArrayMethodRef = body.ImportMethod(toCharArrayMethodRef); Instruction toCharArray = worker.Create(OpCodes.Callvirt, toCharArrayMethodRef); worker.Append(toCharArray); //Store it in the first local Instruction stLoc0 = worker.Create(OpCodes.Stloc_0); worker.Append(stLoc0); //Set up the loop worker.Append(worker.Create(OpCodes.Ldc_I4_0)); Instruction stLoc1 = worker.Create(OpCodes.Stloc_1); worker.Append(stLoc1); //We'll insert a br.s here later.... //Insert another nop and do the rest of our loop Instruction loopNop = worker.Create(OpCodes.Nop); worker.Append(loopNop); worker.Append(worker.Create(OpCodes.Ldloc_0)); worker.Append(worker.Create(OpCodes.Ldloc_1)); worker.Append(worker.Create(OpCodes.Ldloc_0)); worker.Append(worker.Create(OpCodes.Ldloc_1)); worker.Append(worker.Create(OpCodes.Ldelem_U2)); //Load the array worker.Append(worker.Create(OpCodes.Ldarg_1)); worker.Append(worker.Create(OpCodes.Xor)); //Do the xor worker.Append(worker.Create(OpCodes.Conv_U2)); worker.Append(worker.Create(OpCodes.Stelem_I2)); //Store back in the array worker.Append(worker.Create(OpCodes.Nop)); worker.Append(worker.Create(OpCodes.Ldloc_1)); worker.Append(worker.Create(OpCodes.Ldc_I4_1)); worker.Append(worker.Create(OpCodes.Add)); worker.Append(worker.Create(OpCodes.Stloc_1)); Instruction ldLoc = worker.Create(OpCodes.Ldloc_1); worker.Append(ldLoc); //Link to this line from an earlier statement worker.InsertAfter(stLoc1, worker.Create(OpCodes.Br_S, ldLoc)); worker.Append(worker.Create(OpCodes.Ldloc_0)); worker.Append(worker.Create(OpCodes.Ldlen)); worker.Append(worker.Create(OpCodes.Conv_I4)); worker.Append(worker.Create(OpCodes.Clt)); //i < array.Length worker.Append(worker.Create(OpCodes.Stloc_3)); worker.Append(worker.Create(OpCodes.Ldloc_3)); worker.Append(worker.Create(OpCodes.Brtrue_S, loopNop)); //Do the loop //Return a new string worker.Append(worker.Create(OpCodes.Ldloc_0)); //Find the constructor we want to use MethodReference constructor = assembly.Import(typeof(string).GetConstructor(new [] { typeof(char[])})); constructor = body.ImportMethod(constructor); worker.Append(worker.Create(OpCodes.Newobj, constructor)); Instruction stloc2 = worker.Create(OpCodes.Stloc_2); worker.Append(stloc2); Instruction ldloc2 = worker.Create(OpCodes.Ldloc_2); worker.Append(ldloc2); worker.InsertAfter(stloc2, worker.Create(OpCodes.Br_S, ldloc2)); worker.Append(worker.Create(OpCodes.Ret)); }