Mono.Cecil рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ MSIL рдХреЛрдб рдХреЛ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреА рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдореЗрдВ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдирд╛ред рдиреЗрдЯ рдореЗрдВ рдПрдУрдкреА рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛

рдкрд░рд┐рдЪрдп



рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рдореМрдЬреВрджрд╛ .NET рдЕрд╕реЗрдВрдмрд▓реА рдореЗрдВ рдХреИрд╕реЗ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ рдХреИрд╕реЗ рдкрд╣рд▓реВ-рдЙрдиреНрдореБрдЦ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред рд▓реЗрдЦ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдХреЛрдб рдПрдХ рд╡рд┐рдЪрд╛рд░ рд╡реНрдпрдХреНрдд рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реИред



рдХрдИ .NET рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рдХрд┐рд╕реА рдЕрдиреНрдп рдЕрд╕реЗрдВрдмрд▓реА рдХреА рд╡рд╕реНрддреБрдУрдВ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд░рд┐рдлреНрд▓реЗрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред System.Reflection рд╕реЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рдЕрд╕реЗрдВрдмрд▓реА рдореЗрдВ рдХрдИ .NET рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрдирдХреЗ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЙрди рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рдЕрдиреНрдп рдХреНрд▓рд╛рд╕ рдХреЗ рдирд┐рдЬреА рддрд░реАрдХреЗ)ред рд▓реЗрдХрд┐рди рдкрд░рд╛рд╡рд░реНрддрди рдХреЗ рдЙрдкрдпреЛрдЧ рдХреА рдЕрдкрдиреА рд╕реАрдорд╛рдПрдБ рд╣реИрдВ рдФрд░ рдЗрд╕рдХрд╛ рдореБрдЦреНрдп рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ рдЬрд┐рд╕ рдбреЗрдЯрд╛ рдкрд░ рдЖрдк рдкрд░рд╛рд╡рд░реНрддрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдЙрд╕реЗ рдЕрднреА рднреА рдХреЛрдб рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рдЬрд┐рд╕ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдореЗрдВ рд░рд┐рдлреНрд▓реЗрдХреНрд╢рди рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЙрд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдХреЛрдбрдЕрд╢реЗрд╕рд┐рд╕рд┐рдЯреА рдЕрдкрд╡рд╛рдж рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИред рдЙрд╕реА рдХрд╛рд░рдг рд╕реЗ, рдкрд░рд╛рд╡рд░реНрддрди рдмрд╣реБрдд рдзреАрдорд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдорд╛рдирдХ рдкрд░рд╛рд╡рд░реНрддрди рдЖрдкрдХреЛ рдореМрдЬреВрджрд╛ рд╡рд┐рдзрд╛рдирд╕рднрд╛рдУрдВ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдирдП рд▓реЛрдЧреЛрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдмрдЪрд╛рддрд╛ рд╣реИред



Mono.Cecil



рдПрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореБрдлреНрдд рдЦреБрд▓рд╛ рд╕реНрд░реЛрдд рдкреБрд╕реНрддрдХрд╛рд▓рдп Mono.Cecil рджреНрд╡рд╛рд░рд╛ рдХреА рдкреЗрд╢рдХрд╢ рдХреА рд╣реИред Mono.Cecil рджреГрд╖реНрдЯрд┐рдХреЛрдг рдФрд░ рдкреНрд░рддрд┐рдмрд┐рдВрдм рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдмреАрдЪ рдореБрдЦреНрдп рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдмрд╛рдЗрдЯ рдХреА рдПрдХ рдзрд╛рд░рд╛ рдХреЗ рд░реВрдк рдореЗрдВ NET рдЕрд╕реЗрдВрдмрд▓реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЕрд╕реЗрдВрдмрд▓реА рдХреЛ рд▓реЛрдб рдХрд░рддреЗ рд╕рдордп, Mono.Cecil рдкреАрдИ рд╣реЗрдбрд░, рд╕реАрдПрд▓рдЖрд░ рд╣реЗрдбрд░, рд╡рд░реНрдЧреЛрдВ рдФрд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдордПрд╕рдЖрдИрдПрд▓ рдХреЛрдб, рдЖрджрд┐ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИред рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдмрд╛рдЗрдЯ рд╕реНрдЯреНрд░реАрдо рдХреЗ рд╕рд╛рде рд╕реАрдзреЗ рдХрд╛рдо рдХрд░рдирд╛ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЗрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреА рдорджрдж рд╕реЗ, рдЖрдк рдЕрдкрдиреА рдЗрдЪреНрдЫрд╛рдиреБрд╕рд╛рд░ рдореМрдЬреВрджрд╛ рдЕрд╕реЗрдВрдмрд▓реА рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рд╕реАрдорд╛ рдХреЗ рднреАрддрд░)ред



