[Mono-dev] Unity - patching methods

pardeike andreas at pardeike.net
Sun Jan 22 13:50:17 UTC 2017

Ivo Smits wrote
> One thing I found out is that when using 
> Marshal.GetDelegateForFunctionPointer, you need to keep a (managed) 
> reference to the delegate used to construct the function pointer around 
> as well. Otherwise the GC may clean up the delegate and the function 
> pointer will become invalid - although I did get a message informing me 
> that the handle had been cleaned instead of an immediate crash.

Yes, I am aware of this. I have spend the better part of my weekend to test
different strategies. Currently, I copy over IL code from the original to a
DynamicMethod, prerun it, add a delegate to it, anchor all parts to a static
object[] and the do the ordinary detour() that everyone is doing on
original.MethodHandle.GetFunctionPointer() and
dynamicCopyDelegate.MethodHandle.GetFunctionPointer(). It works BUT and this
is something I am trying to understand: I can patch original A fine, or
original B fine but when I do A and B together, the second call just
crashes. I suspect that the ordinary detour that basically writes a jump to
B at the start of A is wrong. It probably points to a trampoline and when
two methods are patched the end result is messed up. Interestingly, that
approach works fine if both methods are from loaded assemblies (my B is
always dynamic and adding a delegate or prerunning it did not help).

I read about trampolines (type-0, specific, generic and magic) and are still
not sure if I understand this correctly. It says that the original CALL in
the method points to a trampoline that itself invokes more stuff and
compiles the called method and then *replaces the address of the original
CALL in the method body*. Saves one jump so fine, but I am not sure if this
would mean that *all* CALLs in the application need to be patched too or if
this process is done for every CALL later with either recompiling (unlikely)
or just using a pointer to the compiled method (in the method table?). I get
lazy compiling but the replacement of call addresses is confusing.

Sorry for the rant,

View this message in context: http://mono.1490590.n4.nabble.com/Unity-patching-methods-tp4669765p4669773.html
Sent from the Mono - Dev mailing list archive at Nabble.com.

More information about the Mono-devel-list mailing list