Closed Drakulix closed 11 years ago
Hi Victor,
What does it say when you run PEVerify.exe on the modified assembly?
On Sun, May 26, 2013 at 3:42 AM, Drakulix notifications@github.com wrote:
First of all, thanks for this lovely framework. However I am having some issues using this framework, which are hopefully easy to fix and probably my own fault of miss-using this wonderful framework. I am quite an experienced Hobby-Programmer, however I have not worked too much with assembly code in general and found Mono.Cecil to be it quite difficult to use, if you want to achieve more complex results, besides adding some static method calls, so I was very happy that I found this on codeProject.com.
I am trying to inject some smaller code into an already compiled assembly, so I am using PostWeaver.exe. I tried weaving the complete assembly at the beginning, however that failed horribly with lots of exceptions, when running the resulting assembly, which was expected since the assembly is a really complex one, with lots of native library bindings. Which is why I started to weave only filtered method bodies and nothing else, but that should not be the problem, right?
I can modify methods returning void or objects quite well, however I run into problems when I want to edit a method returning a 'bool'. I have not tried to extend a wide range of methods, so I am not sure if this might also happen on other 'primitive' types.
The code of the to be modified assembly looks like this before weaving:
C#
private bool sendSilentRequest (string request){ if (this.m_Socket != null && this.m_Socket.Connected && this.IsServerInfoReceived ()) { if (!request.EndsWith ("\n")) { request += "\n"; } byte[] bytes = Encoding.get_UTF8 ().GetBytes (request); this.m_Socket.Send (bytes); return true; } return false;}
IL
.method private hidebysig instance bool sendSilentRequest ( string 'request' ) cil managed { // Method begins at RVA 0x31a50 // Code size 96 (0x60) .maxstack 14 .locals init ( [0] uint8[] )
IL_0000: ldarg.0 IL_0001: ldfld class [System]System.Net.Sockets.Socket Communicator::m_Socket IL_0006: brfalse IL_005e IL_000b: ldarg.0 IL_000c: ldfld class [System]System.Net.Sockets.Socket Communicator::m_Socket IL_0011: callvirt instance bool [System]System.Net.Sockets.Socket::get_Connected() IL_0016: brfalse IL_005e IL_001b: ldarg.0 IL_001c: call instance bool Communicator::IsServerInfoReceived() IL_0021: brfalse IL_005e IL_0026: ldarg.1 IL_0027: ldstr "\n" IL_002c: callvirt instance bool [mscorlib]System.String::EndsWith(string) IL_0031: brtrue IL_0043 IL_0036: ldarg.1 IL_0037: ldstr "\n" IL_003c: call string [mscorlib]System.String::Concat(string, string) IL_0041: starg.s 'request' IL_0043: call class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::get_UTF8() IL_0048: ldarg.1 IL_0049: callvirt instance uint8[] [mscorlib]System.Text.Encoding::GetBytes(string) IL_004e: stloc.0 IL_004f: ldarg.0 IL_0050: ldfld class [System]System.Net.Sockets.Socket Communicator::m_Socket IL_0055: ldloc.0 IL_0056: callvirt instance int32 [System]System.Net.Sockets.Socket::Send(uint8[]) IL_005b: pop IL_005c: ldc.i4.1 IL_005d: ret IL_005e: ldc.i4.0 IL_005f: ret
} // end of method
After Weaving it looks like this:
C#
private bool sendSilentRequest (string request){ bool isInterceptionDisabled; if (this is IModifiableType) { isInterceptionDisabled = (this as IModifiableType).IsInterceptionDisabled; } IInvocationInfo invocationInfo; IAroundInvokeProvider methodBodyReplacementProvider; IAroundInvoke surroundingImplementation; IAroundInvoke surroundingImplementation2; if (!isInterceptionDisabled) { Type[] typeArguments = new Type[0]; object[] arguments = new object[] { request }; MethodBase methodFromHandle = MethodBase.GetMethodFromHandle (methodof (Communicator.sendSilentRequest (string)).MethodHandle, typeof(Communicator).TypeHandle); invocationInfo = new InvocationInfo (this, methodFromHandle, new StackTrace (1, false), new Type[] { typeof(string) }, typeArguments, typeof(bool), arguments); IgnoredInstancesRegistry.AddInstance (invocationInfo); if (!isInterceptionDisabled) { IMethodReplacementProvider methodReplacementProvider = ((IMethodReplacementHost)this).MethodBodyReplacementProvider; if (this is IModifiableType && !isInterceptionDisabled) { methodBodyReplacementProvider = ((IMethodReplacementHost)this).MethodBodyReplacementProvider; methodReplacementProvider = ((IAroundInvokeHost)this).AroundMethodBodyProvider; if (methodReplacementProvider != null) { surroundingImplementation = methodReplacementProvider.GetSurroundingImplementation (invocationInfo); } surroundingImplementation2 = AroundMethodBodyRegistry.GetSurroundingImplementation (invocationInfo); if (surroundingImplementation2 != null) { surroundingImplementation2.BeforeInvoke (invocationInfo); } if (surroundingImplementation != null) { surroundingImplementation.BeforeInvoke (invocationInfo); } } } } IMethodReplacementProvider provider = MethodBodyReplacementProviderRegistry.GetProvider (this, invocationInfo); if (!isInterceptionDisabled) { if (methodBodyReplacementProvider != null || provider != null) { IInterceptor methodReplacement; if (methodBodyReplacementProvider != null) { methodReplacement = methodBodyReplacementProvider.GetMethodReplacement (this, invocationInfo); } if (methodReplacement == null) { if (provider != null) { methodReplacement = provider.GetMethodReplacement (this, invocationInfo); } } if (methodReplacement != null) { (bool)methodReplacement.Intercept (invocationInfo); goto IL_245; } } } if (this.m_Socket != null && this.m_Socket.Connected && this.IsServerInfoReceived ()) { if (!request.EndsWith ("\n")) { request += "\n"; } byte[] bytes = Encoding.UTF8.GetBytes (request); this.m_Socket.Send (bytes); 1; } else { 0; } IL_245: object obj; if (!isInterceptionDisabled) { if (surroundingImplementation == null) { } if (surroundingImplementation != null) { surroundingImplementation.AfterInvoke (invocationInfo, obj); } if (surroundingImplementation2 == null) { } if (surroundingImplementation2 != null) { surroundingImplementation2.AfterInvoke (invocationInfo, obj); } } return obj != null;}
IL
.method private hidebysig instance bool sendSilentRequest ( string 'request' ) cil managed { // Method begins at RVA 0x1c4a4 // Code size 671 (0x29f) .maxstack 7 .locals init ( [0] uint8[], [1] bool, [2] class LinFu.AOP.Interfaces.IInvocationInfo, [3] class LinFu.AOP.Interfaces.IAroundInvokeProvider, [4] class LinFu.AOP.Interfaces.IMethodReplacementProvider, [5] object, [6] class LinFu.AOP.Interfaces.IMethodReplacementProvider, [7] class [mscorlib]System.Reflection.MethodBase, [8] class [mscorlib]System.Type[], [9] object[], [10] class [mscorlib]System.Type[], [11] class LinFu.AOP.Interfaces.IAroundInvoke, [12] class LinFu.AOP.Interfaces.IAroundInvoke, [13] class LinFu.AOP.Interfaces.IInterceptor )
IL_0000: ldarg.0 IL_0001: isinst LinFu.AOP.Interfaces.IModifiableType IL_0006: brfalse IL_001a IL_000b: ldarg.0 IL_000c: isinst LinFu.AOP.Interfaces.IModifiableType IL_0011: callvirt instance bool LinFu.AOP.Interfaces.IModifiableType::get_IsInterceptionDisabled() IL_0016: stloc 1 IL_001a: nop IL_001b: ldloc 1 IL_001f: brtrue IL_014a IL_0024: ldc.i4 0 IL_0029: newarr [mscorlib]System.Type IL_002e: stloc 10 IL_0032: ldc.i4 1 IL_0037: newarr [mscorlib]System.Object IL_003c: stloc 9 IL_0040: ldloc 9 IL_0044: ldc.i4 0 IL_0049: ldarg 'request' IL_004d: stelem.ref IL_004e: ldarg.0 IL_004f: ldtoken method instance bool Communicator::sendSilentRequest(string) IL_0054: ldtoken Communicator IL_0059: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle, valuetype [mscorlib]System.RuntimeTypeHandle) IL_005e: stloc 7 IL_0062: ldloc 7 IL_0066: ldc.i4.1 IL_0067: ldc.i4.0 IL_0068: newobj instance void [mscorlib]System.Diagnostics.StackTrace::.ctor(int32, bool) IL_006d: ldc.i4 1 IL_0072: newarr [mscorlib]System.Type IL_0077: stloc 8 IL_007b: ldloc 8 IL_007f: ldc.i4 0 IL_0084: ldtoken [mscorlib]System.String IL_0089: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_008e: stelem.ref IL_008f: ldloc 8 IL_0093: ldloc 10 IL_0097: ldtoken [mscorlib]System.Boolean IL_009c: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_00a1: ldloc 9 IL_00a5: newobj instance void LinFu.AOP.Cecil.InvocationInfo::.ctor(object, class [mscorlib]System.Reflection.MethodBase, class [mscorlib]System.Diagnostics.StackTrace, class [mscorlib]System.Type[], class [mscorlib]System.Type[], class [mscorlib]System.Type, object[]) IL_00aa: stloc 2 IL_00ae: ldloc 2 IL_00b2: call void LinFu.AOP.Cecil.IgnoredInstancesRegistry::AddInstance(object) IL_00b7: ldloc 1 IL_00bb: brtrue IL_0149 IL_00c0: ldarg.0 IL_00c1: callvirt instance class LinFu.AOP.Interfaces.IMethodReplacementProvider LinFu.AOP.Interfaces.IMethodReplacementHost::get_MethodBodyReplacementProvider() IL_00c6: stloc 4 IL_00ca: ldarg.0 IL_00cb: isinst LinFu.AOP.Interfaces.IModifiableType IL_00d0: brfalse IL_0148 IL_00d5: ldloc 1 IL_00d9: brtrue IL_0148 IL_00de: ldarg.0 IL_00df: callvirt instance class LinFu.AOP.Interfaces.IMethodReplacementProvider LinFu.AOP.Interfaces.IMethodReplacementHost::get_MethodBodyReplacementProvider() IL_00e4: stloc 3 IL_00e8: ldarg.0 IL_00e9: callvirt instance class LinFu.AOP.Interfaces.IAroundInvokeProvider LinFu.AOP.Interfaces.IAroundInvokeHost::get_AroundMethodBodyProvider() IL_00ee: stloc 4 IL_00f2: ldloc 4 IL_00f6: brfalse IL_010c IL_00fb: ldloc 4 IL_00ff: ldloc 2 IL_0103: callvirt instance class LinFu.AOP.Interfaces.IAroundInvoke LinFu.AOP.Interfaces.IAroundInvokeProvider::GetSurroundingImplementation(class LinFu.AOP.Interfaces.IInvocationInfo) IL_0108: stloc 11 IL_010c: nop IL_010d: ldloc 2 IL_0111: call class LinFu.AOP.Interfaces.IAroundInvoke LinFu.AOP.Interfaces.AroundMethodBodyRegistry::GetSurroundingImplementation(class LinFu.AOP.Interfaces.IInvocationInfo) IL_0116: stloc 12 IL_011a: ldloc 12 IL_011e: brfalse IL_0130 IL_0123: ldloc 12 IL_0127: ldloc 2 IL_012b: callvirt instance void LinFu.AOP.Interfaces.IBeforeInvoke::BeforeInvoke(class LinFu.AOP.Interfaces.IInvocationInfo) IL_0130: nop IL_0131: ldloc 11 IL_0135: brfalse IL_0147 IL_013a: ldloc 11 IL_013e: ldloc 2 IL_0142: callvirt instance void LinFu.AOP.Interfaces.IBeforeInvoke::BeforeInvoke(class LinFu.AOP.Interfaces.IInvocationInfo) IL_0147: nop IL_0148: nop IL_0149: nop IL_014a: nop IL_014b: ldarg.0 IL_014c: ldloc 2 IL_0150: call class LinFu.AOP.Interfaces.IMethodReplacementProvider LinFu.AOP.Interfaces.MethodBodyReplacementProviderRegistry::GetProvider(object, class LinFu.AOP.Interfaces.IInvocationInfo) IL_0155: stloc 6 IL_0159: ldloc 1 IL_015d: brtrue IL_01dc IL_0162: ldloc 3 IL_0166: brtrue IL_0179 IL_016b: ldloc 6 IL_016f: brtrue IL_0179 IL_0174: br IL_01dc IL_0179: nop IL_017a: ldloc 3 IL_017e: brfalse IL_0195 IL_0183: ldloc 3 IL_0187: ldarg.0 IL_0188: ldloc 2 IL_018c: callvirt instance class LinFu.AOP.Interfaces.IInterceptor LinFu.AOP.Interfaces.IMethodReplacementProvider::GetMethodReplacement(object, class LinFu.AOP.Interfaces.IInvocationInfo) IL_0191: stloc 13 IL_0195: nop IL_0196: ldloc 13 IL_019a: brtrue IL_01bb IL_019f: ldloc 6 IL_01a3: brfalse IL_01ba IL_01a8: ldloc 6 IL_01ac: ldarg.0 IL_01ad: ldloc 2 IL_01b1: callvirt instance class LinFu.AOP.Interfaces.IInterceptor LinFu.AOP.Interfaces.IMethodReplacementProvider::GetMethodReplacement(object, class LinFu.AOP.Interfaces.IInvocationInfo) IL_01b6: stloc 13 IL_01ba: nop IL_01bb: nop IL_01bc: ldloc 13 IL_01c0: brfalse IL_01dc IL_01c5: ldloc 13 IL_01c9: ldloc 2 IL_01cd: callvirt instance object LinFu.AOP.Interfaces.IInterceptor::Intercept(class LinFu.AOP.Interfaces.IInvocationInfo) IL_01d2: unbox.any [mscorlib]System.Boolean IL_01d7: br IL_0245 IL_01dc: nop IL_01dd: ldarg.0 IL_01de: ldfld class [System]System.Net.Sockets.Socket Communicator::m_Socket IL_01e3: brfalse IL_023f IL_01e8: ldarg.0 IL_01e9: ldfld class [System]System.Net.Sockets.Socket Communicator::m_Socket IL_01ee: callvirt instance bool [System]System.Net.Sockets.Socket::get_Connected() IL_01f3: brfalse IL_023f IL_01f8: ldarg.0 IL_01f9: call instance bool Communicator::IsServerInfoReceived() IL_01fe: brfalse IL_023f IL_0203: ldarg.1 IL_0204: ldstr "\n" IL_0209: callvirt instance bool [mscorlib]System.String::EndsWith(string) IL_020e: brtrue IL_0220 IL_0213: ldarg.1 IL_0214: ldstr "\n" IL_0219: call string [mscorlib]System.String::Concat(string, string) IL_021e: starg.s 'request' IL_0220: call class [mscorlib]System.Text.Encoding [mscorlib]System.Text.Encoding::get_UTF8() IL_0225: ldarg.1 IL_0226: callvirt instance uint8[] [mscorlib]System.Text.Encoding::GetBytes(string) IL_022b: stloc.0 IL_022c: ldarg.0 IL_022d: ldfld class [System]System.Net.Sockets.Socket Communicator::m_Socket IL_0232: ldloc.0 IL_0233: callvirt instance int32 [System]System.Net.Sockets.Socket::Send(uint8[]) IL_0238: pop IL_0239: ldc.i4.1 IL_023a: br IL_0240 IL_023f: ldc.i4.0 IL_0240: br IL_0245 IL_0245: nop IL_0246: ldloc 1 IL_024a: brtrue IL_0299 IL_024f: ldloc 11 IL_0253: brtrue IL_0258 IL_0258: nop IL_0259: ldloc 11 IL_025d: brfalse IL_0273 IL_0262: ldloc 11 IL_0266: ldloc 2 IL_026a: ldloc 5 IL_026e: callvirt instance void LinFu.AOP.Interfaces.IAfterInvoke::AfterInvoke(class LinFu.AOP.Interfaces.IInvocationInfo, object) IL_0273: nop IL_0274: ldloc 12 IL_0278: brtrue IL_027d IL_027d: nop IL_027e: ldloc 12 IL_0282: brfalse IL_0298 IL_0287: ldloc 12 IL_028b: ldloc 2 IL_028f: ldloc 5 IL_0293: callvirt instance void LinFu.AOP.Interfaces.IAfterInvoke::AfterInvoke(class LinFu.AOP.Interfaces.IInvocationInfo, object) IL_0298: nop IL_0299: nop IL_029a: ldloc 5 IL_029e: ret
} // end of method
The exception I get on runtime looks like this:
ERROR connecting new socket: System.InvalidProgramException: Invalid IL code in Communicator:sendSilentRequest (string): IL_029e: ret at Communicator.sendSilentRequest (.Message msg) [0x00000] in
:0 at Communicator.sendPing () [0x00000] in :0 at Communicator.makeConnection (System.String ip, Int32 port) [0x00000] in :0 I do not really depend on modifying this specific function and may work-around this somehow, however it would be much nicer this way and I do not want to run into this error on methods as well, especially, if it should be my own fault.
Greetings, looking forward to some answers, Victor Brekenfeld
Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23 .
[IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::sendSilentRequest][offset 0x000000E4][found ref 'LinFu.AOP.Interfaces.IMethodReplacementProvider'][expected ref 'LinFu.AOP.Interfaces.IAroundInvokeProvider'] Unexpected type on the stack.
[IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::sendSilentRequest][offset 0x000000EE][found ref 'LinFu.AOP.Interfaces.IAroundInvokeProvider'][expected ref 'LinFu.AOP.Interfaces.IMethodReplacementProvider'] Unexpected type on the stack.
[IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::sendSilentRequest][offset 0x00000103][found ref 'LinFu.AOP.Interfaces.IMethodReplacementProvider'][expected ref 'LinFu.AOP.Interfaces.IAroundInvokeProvider'] Unexpected type on the stack.
[IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::sendSilentRequest][offset 0x0000018C][found ref 'LinFu.AOP.Interfaces.IAroundInvokeProvider'][expected ref 'LinFu.AOP.Interfaces.IMethodReplacementProvider'] Unexpected type on the stack.
[IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::sendSilentRequest][offset 0x0000029E] Stack must contain only the return value.
I guess the last error is the one that crashes my app.
Hmm. Are you using method body replacement and the IAroundInvoke options at the same time? Have you tried using just method body replacement?
On Sun, May 26, 2013 at 9:47 PM, Drakulix notifications@github.com wrote:
[IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::sendSilentRequest][offset 0x000000E4][found ref 'LinFu.AOP.Interfaces.IMethodReplacementProvider'][expected ref 'LinFu.AOP.Interfaces.IAroundInvokeProvider'] Unexpected type on the stack. [IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::sendSilentRequest][offset 0x000000EE][found ref 'LinFu.AOP.Interfaces.IAroundInvokeProvider'][expected ref 'LinFu.AOP.Interfaces.IMethodReplacementProvider'] Unexpected type on the stack. [IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::sendSilentRequest][offset 0x00000103][found ref 'LinFu.AOP.Interfaces.IMethodReplacementProvider'][expected ref 'LinFu.AOP.Interfaces.IAroundInvokeProvider'] Unexpected type on the stack. [IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::sendSilentRequest][offset 0x0000018C][found ref 'LinFu.AOP.Interfaces.IAroundInvokeProvider'][expected ref 'LinFu.AOP.Interfaces.IMethodReplacementProvider'] Unexpected type on the stack. [IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::sendSilentRequest][offset 0x0000029E] Stack must contain only the return value.
I guess the last error is the one that crashes my app.
— Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23#issuecomment-18461863 .
No, I am not. I am just calling InterceptMethodBody on the assembly with a method filter and at runtime I use MethodBodyReplacementProviderRegistry.SetProvider(provider) to get the callback. Nothing else.
OK, Can you show me the complete solution with the code that you're using to weave the assembly so that I can take a look?
On Mon, May 27, 2013 at 4:52 AM, Drakulix notifications@github.com wrote:
No, I am not. I am just calling InterceptMethodBody on the assembly with a method filter and at runtime I use MethodBodyReplacementProviderRegistry.SetProvider(provider) to get the callback. Nothing else.
— Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23#issuecomment-18467637 .
Sure, it is on a public repository of myself. The weaving happens at the last function in here (weaveAssembly): https://github.com/Drakulix/ScrollsModLoader/blob/master/Patcher.cs
I made a small modification to allow filtering not only by method but also by file type, which you may find here: https://github.com/Drakulix/ScrollsModLoader/blob/master/LinFu-master/src/LinFu.AOP/Extensions/MethodBodyInterceptionExtensions.cs
I have introduced that little extension, after I had already encountered that issue described, so that should not matter. In case you ask yourself, why I did that: The Assembly I am modifying contains Types, that are converted to JSON Strings and some of the fields added by LinFu, would otherwise appear in the JSON Strings, even if I do not modify a single method in its type.
Any idea what causes this?
If you look at the local variables, you'll notice that LinFu is trying to store an IMethodReplacmentProvider into an IAroundInvokeProvider local variable, which is causing PEVerify to fail. It's definitely caused by a typing problem.
Well, not on my side. I do only weave them and set an MethodReplaceProvider in the Registry, I do not mess with these variables at all. I have also encountered an issue when trying to Intercept a static method using the BaseMethodReplacementProvider, as it fails on GetPending calls, because context.Target is null, although intercepting static methods, is clearly offered as feature. I was only able to work around that bug, through making a complete replacement provider on my own.
Do you maybe have a more stable (older) version of the Framework (preferably with source code)? The latest GitHub checkout, seems to be a bit buggy to me.
Sorry for double posting, but I have some progress. This commit, fixed the wrong IMethodReplacementProvider and IAroundInvokeProvider assignments: https://github.com/dmagyari/LinFu/commit/bf5a101d4a2634b6c1ec717023bb60e2771420b6
These errors are also gone in the PEVerify log, however the last line and the resulting Invalid IL code exception still remain.
So PEVerify reports no errors?
On Mon, Jun 3, 2013 at 7:40 PM, Drakulix notifications@github.com wrote:
Sorry for double posting, but I have some progress. This commit, fixed the wrong IMethodReplacementProvider and IAroundInvokeProvider assignments: dmagyari@bf5a101https://github.com/dmagyari/LinFu/commit/bf5a101d4a2634b6c1ec717023bb60e2771420b6
These errors are also gone in the PEVerify log, however the last line and the resulting Invalid IL code exception still remain.
— Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23#issuecomment-18830904 .
Yes, it seems to be completely valid. Might it be an issue of the Mono Runtime? And is there probably a way to work around that? because I have no influence on the runtime used.
Is it only for bool return types, or does this also apply to other value types? I suspect that this has nothing to do with the runtime being used as much as it is with the IL being generated.
On Mon, Jun 3, 2013 at 9:33 PM, Drakulix notifications@github.com wrote:
Yes, it seems to be completely valid. Might it be an issue of the Mono Runtime? And is there probably a way to work around that, because I have no influence on the runtime used? Also I can verify, that this issue only happens, if the function returns a bool type variable.
— Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23#issuecomment-18835385 .
I just did a quick test with a function returning a string. It also gives an invalid IL Exception. Normally that function only returns this.username. The weaved code follows. Should not normally, the object value be assigned from the return of the Intercept call? And should not the old body return normally?
C#
public string getUserScreenName ()
{
bool isInterceptionDisabled;
if (this is IModifiableType)
{
isInterceptionDisabled = (this as IModifiableType).IsInterceptionDisabled;
}
IInvocationInfo invocationInfo;
IMethodReplacementProvider methodBodyReplacementProvider;
IAroundInvoke surroundingImplementation;
IAroundInvoke surroundingImplementation2;
if (!isInterceptionDisabled)
{
Type[] typeArguments = new Type[0];
object[] arguments = new object[0];
MethodBase methodFromHandle = MethodBase.GetMethodFromHandle (methodof (Communicator.getUserScreenName ()).MethodHandle, typeof(Communicator).TypeHandle);
MethodBase arg_83_1 = methodFromHandle;
StackTrace arg_83_2 = new StackTrace (1, false);
Type[] parameterTypes = new Type[0];
invocationInfo = new InvocationInfo (this, arg_83_1, arg_83_2, parameterTypes, typeArguments, typeof(string), arguments);
IgnoredInstancesRegistry.AddInstance (invocationInfo);
if (!isInterceptionDisabled)
{
methodBodyReplacementProvider = ((IMethodReplacementHost)this).MethodBodyReplacementProvider;
if (this is IModifiableType && !isInterceptionDisabled)
{
methodBodyReplacementProvider = ((IMethodReplacementHost)this).MethodBodyReplacementProvider;
IAroundInvokeProvider aroundMethodBodyProvider = ((IAroundInvokeHost)this).AroundMethodBodyProvider;
if (aroundMethodBodyProvider != null)
{
surroundingImplementation = aroundMethodBodyProvider.GetSurroundingImplementation (invocationInfo);
}
surroundingImplementation2 = AroundMethodBodyRegistry.GetSurroundingImplementation (invocationInfo);
if (surroundingImplementation2 != null)
{
surroundingImplementation2.BeforeInvoke (invocationInfo);
}
if (surroundingImplementation != null)
{
surroundingImplementation.BeforeInvoke (invocationInfo);
}
}
}
}
IMethodReplacementProvider provider = MethodBodyReplacementProviderRegistry.GetProvider (this, invocationInfo);
if (!isInterceptionDisabled)
{
if (methodBodyReplacementProvider != null || provider != null)
{
IInterceptor methodReplacement;
if (methodBodyReplacementProvider != null)
{
methodReplacement = methodBodyReplacementProvider.GetMethodReplacement (this, invocationInfo);
}
if (methodReplacement == null)
{
if (provider != null)
{
methodReplacement = provider.GetMethodReplacement (this, invocationInfo);
}
}
if (methodReplacement != null)
{
(string)methodReplacement.Intercept (invocationInfo);
goto IL_1C6;
}
}
}
this.username;
IL_1C6:
object obj;
if (!isInterceptionDisabled)
{
if (surroundingImplementation == null)
{
}
if (surroundingImplementation != null)
{
surroundingImplementation.AfterInvoke (invocationInfo, obj);
}
if (surroundingImplementation2 == null)
{
}
if (surroundingImplementation2 != null)
{
surroundingImplementation2.AfterInvoke (invocationInfo, obj);
}
}
return obj;
}
IL
.method public hidebysig
instance string getUserScreenName () cil managed
{
// Method begins at RVA 0x1beb4
// Code size 544 (0x220)
.maxstack 8
.locals init (
[0] bool,
[1] class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo,
[2] class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvokeProvider,
[3] class [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider,
[4] object,
[5] class [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider,
[6] class [mscorlib]System.Reflection.MethodBase,
[7] class [mscorlib]System.Type[],
[8] object[],
[9] class [mscorlib]System.Type[],
[10] class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvoke,
[11] class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvoke,
[12] class [ScrollsModLoader]LinFu.AOP.Interfaces.IInterceptor
)
IL_0000: ldarg.0
IL_0001: isinst [ScrollsModLoader]LinFu.AOP.Interfaces.IModifiableType
IL_0006: brfalse IL_001a
IL_000b: ldarg.0
IL_000c: isinst [ScrollsModLoader]LinFu.AOP.Interfaces.IModifiableType
IL_0011: callvirt instance bool [ScrollsModLoader]LinFu.AOP.Interfaces.IModifiableType::get_IsInterceptionDisabled()
IL_0016: stloc 0
IL_001a: nop
IL_001b: ldloc 0
IL_001f: brtrue IL_0128
IL_0024: ldc.i4 0
IL_0029: newarr [mscorlib]System.Type
IL_002e: stloc 9
IL_0032: ldc.i4 0
IL_0037: newarr [mscorlib]System.Object
IL_003c: stloc 8
IL_0040: ldarg.0
IL_0041: ldtoken method instance string Communicator::getUserScreenName()
IL_0046: ldtoken Communicator
IL_004b: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle, valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0050: stloc 6
IL_0054: ldloc 6
IL_0058: ldc.i4.1
IL_0059: ldc.i4.0
IL_005a: newobj instance void [mscorlib]System.Diagnostics.StackTrace::.ctor(int32, bool)
IL_005f: ldc.i4 0
IL_0064: newarr [mscorlib]System.Type
IL_0069: stloc 7
IL_006d: ldloc 7
IL_0071: ldloc 9
IL_0075: ldtoken [mscorlib]System.String
IL_007a: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_007f: ldloc 8
IL_0083: newobj instance void [ScrollsModLoader]LinFu.AOP.Cecil.InvocationInfo::.ctor(object, class [mscorlib]System.Reflection.MethodBase, class [mscorlib]System.Diagnostics.StackTrace, class [mscorlib]System.Type[], class [mscorlib]System.Type[], class [mscorlib]System.Type, object[])
IL_0088: stloc 1
IL_008c: ldloc 1
IL_0090: call void [ScrollsModLoader]LinFu.AOP.Cecil.IgnoredInstancesRegistry::AddInstance(object)
IL_0095: ldloc 0
IL_0099: brtrue IL_0127
IL_009e: ldarg.0
IL_009f: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementHost::get_MethodBodyReplacementProvider()
IL_00a4: stloc 3
IL_00a8: ldarg.0
IL_00a9: isinst [ScrollsModLoader]LinFu.AOP.Interfaces.IModifiableType
IL_00ae: brfalse IL_0126
IL_00b3: ldloc 0
IL_00b7: brtrue IL_0126
IL_00bc: ldarg.0
IL_00bd: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementHost::get_MethodBodyReplacementProvider()
IL_00c2: stloc 3
IL_00c6: ldarg.0
IL_00c7: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvokeProvider [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvokeHost::get_AroundMethodBodyProvider()
IL_00cc: stloc 2
IL_00d0: ldloc 2
IL_00d4: brfalse IL_00ea
IL_00d9: ldloc 2
IL_00dd: ldloc 1
IL_00e1: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvoke [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvokeProvider::GetSurroundingImplementation(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo)
IL_00e6: stloc 10
IL_00ea: nop
IL_00eb: ldloc 1
IL_00ef: call class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvoke [ScrollsModLoader]LinFu.AOP.Interfaces.AroundMethodBodyRegistry::GetSurroundingImplementation(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo)
IL_00f4: stloc 11
IL_00f8: ldloc 11
IL_00fc: brfalse IL_010e
IL_0101: ldloc 11
IL_0105: ldloc 1
IL_0109: callvirt instance void [ScrollsModLoader]LinFu.AOP.Interfaces.IBeforeInvoke::BeforeInvoke(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo)
IL_010e: nop
IL_010f: ldloc 10
IL_0113: brfalse IL_0125
IL_0118: ldloc 10
IL_011c: ldloc 1
IL_0120: callvirt instance void [ScrollsModLoader]LinFu.AOP.Interfaces.IBeforeInvoke::BeforeInvoke(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo)
IL_0125: nop
IL_0126: nop
IL_0127: nop
IL_0128: nop
IL_0129: ldarg.0
IL_012a: ldloc 1
IL_012e: call class [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider [ScrollsModLoader]LinFu.AOP.Interfaces.MethodBodyReplacementProviderRegistry::GetProvider(object, class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo)
IL_0133: stloc 5
IL_0137: ldloc 0
IL_013b: brtrue IL_01ba
IL_0140: ldloc 3
IL_0144: brtrue IL_0157
IL_0149: ldloc 5
IL_014d: brtrue IL_0157
IL_0152: br IL_01ba
IL_0157: nop
IL_0158: ldloc 3
IL_015c: brfalse IL_0173
IL_0161: ldloc 3
IL_0165: ldarg.0
IL_0166: ldloc 1
IL_016a: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IInterceptor [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider::GetMethodReplacement(object, class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo)
IL_016f: stloc 12
IL_0173: nop
IL_0174: ldloc 12
IL_0178: brtrue IL_0199
IL_017d: ldloc 5
IL_0181: brfalse IL_0198
IL_0186: ldloc 5
IL_018a: ldarg.0
IL_018b: ldloc 1
IL_018f: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IInterceptor [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider::GetMethodReplacement(object, class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo)
IL_0194: stloc 12
IL_0198: nop
IL_0199: nop
IL_019a: ldloc 12
IL_019e: brfalse IL_01ba
IL_01a3: ldloc 12
IL_01a7: ldloc 1
IL_01ab: callvirt instance object [ScrollsModLoader]LinFu.AOP.Interfaces.IInterceptor::Intercept(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo)
IL_01b0: unbox.any [mscorlib]System.String
IL_01b5: br IL_01c6
IL_01ba: nop
IL_01bb: ldarg.0
IL_01bc: ldfld string Communicator::username
IL_01c1: br IL_01c6
IL_01c6: nop
IL_01c7: ldloc 0
IL_01cb: brtrue IL_021a
IL_01d0: ldloc 10
IL_01d4: brtrue IL_01d9
IL_01d9: nop
IL_01da: ldloc 10
IL_01de: brfalse IL_01f4
IL_01e3: ldloc 10
IL_01e7: ldloc 1
IL_01eb: ldloc 4
IL_01ef: callvirt instance void [ScrollsModLoader]LinFu.AOP.Interfaces.IAfterInvoke::AfterInvoke(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo, object)
IL_01f4: nop
IL_01f5: ldloc 11
IL_01f9: brtrue IL_01fe
IL_01fe: nop
IL_01ff: ldloc 11
IL_0203: brfalse IL_0219
IL_0208: ldloc 11
IL_020c: ldloc 1
IL_0210: ldloc 4
IL_0214: callvirt instance void [ScrollsModLoader]LinFu.AOP.Interfaces.IAfterInvoke::AfterInvoke(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo, object)
IL_0219: nop
IL_021a: nop
IL_021b: ldloc 4
IL_021f: ret
}
What does PEVerify say?
On Mon, Jun 3, 2013 at 9:45 PM, Drakulix notifications@github.com wrote:
I just did a quick test with a function returning a string. It also gives an invalid IL Exception. Normally that function only returns this.username. The weaved code follows. Should not normally, the object value be assigned from the return of the Intercept call? And should not the old body return normally?
C#
public string getUserScreenName () { bool isInterceptionDisabled; if (this is IModifiableType) { isInterceptionDisabled = (this as IModifiableType).IsInterceptionDisabled; } IInvocationInfo invocationInfo; IMethodReplacementProvider methodBodyReplacementProvider; IAroundInvoke surroundingImplementation; IAroundInvoke surroundingImplementation2; if (!isInterceptionDisabled) { Type[] typeArguments = new Type[0]; object[] arguments = new object[0]; MethodBase methodFromHandle = MethodBase.GetMethodFromHandle (methodof (Communicator.getUserScreenName ()).MethodHandle, typeof(Communicator).TypeHandle); MethodBase arg_83_1 = methodFromHandle; StackTrace arg_83_2 = new StackTrace (1, false); Type[] parameterTypes = new Type[0]; invocationInfo = new InvocationInfo (this, arg_83_1, arg_83_2, parameterTypes, typeArguments, typeof(string), arguments); IgnoredInstancesRegistry.AddInstance (invocationInfo); if (!isInterceptionDisabled) { methodBodyReplacementProvider = ((IMethodReplacementHost)this).MethodBodyReplacementProvider; if (this is IModifiableType && !isInterceptionDisabled) { methodBodyReplacementProvider = ((IMethodReplacementHost)this).MethodBodyReplacementProvider; IAroundInvokeProvider aroundMethodBodyProvider = ((IAroundInvokeHost)this).AroundMethodBodyProvider; if (aroundMethodBodyProvider != null) { surroundingImplementation = aroundMethodBodyProvider.GetSurroundingImplementation (invocationInfo); } surroundingImplementation2 = AroundMethodBodyRegistry.GetSurroundingImplementation (invocationInfo); if (surroundingImplementation2 != null) { surroundingImplementation2.BeforeInvoke (invocationInfo); } if (surroundingImplementation != null) { surroundingImplementation.BeforeInvoke (invocationInfo); } } } } IMethodReplacementProvider provider = MethodBodyReplacementProviderRegistry.GetProvider (this, invocationInfo); if (!isInterceptionDisabled) { if (methodBodyReplacementProvider != null || provider != null) { IInterceptor methodReplacement; if (methodBodyReplacementProvider != null) { methodReplacement = methodBodyReplacementProvider.GetMethodReplacement (this, invocationInfo); } if (methodReplacement == null) { if (provider != null) { methodReplacement = provider.GetMethodReplacement (this, invocationInfo); } } if (methodReplacement != null) { (string)methodReplacement.Intercept (invocationInfo); goto IL_1C6; } } } this.username; IL_1C6: object obj; if (!isInterceptionDisabled) { if (surroundingImplementation == null) { } if (surroundingImplementation != null) { surroundingImplementation.AfterInvoke (invocationInfo, obj); } if (surroundingImplementation2 == null) { } if (surroundingImplementation2 != null) { surroundingImplementation2.AfterInvoke (invocationInfo, obj); } } return obj; }
IL
.method public hidebysig instance string getUserScreenName () cil managed { // Method begins at RVA 0x1beb4 // Code size 544 (0x220) .maxstack 8 .locals init ( [0] bool, [1] class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo, [2] class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvokeProvider, [3] class [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider, [4] object, [5] class [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider, [6] class [mscorlib]System.Reflection.MethodBase, [7] class [mscorlib]System.Type[], [8] object[], [9] class [mscorlib]System.Type[], [10] class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvoke, [11] class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvoke, [12] class [ScrollsModLoader]LinFu.AOP.Interfaces.IInterceptor )
IL_0000: ldarg.0 IL_0001: isinst [ScrollsModLoader]LinFu.AOP.Interfaces.IModifiableType IL_0006: brfalse IL_001a IL_000b: ldarg.0 IL_000c: isinst [ScrollsModLoader]LinFu.AOP.Interfaces.IModifiableType IL_0011: callvirt instance bool [ScrollsModLoader]LinFu.AOP.Interfaces.IModifiableType::get_IsInterceptionDisabled() IL_0016: stloc 0 IL_001a: nop IL_001b: ldloc 0 IL_001f: brtrue IL_0128 IL_0024: ldc.i4 0 IL_0029: newarr [mscorlib]System.Type IL_002e: stloc 9 IL_0032: ldc.i4 0 IL_0037: newarr [mscorlib]System.Object IL_003c: stloc 8 IL_0040: ldarg.0 IL_0041: ldtoken method instance string Communicator::getUserScreenName() IL_0046: ldtoken Communicator IL_004b: call class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle, valuetype [mscorlib]System.RuntimeTypeHandle) IL_0050: stloc 6 IL_0054: ldloc 6 IL_0058: ldc.i4.1 IL_0059: ldc.i4.0 IL_005a: newobj instance void [mscorlib]System.Diagnostics.StackTrace::.ctor(int32, bool) IL_005f: ldc.i4 0 IL_0064: newarr [mscorlib]System.Type IL_0069: stloc 7 IL_006d: ldloc 7 IL_0071: ldloc 9 IL_0075: ldtoken [mscorlib]System.String IL_007a: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_007f: ldloc 8 IL_0083: newobj instance void [ScrollsModLoader]LinFu.AOP.Cecil.InvocationInfo::.ctor(object, class [mscorlib]System.Reflection.MethodBase, class [mscorlib]System.Diagnostics.StackTrace, class [mscorlib]System.Type[], class [mscorlib]System.Type[], class [mscorlib]System.Type, object[]) IL_0088: stloc 1 IL_008c: ldloc 1 IL_0090: call void [ScrollsModLoader]LinFu.AOP.Cecil.IgnoredInstancesRegistry::AddInstance(object) IL_0095: ldloc 0 IL_0099: brtrue IL_0127 IL_009e: ldarg.0 IL_009f: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementHost::get_MethodBodyReplacementProvider() IL_00a4: stloc 3 IL_00a8: ldarg.0 IL_00a9: isinst [ScrollsModLoader]LinFu.AOP.Interfaces.IModifiableType IL_00ae: brfalse IL_0126 IL_00b3: ldloc 0 IL_00b7: brtrue IL_0126 IL_00bc: ldarg.0 IL_00bd: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementHost::get_MethodBodyReplacementProvider() IL_00c2: stloc 3 IL_00c6: ldarg.0 IL_00c7: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvokeProvider [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvokeHost::get_AroundMethodBodyProvider() IL_00cc: stloc 2 IL_00d0: ldloc 2 IL_00d4: brfalse IL_00ea IL_00d9: ldloc 2 IL_00dd: ldloc 1 IL_00e1: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvoke [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvokeProvider::GetSurroundingImplementation(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo) IL_00e6: stloc 10 IL_00ea: nop IL_00eb: ldloc 1 IL_00ef: call class [ScrollsModLoader]LinFu.AOP.Interfaces.IAroundInvoke [ScrollsModLoader]LinFu.AOP.Interfaces.AroundMethodBodyRegistry::GetSurroundingImplementation(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo) IL_00f4: stloc 11 IL_00f8: ldloc 11 IL_00fc: brfalse IL_010e IL_0101: ldloc 11 IL_0105: ldloc 1 IL_0109: callvirt instance void [ScrollsModLoader]LinFu.AOP.Interfaces.IBeforeInvoke::BeforeInvoke(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo) IL_010e: nop IL_010f: ldloc 10 IL_0113: brfalse IL_0125 IL_0118: ldloc 10 IL_011c: ldloc 1 IL_0120: callvirt instance void [ScrollsModLoader]LinFu.AOP.Interfaces.IBeforeInvoke::BeforeInvoke(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo) IL_0125: nop IL_0126: nop IL_0127: nop IL_0128: nop IL_0129: ldarg.0 IL_012a: ldloc 1 IL_012e: call class [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider [ScrollsModLoader]LinFu.AOP.Interfaces.MethodBodyReplacementProviderRegistry::GetProvider(object, class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo) IL_0133: stloc 5 IL_0137: ldloc 0 IL_013b: brtrue IL_01ba IL_0140: ldloc 3 IL_0144: brtrue IL_0157 IL_0149: ldloc 5 IL_014d: brtrue IL_0157 IL_0152: br IL_01ba IL_0157: nop IL_0158: ldloc 3 IL_015c: brfalse IL_0173 IL_0161: ldloc 3 IL_0165: ldarg.0 IL_0166: ldloc 1 IL_016a: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IInterceptor [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider::GetMethodReplacement(object, class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo) IL_016f: stloc 12 IL_0173: nop IL_0174: ldloc 12 IL_0178: brtrue IL_0199 IL_017d: ldloc 5 IL_0181: brfalse IL_0198 IL_0186: ldloc 5 IL_018a: ldarg.0 IL_018b: ldloc 1 IL_018f: callvirt instance class [ScrollsModLoader]LinFu.AOP.Interfaces.IInterceptor [ScrollsModLoader]LinFu.AOP.Interfaces.IMethodReplacementProvider::GetMethodReplacement(object, class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo) IL_0194: stloc 12 IL_0198: nop IL_0199: nop IL_019a: ldloc 12 IL_019e: brfalse IL_01ba IL_01a3: ldloc 12 IL_01a7: ldloc 1 IL_01ab: callvirt instance object [ScrollsModLoader]LinFu.AOP.Interfaces.IInterceptor::Intercept(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo) IL_01b0: unbox.any [mscorlib]System.String IL_01b5: br IL_01c6 IL_01ba: nop IL_01bb: ldarg.0 IL_01bc: ldfld string Communicator::username IL_01c1: br IL_01c6 IL_01c6: nop IL_01c7: ldloc 0 IL_01cb: brtrue IL_021a IL_01d0: ldloc 10 IL_01d4: brtrue IL_01d9 IL_01d9: nop IL_01da: ldloc 10 IL_01de: brfalse IL_01f4 IL_01e3: ldloc 10 IL_01e7: ldloc 1 IL_01eb: ldloc 4 IL_01ef: callvirt instance void [ScrollsModLoader]LinFu.AOP.Interfaces.IAfterInvoke::AfterInvoke(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo, object) IL_01f4: nop IL_01f5: ldloc 11 IL_01f9: brtrue IL_01fe IL_01fe: nop IL_01ff: ldloc 11 IL_0203: brfalse IL_0219 IL_0208: ldloc 11 IL_020c: ldloc 1 IL_0210: ldloc 4 IL_0214: callvirt instance void [ScrollsModLoader]LinFu.AOP.Interfaces.IAfterInvoke::AfterInvoke(class [ScrollsModLoader]LinFu.AOP.Interfaces.IInvocationInfo, object) IL_0219: nop IL_021a: nop IL_021b: ldloc 4 IL_021f: ret
}
Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23#issuecomment-18835911 .
[IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::getUserScreenName][ offset 0x0000021F] Stack must contain only the return value. 1 Fehler wird/werden ¸berpr¸ft Assembly-CSharp.dll
Can you give me the dump of the IL for that method?
On Mon, Jun 3, 2013 at 9:57 PM, Drakulix notifications@github.com wrote:
[IL]: Error: [E:\Managed\Assembly-CSharp.dll : Communicator::getUserScreenName][ offset 0x0000021F] Stack must contain only the return value. 1 Fehler wird/werden ¸berpr¸ft Assembly-CSharp.dll
— Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23#issuecomment-18836351 .
already attached. See my last but one comment.
btw, this seems to be quite similar to this report: https://github.com/philiplaureano/LinFu/issues/8
Actually he describes nearly the same, just not the crash with an Invalid IL Exception, which might be only happening on my end, because of using mono instead of .net.
Have you reproduced it in both runtimes? On 05/06/2013 6:06 AM, "Drakulix" notifications@github.com wrote:
btw, this seems to be quite similar to this report:
8 https://github.com/philiplaureano/LinFu/issues/8
Actually he describes nearly the same, just not the crash with an Invalid IL Exception, which might be only happening on my end, because of using mono instead of .net.
— Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23#issuecomment-18942710 .
No I cannot test it in .net, as the assembly gets loaded by a third party engine, which uses an embedded mono runtime.
Hmm. Is there any way you can copy some of the properties over to a small sample solution/console app with LinFu.AOP and run it in .NET?
On Wed, Jun 5, 2013 at 5:54 PM, Drakulix notifications@github.com wrote:
No I cannot test it in .net, as the assembly gets loaded by a third party engine, which uses an embedded mono runtime.
— Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23#issuecomment-18960730 .
I can write a little test assembly, that returns a hardcoded value instead on that function. I will post the result once its done.
Okay so on Mono I get this Exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidProgramException: Invalid IL code in ReturnTest.MainClass:getUserScreenName (): IL_0227: ret
at ReturnTest.MainClass.Main (System.String[] args) [0x00000] in <filename unknown>:0
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00054] in /private/tmp/source/bockbuild-crypto-mono/profiles/mono-mac-xamarin/build-root/mono-3.0.10/mcs/class/corlib/System.Reflection/MonoMethod.cs:230
--- End of inner exception stack trace ---
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00069] in /private/tmp/source/bockbuild-crypto-mono/profiles/mono-mac-xamarin/build-root/mono-3.0.10/mcs/class/corlib/System.Reflection/MonoMethod.cs:238
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in /private/tmp/source/bockbuild-crypto-mono/profiles/mono-mac-xamarin/build-root/mono-3.0.10/mcs/class/corlib/System.Reflection/MethodBase.cs:114
at ReturnTestInjector.Injector.Main (System.String[] args) [0x00055] in /Users/Drakulix/Projects/ScrollsModLoader/ReturnTestInjector/Injector.cs:51
With .net I get this (quite similar):
System.Reflection.TargetInvocationException: Exception has been thrown by the ta
rget of an invocation. ---> System.InvalidProgramException: JIT Compiler encount
ered an internal limitation.
at ReturnTest.MainClass.getUserScreenName()
at ReturnTest.MainClass.Main(String[] args)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] argum
ents, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle
typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] argume
nts, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwn
er)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invoke
Attr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisib
ilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invoke
Attr, Binder binder, Object[] parameters, CultureInfo culture)
at ReturnTestInjector.Injector.Main(String[] args)
(Note to self: I seriously need to rewrite this library)
On Wed, Jun 5, 2013 at 6:52 PM, Drakulix notifications@github.com wrote:
Okay so on Mono I get this Exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidProgramException: Invalid IL code in ReturnTest.MainClass:getUserScreenName (): IL_0227: ret
at ReturnTest.MainClass.Main (System.String[] args) [0x00000] in
:0 at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00054] in /private/tmp/source/bockbuild-crypto-mono/profiles/mono-mac-xamarin/build-root/mono-3.0.10/mcs/class/corlib/System.Reflection/MonoMethod.cs:230 --- End of inner exception stack trace --- at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00069] in /private/tmp/source/bockbuild-crypto-mono/profiles/mono-mac-xamarin/build-root/mono-3.0.10/mcs/class/corlib/System.Reflection/MonoMethod.cs:238 at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in /private/tmp/source/bockbuild-crypto-mono/profiles/mono-mac-xamarin/build-root/mono-3.0.10/mcs/class/corlib/System.Reflection/MethodBase.cs:114 at ReturnTestInjector.Injector.Main (System.String[] args) [0x00055] in /Users/Drakulix/Projects/ScrollsModLoader/ReturnTestInjector/Injector.cs:51 With .net I get this (quite similar):
System.Reflection.TargetInvocationException: Exception has been thrown by the ta rget of an invocation. ---> System.InvalidProgramException: JIT Compiler encount ered an internal limitation. at ReturnTest.MainClass.getUserScreenName() at ReturnTest.MainClass.Main(String[] args) --- End of inner exception stack trace --- at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] argum ents, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] argume nts, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwn er) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invoke Attr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisib ilityChecks) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invoke Attr, Binder binder, Object[] parameters, CultureInfo culture) at ReturnTestInjector.Injector.Main(String[] args)
— Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23#issuecomment-18963050 .
Probably, but I don't want judge about that. I am fine, as I was able to work around mostly every bug, but not this one. So a quick and dirty fix would be just fine. I really do not want to fallback to the 1.0 version of this framework.
So from the code perspective, all thats necessary is adding the correct assignment to this value to contain the initial return value: IL_1C6: object obj;
How difficult would that be?
Actually, it's not difficult. I have to admit that I haven't touched the framework in years, but what I do remember is that there's really only one of three things you need to do to make this work:
1) Pop the value off the stack (if it has a void return type) 2) Push the value onto the stack and cast it to the correct object type 3) Load the local variable that contains the return value onto the stack and cast it to the return type.
In theory, it's a very simple fix, but personally I'm not too happy with this framework since it was written in an era where I barely used TDD at all, and it's brittle at best.
On Wed, Jun 5, 2013 at 10:04 PM, Drakulix notifications@github.com wrote:
Probably, but I don't want judge about that. I am fine, as I was able to work around mostly every bug, but not this one. So a quick and dirty fix would be just fine. I really do not want to fallback to the 1.0 version of this framework.
So from the code perspective, all thats necessary is adding the correct assignment to this value to contain the initial return value: IL_1C6: object obj;
How difficult would that be?
— Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23#issuecomment-18971218 .
I know that feeling from my own projects, however that does not help me at all. I have decided to base my own on this library, once I found your article at code-project and now, I really do not have the time to wait, until you may have rewritten a version 3.0. It would be nice to have a final statement, if you are going to do this little fix sometime soon, or at least recommend me some alternatives. I do not want to demand anything, but if the issue does not get resolved, your framework does sadly not fit my needs, although I really liked to use those easy Interfaces.
OK, send me the smallest possible project/solution that reproduces the bug and I'll look into it as soon as possible.
On Thu, Jun 6, 2013 at 12:13 AM, Drakulix notifications@github.com wrote:
I know that feeling from my own projects, however that does not help me at all. I have decided to base my own on this library, once I found your article at code-project and now, I really do not have the time to wait, until you may have rewritten a version 3.0. It would be nice to have a final statement, if you are going to do this little fix sometime soon, or at least recommend me some alternatives. I do not want to demand anything, but if the issue does not get resolved, your framework does sadly not fit my needs, although I really liked to use those easy Interfaces.
— Reply to this email directly or view it on GitHubhttps://github.com/philiplaureano/LinFu/issues/23#issuecomment-18978052 .
sure, here you go:
https://dl.dropboxusercontent.com/u/46559498/ReturnTest.zip
The ReturnTestInject executable expects the path of the Target as argument.
Works nicely, thanks!
First of all, thanks for this lovely framework. However I am having some issues using this framework, which are hopefully easy to fix and probably my own fault of miss-using this wonderful framework. I am quite an experienced Hobby-Programmer, however I have not worked too much with assembly code in general and found Mono.Cecil to be it quite difficult to use, if you want to achieve more complex results, besides adding some static method calls, so I was very happy that I found this on codeProject.com.
I am trying to inject some smaller code into an already compiled assembly, so I am using PostWeaver.exe. I tried weaving the complete assembly at the beginning, however that failed horribly with lots of exceptions, when running the resulting assembly, which was expected since the assembly is a really complex one, with lots of native library bindings. Which is why I started to weave only filtered method bodies and nothing else, but that should not be the problem, right?
I can modify methods returning void or objects quite well, however I run into problems when I want to edit a method returning a 'bool'. I have not tried to extend a wide range of methods, so I am not sure if this might also happen on other 'primitive' types.
The code of the to be modified assembly looks like this before weaving:
C#
IL
After Weaving it looks like this:
C#
IL
The exception I get on runtime looks like this:
I do not really depend on modifying this specific function and may work-around this somehow, however it would be much nicer this way and I do not want to run into this error on methods as well, especially, if it should be my own fault.
Greetings, looking forward to some answers, Victor Brekenfeld