рдЖрдк рдпрд╣рд╛рдВ Mono.Cecil рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ред



рддреБрд░рдВрдд, рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдПрдХ рдордЬрдмреВрдд рдирд╛рдо рдХреЗ рд╕рд╛рде рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд┐рдП рдЧрдП рддреГрддреАрдп-рдкрдХреНрд╖ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЗ рдПрдХ рд╕рдВрд╢реЛрдзрди рд╕реЗ рд╕рднреА рдЖрдЧрд╛рдореА рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд╕рд╛рде рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд╛ рдПрдХ рд░реАрд╕реЗрдЯ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рд╕рдВрд╢реЛрдзрди рдХреЗ рдмрд╛рдж, рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдЙрд╕реА рдХреБрдВрдЬреА рдХреЗ рд╕рд╛рде, рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рд╣реИ, рдпрд╛ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде - рдпрджрд┐, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЛ рдЬреАрдПрд╕реА рдореЗрдВ рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ)ред



рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдЙрджрд╛рд╣рд░рдг



рдХреЗрд╡рд▓ Mono.Cecil рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдмрд┐рдирд╛ рдХреБрдЫ рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдПрдХ рддреГрддреАрдп-рдкрдХреНрд╖ рдЕрд╕реЗрдВрдмрд▓реА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реИред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕реНрд░реЛрдд рдХреЛрдб рддрдХ рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрдВрд╕реЛрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрджреЗрд╢ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░реЗ рдЬрдм рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗред рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо рд▓рдХреНрд╖реНрдп рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рд░рд╛рд╕реНрддрд╛ рдкрд╛рд╕ рдХрд░реЗрдВрдЧреЗ:



using Mono.Cecil; using Mono.Cecil.Cil; class Program { static void Main(string[] args) { if (args.Length == 0) return; string assemblyPath = args[0]; //     Mono.Cecil var assembly = AssemblyDefinition.ReadAssembly(assemblyPath); //   Console.WriteLine,    Reflection var writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }); //    ,  Reflection,    Mono.Cecil var writeLineRef = assembly.MainModule.Import(writeLineMethod); foreach (var typeDef in assembly.MainModule.Types) { foreach (var method in typeDef.Methods) { //       //     "Inject!" method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldstr, "Inject!")); //   Console.WriteLine,      -     "Injected". method.Body.Instructions.Insert(1, Instruction.Create(OpCodes.Call, writeLineRef)); } } assembly.Write(assemblyPath); } }
      
      





рдХрд┐рд╕реА рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреА рдЕрд╕реЗрдВрдмрд▓реА рдХреЗ рд▓рд┐рдП рдкрде рдХреЛ рд╣рдорд╛рд░реЗ рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╕рдордп, рдпрд╣ рдХреЛрдб "Inject!" рдЬреЛрдбрд╝реЗрдЧрд╛, рдкреНрд░рддреНрдпреЗрдХ IL рдкрджреНрдзрддрд┐ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдХрдВрд╕реЛрд▓ рдкрд░, рдФрд░ рдлрд┐рд░ рд╕рдВрд╢реЛрдзрд┐рдд рдЕрд╕реЗрдВрдмрд▓реА рдХреЛ рд╕рд╣реЗрдЬреЗрдВред рдЬрдм рдЖрдк рдПрдХ рд╕рдВрд╢реЛрдзрд┐рдд рдЕрд╕реЗрдВрдмрд▓реА рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ "рдЗрдВрдЬреЗрдХреНрдЯ!" рдХрдВрд╕реЛрд▓ рдкрд░ рд▓рд┐рдЦ рджреЗрдЧреАред



рд╣рдореЗрдВ рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдкрд░ рдзреНрдпрд╛рди рджреЗрдВред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, NET рдХрдИ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдореЗрдВ рдХреЛрдИ рднреА рдХреЛрдб CIL - рд╕рд╛рдорд╛рдиреНрдп рдордзреНрдпрд╡рд░реНрддреА рднрд╛рд╖рд╛ - рдПрдХ рдордзреНрдпрд╡рд░реНрддреА рднрд╛рд╖рд╛ рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рд╣реИред рдХреНрдпреЛрдВ рдмреАрдЪ рдореЗрдВ? рдХреНрдпреЛрдВрдХрд┐ рдЙрд╕рдХреЗ рдмрд╛рдж, CIL рдХреЛрдб рдХреЛ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдХрд┐рд╕реА рднреА рднрд╛рд╖рд╛ рдореЗрдВ рдХреЛрдб рдХреЛ рд▓рдЧрднрдЧ рдЙрд╕реА CIL рдХреЛрдб рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдХрд╛рд░рдг рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЗ C # рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ VB рдкрд░ рдЕрд╕реЗрдВрдмрд▓реАред



рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдмреЛрд▓ рд░рд╣реА рд╣реИ (рдЬреЛ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ), рдФрд░ рд╕реАрдЖрдИрдПрд▓ рдореЗрдВ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯред



рдореИрдВ CIL рдХреЗ рд╡рд┐рд╡рд░рдг рдкрд░ рдзреНрдпрд╛рди рдирд╣реАрдВ рджреВрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рд╡рд┐рд╖рдп рдирд╣реАрдВ рд╣реИред рдореИрдВ рдЦреБрдж рдХреЛ рд╕реАрдорд┐рдд рдХрд░реВрдВрдЧрд╛ рдХрд┐ рднрд╡рд┐рд╖реНрдп рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реЛрдЧрд╛, рдЕрд░реНрдерд╛рддреН, CIL рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреА рдХреБрдЫ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд▓рд┐рдПред рдЖрдк рд╣рдореЗрд╢рд╛ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреА рдкреНрд░рд╕реНрддреБрддрд┐ рдФрд░ рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдЕрдиреНрдп рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред



рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдКрдкрд░ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдХреЛрдб рдХреЗ рднрд╛рдЧ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

 method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldstr, "Inject!")); method.Body.Instructions.Insert(1, Instruction.Create(OpCodes.Call, writeLineRef));
      
      





рдЗрд╕ рдХреЛрдб рдореЗрдВ, рд╣рдореЗрдВ рдХреБрдЫ рд╡рд┐рдзрд┐ рдХреЗ CIL рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рддрдХ рдкрд╣реБрдБрдЪ рдорд┐рд▓реА рдФрд░ рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдЬреЛрдбрд╝реЗрдВред рдЖрдк CIL рдЕрдиреБрджреЗрд╢ рдХреЛ рдпрд╣рд╛рдБ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ: рд╕реАрдЖрдИрдПрд▓ рдХреЗ рд╕рд╛рде рд╕реАрдзреЗ рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп, рд╕реНрдЯреИрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рд╣рдо рд╕реНрдЯреИрдХ рдкрд░ рдХреБрдЫ рдбреЗрдЯрд╛ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рд╡рд╣рд╛рдВ рд╕реЗ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ (рд╕реНрдЯреИрдХ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рдЕрдиреБрд╕рд╛рд░)ред рдКрдкрд░ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, Ldstr рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рд╕реНрдЯреИрдХ рдХреЗ рдЖрдЧреЗ "Inject!" рд▓рд╛рдЗрди рдХреЛ рдзрдХреНрдХрд╛ рджреЗрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдмрд╛рдж, рд╣рдо System.Console.WriteLine рдкрд░ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред рдХреЛрдИ рднреА рд╡рд┐рдзрд┐ рдХреЙрд▓ рдЖрд╡рд╢реНрдпрдХ рддрд░реНрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдЯреИрдХ рддрдХ рдкрд╣реБрдВрдЪрддрд╛ рд╣реИред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, System.Console.WriteLine рдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рддрд░реНрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдордиреЗ рд╕реНрдЯреИрдХ рдкрд░ рд▓реЛрдб рдХрд┐рдпрд╛ рдерд╛ред рдХреЙрд▓ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдЕрдВрдд рд╕реЗ рддрд░реНрдХ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рд╕реНрдЯреИрдХ рдкрд░ рддрд░реНрдХ рдорд╛рдиреЛрдВ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рд▓реЛрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрд╣ рдирд┐рд░реНрджреЗрд╢ "Inject!" рдХреЗ рдмрд░рд╛рдмрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде System.Console.WriteLine рд╡рд┐рдзрд┐ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдЧрд╛ред рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдпрд╣ рд╕реЗрдЯ рдЗрд╕рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ:

 System.Console.WriteLine("Injected!");
      
      







