private static void AgileDynamicStringDecryption() { // Find namspace empty with class "<AgileDotNetRT>" var agileDotNetRt = _moduleDefMd.Types.First(t => t.Namespace == string.Empty && t.Name == "<AgileDotNetRT>"); // Find a method in the class that has only one parameter with the parameter type String and the return value type String var decryptionMethod = agileDotNetRt.Methods.First(m => m.Parameters.Count == 1 && m.Parameters[0].Type.TypeName == "String" && m.ReturnType.TypeName == "String"); // Convert dnlib's MethodDef to MethodBase in .NET reflection var decryptor = _module.ResolveMethod(decryptionMethod.MDToken.ToInt32()); //Looping through all methods in that type and checking if method have body (instructions) foreach (var method in _moduleDefMd.EnumerateAllMethodDefs().Where(x => x.HasBody)) { var instr = method.Body.Instructions; for (var i = 0; i < instr.Count; i++) { if (instr[i].OpCode == OpCodes.Call && instr[i].Operand == decryptionMethod && instr[i - 1].OpCode == OpCodes.Ldstr) { instr[i].OpCode = OpCodes.Nop; instr[i].Operand = null; instr[i - 1].Operand = decryptor.Invoke(null, new[] { instr[i - 1].Operand }); _amount++; } } } // remove decryption method from the assembly _moduleDefMd.Types.Remove(decryptionMethod.DeclaringType); Console.WriteLine("[^] Removed junk : {0} class", decryptionMethod.DeclaringType); }