GetMethod Runtime Implementation

I am currently trying to change the implementation of the get property, replacing it with a small amount of IL. I used this question as a reference: How do I replace a pointer to a pointer to a method in a class of my method inherited from a system class?

The only difference I have is that my method is declared via MethodBuilder:

MethodBuilder propertyGetBuilder = builder.DefineMethod ( dynamicFunctionName, MethodAttributes.Public, propertyInfo.PropertyType, Type.EmptyTypes ); ILGenerator propertyGetIlGenerator = propertyGetBuilder.GetILGenerator(); propertyGetIlGenerator.Emit(OpCodes.Ldarg_0); propertyGetIlGenerator.Emit(OpCodes.Ldstr, propertyInfo.Name); propertyGetIlGenerator.Emit(OpCodes.Ldstr, relationKeyField.Name); propertyGetIlGenerator.Emit(OpCodes.Ldstr, relationAttribute.RelationColumn); propertyGetIlGenerator.Emit(OpCodes.Call, loadRelationMethod); propertyGetIlGenerator.Emit(OpCodes.Ret); 

This adds a new function to the generated type named BeforeGet{PropertyName}

After generating a new type, I instantiate it to make sure that the memory address exists: dynamic fakeType = Activator.CreateInstance(type);

I am retrieving propertyInfo GetMethod from an existing class and the newly created Type class of class FakeType BeforeGet{PropertyName} .

After that, both MethodInfo are used in this function:

 RuntimeHelpers.PrepareMethod(methodA.MethodHandle); RuntimeHelpers.PrepareMethod(methodB.MethodHandle); unsafe { if (IntPtr.Size == 4) { int* inj = (int*)methodA.MethodHandle.Value.ToPointer() + 2; int* tar = (int*)methodB.MethodHandle.Value.ToPointer() + 2; #if DEBUG Console.WriteLine("\nVersion x86 Debug?\n"); byte* injInst = (byte*)*inj; byte* tarInst = (byte*)*tar; int* injSrc = (int*)(injInst + 1); int* tarSrc = (int*)(tarInst + 1); *tarSrc = (((int)injInst + 5) + *injSrc) - ((int)tarInst + 5); #else *tar = *inj; #endif } else { long* inj = (long*)methodA.MethodHandle.Value.ToPointer() + 1; long* tar = (long*)methodB.MethodHandle.Value.ToPointer() + 1; #if DEBUG Console.WriteLine("\nVersion x64 Debug\n"); byte* injInst = (byte*)*inj; byte* tarInst = (byte*)*tar; int* injSrc = (int*)(injInst + 1); int* tarSrc = (int*)(tarInst + 1); *tarSrc = (((int)injInst + 5) + *injSrc) - ((int)tarInst + 5); #else *tar = *inj; #endif } } 

After running this code, I execute the following code in my Program: LoadedTag.Item.ItemID; Where LoadedTag is the class that was supposed to get the new implementation of Item Getter, but instead I got a null reference exception because the function was not replaced.

However, if I execute this code in a direct window, the ItemID is indeed set and the interception function is called.

I think the problem is that the garbage collector removes fakeType, which contains the actual function pointers used during method replacement. If so, how should I solve this?

Thanks in advance!

If necessary, please verify the full code, and I will post it on Github.

+10
pointers c #
source share

No one has answered this question yet.

See similar questions:

2
How to replace a pointer to a pointer to a method in a class of my method inherited from a system class?

or similar:

1743
What is the best way to give the C # auto-property an initial value?
1064
How to sort the <T> list by property in an object
982
LINQ Distinct () for a specific property
975
What is the difference between a field and a property?
774
Get property value from string using reflection in C #
756
Verification failed for one or more objects. See the topic "EntityValidationErrors Property" for more information.
638
Does C # have extension properties?
613
Implementing INotifyPropertyChanged - is there a better way?
612
C # Interfaces. Implicit implementation compared to explicit implementation
5
Why can we dereference a function?

All Articles