рдЪреВрдВрдХрд┐ Mono.Cecil рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЛ рдирд┐рд░реНрджреЗрд╢реЛрдВ (рдмрд╛рдЗрдЯреНрд╕) рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирддрд╛ рд╣реИ, рд╣рдо рдЗрд╕рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдкреНрд░рддрд┐рдмрдВрдз рдХреЗ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред CIL рдХреЛрдб рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЗрд╕реЗ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ (рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ) рдФрд░ рдПрдХ рд╕рдВрд╢реЛрдзрд┐рдд рдЕрд╕реЗрдВрдмрд▓реА рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред



рдкрд╣рд▓реВ-рдЙрдиреНрдореБрдЦ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдкреАрдврд╝реА рдХрд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ





рдЙрдкрд░реЛрдХреНрдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдЕрдкрдиреА рд╡рд┐рдзрд╛рдирд╕рднрд╛рдУрдВ рдкрд░ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдмрд╣реБрдд рдмрд╛рд░ рд╣рдо рдХрд┐рд╕реА рд╡рд┐рдзрд┐ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддреЗ рдпрд╛ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддреЗ рд╕рдордп рдХреБрдЫ рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдФрд░ рд╡рд┐рдзрд┐, рдпрд╛ рдЗрд╕рдХреЗ рд╕рдВрджрд░реНрдн рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреБрдЫ рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдПрдХ рд▓рдХрдбрд╝рд╣рд╛рд░рд╛ рд╣реИред рдпрджрд┐ рд╣рдо рд▓реЙрдЧ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдХреЗ рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рд▓реЙрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдХреЗ рдЖрд░рдВрдн рдФрд░ рдЕрдВрдд рдореЗрдВ рдиреАрд░рд╕ рдХреЛрдб рд▓рд┐рдЦрдирд╛ рдмрд╣реБрдд рдердХрд╛рдК рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдпрд╣ рдХреБрдЫ рд╣рдж рддрдХ рдЧрдВрджрд╛ рдХреЛрдб рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╕реНрдЯреИрдХ рдкрд░ рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдЧрд░ рд╣рдо рдЗрдирдкреБрдЯ рдкрд░ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд░рд┐рдХреЙрд░реНрдб рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЗрд╕реЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рджреВрд╕рд░реА рдЬреНрдЮрд╛рдд рд╕рдорд╕реНрдпрд╛ INotifyPropertyChanged рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ, рдЬрд┐рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕реМрдВрдкрд╛ рдЬрд╛рдирд╛ рд╣реИред



рдПрдХ рдЕрд▓рдЧ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдирдпрд╛ рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдПрдВред рдПрдХ рд╡рд░реНрдЧ рдЬреЛрдбрд╝реЗрдВ:

 [AttributeUsage(AttributeTargets.Method)] public class MethodInterceptionAttribute : Attribute { public virtual void OnEnter(System.Reflection.MethodBase method, Dictionary<string, object> parameters) { } public virtual void OnExit() { } }
      
      





рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрд╕ рд╡рд░реНрдЧ рд╕реЗ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдСрдирдПрдВрдЯрд░ рд╡рд┐рдзрд┐ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдХрд┐рд╕реА рднреА рд╡рд┐рдзрд┐ рдкрд░ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрд╡рд╕рд░ рдХрд╛ рдПрд╣рд╕рд╛рд╕ рдХрд░рдирд╛ рд╣реИ: MethodInterceptionAttribute рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╡рд┐рдзрд┐ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддреЗ рд╕рдордп, OnEnter рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ, рдЬрд╣рд╛рдВ рд╡рд┐рдзрд┐ рдХрд╛ рдПрдХ рд╕рдВрджрд░реНрдн рдФрд░ <рдкреИрд░рд╛рдореАрдЯрд░ рдирд╛рдо: рдорд╛рди> рдореЗрдВ рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реИред



рдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо рджреЛ рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдПрдВрдЧреЗред рдкрд╣рд▓реЗ рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдкрд░рд┐рднрд╛рд╖рд╛ рд╣реЛрдЧреА рдФрд░ рдХреЛрдб рдХреЛ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рднреА рд╡рд┐рдзрд┐рдпрд╛рдВ рд╣реЛрдВрдЧреАред рджреВрд╕рд░реЗ рдЖрд╡реЗрджрди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рд╣реЛрдЧрд╛ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдкрд░реАрдХреНрд╖рдг рдЖрд╡реЗрджрди рдХреЗ рдЫреЛрдЯреЗ рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:



 class Program { static void Main(string[] args) { MethodToChange("Test"); } [TestMethodInterception()] public static void MethodToChange(string text) { Console.ReadLine(); } } public class TestMethodInterceptionAttribute : MethodInterceptionAttribute { public override void OnEnter(System.Reflection.MethodBase method, Dictionary<string, object> parameters) { Console.WriteLine("Entering method " + method.Name + "..." + Environment.NewLine); foreach (string paramName in parameters.Keys) { Console.WriteLine("Parameter " + paramName + " has value " + parameters[paramName] + Environment.NewLine); } } }
      
      





рдпрд╣ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ рдЬреЛ рдЯреЗрд╕реНрдЯ рдХреЗ рдмрд░рд╛рдмрд░ рдЯреЗрдХреНрд╕реНрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде MethodToChange рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рдзрд┐ TestMethodInterceptionAttribute рд╡рд┐рд╢реЗрд╖рддрд╛ MethodInterceptionAttribute рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╣реИред рдЗрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рд╕реА рднреА рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП OnEnter рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдкреВрд░реНрд╡-рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдмрд┐рдирд╛, рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░ рдпрд╣ рдПрдкреНрд▓рд┐рдХреЗрд╢рди Console.ReadLine рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛ рдФрд░ рдмрд╛рд╣рд░ рдирд┐рдХрд▓ рдЬрд╛рдПрдЧрд╛ред



рд╣рдо рдореБрдЦреНрдп рдПрдкреНрд▓рд┐рдХреЗрд╢рди (рдХрдВрд╕реЛрд▓ рднреА) рдкрд░ рд╡рд┐рдЪрд╛рд░ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВред MSIL рдХреЛрдб рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдФрд░ рдЖрдЧреЗ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐ рд▓рд┐рдЦреЗрдВрдЧреЗ:



 static void DumpAssembly(string path, string methodName) { System.IO.File.AppendAllText("dump.txt", "Dump started... " + Environment.NewLine); var assembly = AssemblyDefinition.ReadAssembly(path); foreach (var typeDef in assembly.MainModule.Types) { foreach (var method in typeDef.Methods) { if (String.IsNullOrEmpty(methodName) || method.Name == methodName) { System.IO.File.AppendAllText("dump.txt", "Method: " + method.ToString()); System.IO.File.AppendAllText("dump.txt", Environment.NewLine); foreach (var instruction in method.Body.Instructions) { System.IO.File.AppendAllText("dump.txt", instruction.ToString() + Environment.NewLine); } } } } }
      
      





