Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using Mono.Cecil;
- using Mono.Cecil.Cil;
- namespace CustomFieldsInjection
- {
- public partial class Injector
- {
- public static void MethodInjection(string assemblyFilename,
- string typeName, string methodName)
- {
- AssemblyDefinition assembly = AssemblyFactory.GetAssembly
- (assemblyFilename);
- // Compared to Reflection, Cecil doesn`t use a
- AppDomain here,
- // which also allows us to load incomplete or CAS-
- prohibited assemblies.
- //Load the debugger symbols file
- // assembly.MainModule.LoadSymbols();
- // Next we'd like to define our new Method. A method
- in Cecil consists of
- // the return type the signature and the body (code).
- //Get a TypeReference for the return Type
- TypeReference returnTypeReference =
- assembly.MainModule.Import(typeof(void));
- //Define Method signature "public static void" methodName
- MethodDefinition methodDefinition = new MethodDefinition(
- methodName, MethodAttributes.Public |
- MethodAttributes.Static,
- returnTypeReference);
- // Now we got our method but it hasn`t got any code
- in it`s body.
- // The new method will write a message outputString
- to the Console.
- //Push string onto the stack
- Instruction instruction1 =
- methodDefinition.Body.CilWorker.Create(OpCodes.Nop);
- //Push string onto the stack
- Instruction instruction2 =
- methodDefinition.Body.CilWorker.Create(OpCodes.Ldstr, methodName);
- //Import external method reference to Console.WriteLine()
- MethodReference writeline = assembly.MainModule.Import(
- typeof(Console).GetMethod("WriteLine", new Type[]
- { typeof(string) }));
- // We need to generate the defined code and append it
- to our new method Body
- //Generate stack-push
- methodDefinition.Body.CilWorker.Append(instruction1);
- methodDefinition.Body.CilWorker.Append(instruction2);
- //Generate call to WriteLine()
- methodDefinition.Body.CilWorker.InsertAfter(
- instruction2, methodDefinition.Body.CilWorker.Create
- (OpCodes.Call, writeline));
- //Generate return
- methodDefinition.Body.CilWorker.Append
- (methodDefinition.Body.CilWorker.Create(OpCodes.Ret));
- // That done, we need to inject the generated Method
- into the assembly
- assembly.MainModule.Inject(methodDefinition,
- assembly.MainModule.Types[typeName]);
- // At last we need to modify Main to call our new
- Method
- //Get Method reference with name like methodName,
- MethodReference methodReference = null;
- //Get all the methods of typeName
- foreach (MethodDefinition method in
- assembly.MainModule.Types[typeName].Methods)
- {
- if (method.Name == methodName)
- {
- methodReference = assembly.MainModule.Import
- (method);
- break;
- }
- }
- //Create call to the reference
- Instruction callTest =
- methodDefinition.Body.CilWorker.Create(OpCodes.Call, methodReference);
- if (assembly.EntryPoint != null)
- {
- //Insert reference
- assembly.EntryPoint.Body.CilWorker.InsertBefore
- (assembly.EntryPoint.Body.Instructions[0], callTest);
- }
- //Save the debugger symbols file
- // assembly.MainModule.SaveSymbols();
- //Save the patched assembly back to disk
- AssemblyFactory.SaveAssembly(assembly, assemblyFilename);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment