public static void SetMethodBody(Type type, MethodToken somemethodToken, byte[] methodBytes) { //MethodToken somemethodToken = somemethod.GetToken(); // Get the pointer to the method body. GCHandle methodBytesHandle = GCHandle.Alloc((Object)methodBytes, GCHandleType.Pinned); IntPtr methodBytesAddress = methodBytesHandle.AddrOfPinnedObject(); int methodBytesLength = methodBytes.Length; // Swap the old method body with the new body. MethodRental.SwapMethodBody( type, somemethodToken.Token, methodBytesAddress, methodBytesLength, MethodRental.JitImmediate); ////// Verify that the modified method returns 1. ////int res2 = (int)tbBaked.GetMethod("My method Name").Invoke(null, new Object[] { }); ////if (res2 != 1) ////{ //// Console.WriteLine("Err_001b, should have returned 1"); ////} ////else ////{ //// Console.WriteLine("Swapped method body returned 1"); ////} }
public static void WrapMethod(object instance, MethodInfo m, string MethodName) { byte[] ilasByteArray = instance.GetType().GetMethod(MethodName).GetMethodBody().GetILAsByteArray(); IntPtr rgIL = GCHandle.Alloc(ilasByteArray, GCHandleType.Pinned).AddrOfPinnedObject(); int methodSize = ilasByteArray.Length; MethodRental.SwapMethodBody(instance.GetType(), m.MetadataToken, rgIL, methodSize, 1); }
private void CloneMethodBody(byte[] newMethodBytes) { var handle = GCHandle.Alloc((Object)newMethodBytes, GCHandleType.Pinned); IntPtr addressOfHandle = handle.AddrOfPinnedObject(); int methodSize = newMethodBytes.Length; MethodRental.SwapMethodBody(this.ReleasedType, //methodToken.Token, this.SourceMethodInfo.MetadataToken, addressOfHandle, methodSize, MethodRental.JitImmediate); }
/// <inheritdoc /> public void AddInterceptor(MethodInfo method, IInterceptor interceptor) { if (method == null) { throw new ArgumentNullException(@"method"); } if (interceptor == null) { throw new ArgumentNullException(@"interceptor"); } // FIXME: Just a quick and dirty check to verify that we can replace method bodies. // This doesn't actually install an interceptor but it causes the method to not run. // The trick for actually doing that will be to inject code at the beginning // of the method that looks for a thread-local "proceed" flag. If it's not // set, then it should call the interceptors. Otherwise it should clear it // immediately and run the method to completion. -- Jeff. Byte[] methodBytes = { 0x03, 0x30, 0x0A, 0x00, 0x01, // code size 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a // ret }; // Get the pointer to the method body. GCHandle handle = new GCHandle(); try { handle = GCHandle.Alloc(methodBytes, GCHandleType.Pinned); IntPtr addr = handle.AddrOfPinnedObject(); MethodRental.SwapMethodBody(method.DeclaringType, method.MetadataToken, addr, methodBytes.Length, MethodRental.JitOnDemand); } finally { if (handle.IsAllocated) { handle.Free(); } } }
public static void Init() { MethodInfo MI = typeof(AssemblerModifier).GetMethod("UpdateCurrentItemStatus"); MethodBody MB = MI.GetMethodBody(); byte[] MethodBytes = MB.GetILAsByteArray(); int methodSize = MethodBytes.Length; GCHandle hmem = GCHandle.Alloc((object)MethodBytes, GCHandleType.Pinned); IntPtr addr = hmem.AddrOfPinnedObject(); MethodRental.SwapMethodBody(typeof(MyCraftingComponentBase), MI.MetadataToken, addr, methodSize, MethodRental.JitImmediate); }
public void SwapMethodBodyUnfinishedType() { MethodRental.SwapMethodBody(genClass, 0, IntPtr.Zero, 1, 0); }
public void SwapMethodBodyNullType() { MethodRental.SwapMethodBody(null, 0, IntPtr.Zero, 1, 0); }
public void SwapMethodBodyInvalidMethodSize() { MethodRental.SwapMethodBody(null, 0, IntPtr.Zero, 0, 0); }
public void SwapMethodBody() { MethodRental.SwapMethodBody(typeof(object), 0, IntPtr.Zero, 0, 0); }
// First make a method that returns 0. // Then swap the method body with a body that returns 1. public static void Main(String [] args) { // Construct a dynamic assembly Guid g = Guid.NewGuid(); AssemblyName asmname = new AssemblyName(); asmname.Name = "tempfile" + g; AssemblyBuilder asmbuild = System.Threading.Thread.GetDomain(). DefineDynamicAssembly(asmname, AssemblyBuilderAccess.Run); // Add a dynamic module that contains one type that has one method that // has no arguments. ModuleBuilder modbuild = asmbuild.DefineDynamicModule("test"); TypeBuilder tb = modbuild.DefineType("name of the Type"); MethodBuilder somemethod = tb.DefineMethod ("My method Name", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[] {}); // Define the body of the method to return 0. ILGenerator ilg = somemethod.GetILGenerator(); ilg.Emit(OpCodes.Ldc_I4_0); ilg.Emit(OpCodes.Ret); // Complete the type and verify that it returns 0. Type tbBaked = tb.CreateType(); int res1 = (int)tbBaked.GetMethod("My method Name").Invoke(null, new Object[] {}); if (res1 != 0) { Console.WriteLine("Err_001a, should have returned 0"); } else { Console.WriteLine("Original method returned 0"); } // Define a new method body that will return a 1 instead. Byte[] methodBytes = { 0x03, 0x30, 0x0A, 0x00, 0x02, // code size 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, // ldc_i4_1 0x2a // ret }; // Get the token for the method whose body you are replacing. MethodToken somemethodToken = somemethod.GetToken(); // Get the pointer to the method body. GCHandle hmem = GCHandle.Alloc((Object)methodBytes, GCHandleType.Pinned); IntPtr addr = hmem.AddrOfPinnedObject(); int cbSize = methodBytes.Length; // Swap the old method body with the new body. MethodRental.SwapMethodBody( tbBaked, somemethodToken.Token, addr, cbSize, MethodRental.JitImmediate); // Verify that the modified method returns 1. int res2 = (int)tbBaked.GetMethod("My method Name").Invoke(null, new Object[] {}); if (res2 != 1) { Console.WriteLine("Err_001b, should have returned 1"); } else { Console.WriteLine("Swapped method body returned 1"); } }