рдпрд╣ рд╡рд┐рдзрд┐ рдПрдХ рдирд┐рд░реНрдорд╛рдг рд╡рд┐рдзрд┐ (рдпрд╛ рд╕рднреА) рд╕реЗ рдореМрдЬреВрджрд╛ MSIL рдХреЛрдб рдХреЛ рдкрдврд╝рддреА рд╣реИ рдФрд░ рдЗрд╕реЗ dip.txt рдкрд░ рд▓рд┐рдЦрддреА рд╣реИред рдпрд╣ рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ? рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреА рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдореЗрдВ рд╣рдо рдХреНрдпрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреЛрдб рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рднреА MSIL рдХреЛрдб рдХреЛ рдЦрд░реЛрдВрдЪ рд╕реЗ рдирд╣реАрдВ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдлрд┐рд░ рд╣рдо рдЕрдкрдиреЗ рдХреБрдЫ рддрд░реАрдХреЛрдВ рдХреЛ C # рдореЗрдВ рдЗрд╕ рдХреЛрдб рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ рдбрдВрдк рдХрд░реЗрдВрдЧреЗред рдЙрд╕рдХреЗ рдмрд╛рдж, Mono.Cecil рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ MSIL рд▓рд┐рдЦрдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рддреИрдпрд╛рд░ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦреЗрдЧрд╛ (рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, MSIL рдЕрд╕реЗрдВрдмрд▓реА рдХреЛрдб рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреНрдп рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)ред



рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдХреНрдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ (C # рдХреЗ рд░реВрдк рдореЗрдВ):



 var currentMethod = System.Reflection.MethodBase.GetCurrentMethod(); var attribute = (MethodInterceptionAttribute)Attribute.GetCustomAttribute(currentMethod, typeof(MethodInterceptionAttribute)); Dictionary<string, object> parameters = new Dictionary<string, object>(); //              parameters,    #   attribute.OnEnter(currentMethod, parameters);
      
      





рдЗрд╕ MSIL рдХреЛрдб рдХреЛ рдбрдВрдк рдХрд░рдиреЗ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛:



IL_0000: nop

IL_0001: call System.Reflection.MethodBase System.Reflection.MethodBase::GetCurrentMethod()

IL_0006: ldtoken EmitExperiments.MethodInterceptionAttribute

IL_000b: call System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)

IL_0010: call System.Attribute System.Attribute::GetCustomAttribute(System.Reflection.MemberInfo,System.Type)

IL_0015: castclass EmitExperiments.MethodInterceptionAttribute

IL_001a: stloc V_1

IL_001e: ldloc V_1

IL_0022: callvirt System.Void EmitExperiments.MethodInterceptionAttribute::OnEnter()

...







рдЕрдЧрд▓рд╛, рдореИрдВ рдХреЗрд╡рд▓ InjectToAssembly рд╡рд┐рдзрд┐ рдХрд╛ рдкреВрд░рд╛ рдХреЛрдб (рд╡рд┐рд╕реНрддреГрдд рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде) рджреВрдВрдЧрд╛, рдЬреЛ рдХрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЗ MethodInterceptionAttribute рдХреЗ рд╕рд╛рде рд╕рднреА рддрд░реАрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдХреЛрдб рдЬреЛрдбрд╝ рджреЗрдЧрд╛:



 static void InjectToAssembly(string path) { var assembly = AssemblyDefinition.ReadAssembly(path); //   GetCurrentMethod() var getCurrentMethodRef = assembly.MainModule.Import(typeof(System.Reflection.MethodBase).GetMethod("GetCurrentMethod")); //   Attribute.GetCustomAttribute() var getCustomAttributeRef = assembly.MainModule.Import(typeof(System.Attribute).GetMethod("GetCustomAttribute", new Type[] { typeof(System.Reflection.MethodInfo), typeof(Type) })); //   Type.GetTypeFromHandle() -  typeof() var getTypeFromHandleRef = assembly.MainModule.Import(typeof(Type).GetMethod("GetTypeFromHandle")); //    MethodBase var methodBaseRef = assembly.MainModule.Import(typeof(System.Reflection.MethodBase)); //    MethodInterceptionAttribute var interceptionAttributeRef = assembly.MainModule.Import(typeof(MethodInterceptionAttribute)); //   MethodInterceptionAttribute.OnEnter var interceptionAttributeOnEnter = assembly.MainModule.Import(typeof(MethodInterceptionAttribute).GetMethod("OnEnter")); //    Dictionary<string,object> var dictionaryType = Type.GetType("System.Collections.Generic.Dictionary`2[System.String,System.Object]"); var dictStringObjectRef = assembly.MainModule.Import(dictionaryType); var dictConstructorRef = assembly.MainModule.Import(dictionaryType.GetConstructor(Type.EmptyTypes)); var dictMethodAddRef = assembly.MainModule.Import(dictionaryType.GetMethod("Add")); foreach (var typeDef in assembly.MainModule.Types) { foreach (var method in typeDef.Methods.Where(m => m.CustomAttributes.Where( attr => attr.AttributeType.Resolve().BaseType.Name == "MethodInterceptionAttribute").FirstOrDefault() != null)) { var ilProc = method.Body.GetILProcessor(); //   InitLocals  true,       false (      ) //      -  IL   . method.Body.InitLocals = true; //      attribute, currentMethod  parameters var attributeVariable = new VariableDefinition(interceptionAttributeRef); var currentMethodVar = new VariableDefinition(methodBaseRef); var parametersVariable = new VariableDefinition(dictStringObjectRef); ilProc.Body.Variables.Add(attributeVariable); ilProc.Body.Variables.Add(currentMethodVar); ilProc.Body.Variables.Add(parametersVariable); Instruction firstInstruction = ilProc.Body.Instructions[0]; ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Nop)); //    ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Call, getCurrentMethodRef)); //       currentMethodVar ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Stloc, currentMethodVar)); //        ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Ldloc, currentMethodVar)); //     MethodInterceptionAttribute ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Ldtoken, interceptionAttributeRef)); //  GetTypeFromHandle (   typeof()) -  typeof(MethodInterceptionAttribute) ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Call, getTypeFromHandleRef)); //          MethodInterceptionAttribute.  Attribute.GetCustomAttribute ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Call, getCustomAttributeRef)); //     MethodInterceptionAttribute ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Castclass, interceptionAttributeRef)); //     attributeVariable ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Stloc, attributeVariable)); //   Dictionary<stirng, object> ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Newobj, dictConstructorRef)); //   parametersVariable ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Stloc, parametersVariable)); foreach (var argument in method.Parameters) { //    //     Dictionary<string,object> ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Ldloc, parametersVariable)); //    ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Ldstr, argument.Name)); //    ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Ldarg, argument)); //  Dictionary.Add(string key, object value) ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Call, dictMethodAddRef)); } //     ,       OnEnter ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Ldloc, attributeVariable)); ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Ldloc, currentMethodVar)); ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Ldloc, parametersVariable)); //  OnEnter.     ,    OnEnter    ilProc.InsertBefore(firstInstruction, Instruction.Create(OpCodes.Callvirt, interceptionAttributeOnEnter)); } } assembly.Write(path); } }
      
      





рд╣рдорд╛рд░реЗ рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рдореБрдЦреНрдп рд╡рд┐рдзрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдордд рднреВрд▓рдирд╛:



 static void Main(string[] args) { if (args.Length > 0) { string mode = args[0]; string path = args[1]; if (mode == "-dump") { string methodName = args.Length > 2 ? args[2] : String.Empty; DumpAssembly(path, methodName); } else if (mode == "-inject") { InjectToAssembly(args[1]); } } }
      
      





рд╣реЛ рдЧрдпрд╛! рдЕрдм, рдпрджрд┐ рдЖрдк -inject рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдореБрдЦреНрдп рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╣рдорд╛рд░реЗ рдЯреЗрд╕реНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдкрде рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, MethodToChange рд╡рд┐рдзрд┐ рдХрд╛ рдХреЛрдб рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ (рд░рд┐рдлреНрд▓реЗрдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ)



 [TestMethodInterception] public static void MethodToChange(string text) { MethodBase currentMethod = MethodBase.GetCurrentMethod(); MethodInterceptionAttribute customAttribute = (MethodInterceptionAttribute) Attribute.GetCustomAttribute(currentMethod, typeof(MethodInterceptionAttribute)); Dictionary<string, object> parameters = new Dictionary<string, object>(); parameters.Add("text", text); customAttribute.OnEnter(currentMethod, parameters); Console.ReadLine(); }
      
      







рдЬрд┐рд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред рдЕрдм, TestMethodInterception рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдХреЛ рдХрдИ рдмрд╛рд░ рджреЛрд╣рд░рд╛рдпрд╛ рдЧрдпрд╛ рдХреЛрдб рд▓рд┐рдЦреЗ рдмрд┐рдирд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рд╡реАрдПрд╕ рдореЗрдВ рдкреЛрд╕реНрдЯ-рдмрд┐рд▓реНрдб рдЗрд╡реЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рдХрд┐рд╕реА рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд╕рдлрд▓ рдирд┐рд░реНрдорд╛рдг рдХреЗ рдмрд╛рдж, рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рддреИрдпрд╛рд░ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░реЗрдВ рдФрд░ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреЛрдб рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВред рдЖрдк рдХреЛрдб рдпрд╛ рдЕрд╕реЗрдВрдмрд▓реА рд╕реНрддрд░ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдПрдХ рд╕рд╛рде рд╕рднреА рдХреНрд▓рд╛рд╕ рдпрд╛ рдЕрд╕реЗрдВрдмрд▓реА рд╡рд┐рдзрд┐рдпреЛрдВ рдореЗрдВ рдХреЛрдб рдПрдореНрдмреЗрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред



рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг .NET рдореЗрдВ рдкрд╣рд▓реВ-рдЙрдиреНрдореБрдЦ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред рдореИрдВ рдЗрд╕ рдмрд╛рдд рдкрд░ рдзреНрдпрд╛рди рдирд╣реАрдВ рджреВрдВрдЧрд╛ рдХрд┐ AOP рдХреНрдпрд╛ рд╣реИ, рд╕рд╛рдорд╛рдиреНрдп рд╢рдмреНрджреЛрдВ рдореЗрдВ рдЖрдк рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рдХрд┐рдкреАрдбрд┐рдпрд╛ рдкрд░ рд╣рдореЗрд╢рд╛ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рдкреНрд░рд╕рд┐рджреНрдз рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЬреЛ рдЖрдкрдХреЛ .NET рдореЗрдВ AOP рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд╡рд╣ PostSharp рд╣реИ , рдЬрд┐рд╕рдиреЗ рдореБрдЭреЗ рдЗрд╕ рд▓реЗрдЦ рдХреЛ рд▓рд┐рдЦрддреЗ рд╣реБрдП рд╕рдорд╛рди рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреЛ рдЗрдВрдЬреЗрдХреНрд╢рди рд▓рдЧрд╛рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рд┐рдд рдХрд┐рдпрд╛ред



рдПрдУрдкреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЖрдк рд╕рд╛рдл рдФрд░ рдЖрд╕рд╛рдиреА рд╕реЗ рдмрдирд╛рдП рд░рдЦрд╛ рдХреЛрдб рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рдХрд╛ рдореБрдЦреНрдп рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЛрдб рдкрд╣рд▓реБрдУрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддреЗ рд╣реИрдВред



рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВрдиреЗ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рдХрд┐ рдЖрдк Mono.Cecil рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореМрдЬреВрджрд╛ рдиреЗрдЯ рдЕрд╕реЗрдВрдмрд▓реА рдореЗрдВ рдХреЛрдб рдХреИрд╕реЗ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рд╛рде рд╣реА рдиреЗрдЯ рдореЗрдВ AOP рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдХрдИ рдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рдпрд╛ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред



All Articles