philiplaureano / LinFu

A framework that adds mixins, inversion of control, DbC, and other language features to the Common Language Runtime.
http://www.codeproject.com/KB/cs/LinFuPart1.aspx
206 stars 30 forks source link

LinFu.AOP MethodBodyReplacement producing Invalid IL code #23

Closed Drakulix closed 11 years ago

Drakulix commented 11 years ago

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 <filename unknown>:0 
  at Communicator.sendPing () [0x00000] in <filename unknown>:0 
  at Communicator.makeConnection (System.String ip, Int32 port) [0x00000] in <filename unknown>: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

philiplaureano commented 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 .

Drakulix commented 11 years ago
[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.

philiplaureano commented 11 years ago

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 .

Drakulix commented 11 years ago

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.

philiplaureano commented 11 years ago

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 .

Drakulix commented 11 years ago

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.

Drakulix commented 11 years ago

Any idea what causes this?

philiplaureano commented 11 years ago

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.

Drakulix commented 11 years ago

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.

Drakulix commented 11 years ago

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.

philiplaureano commented 11 years ago

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 .

Drakulix commented 11 years ago

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.

philiplaureano commented 11 years ago

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 .

Drakulix commented 11 years ago

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
}
philiplaureano commented 11 years ago

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 .

Drakulix commented 11 years ago

[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

philiplaureano commented 11 years ago

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 .

Drakulix commented 11 years ago

already attached. See my last but one comment.

Drakulix commented 11 years ago

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.

philiplaureano commented 11 years ago

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 .

Drakulix commented 11 years ago

No I cannot test it in .net, as the assembly gets loaded by a third party engine, which uses an embedded mono runtime.

philiplaureano commented 11 years ago

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 .

Drakulix commented 11 years ago

I can write a little test assembly, that returns a hardcoded value instead on that function. I will post the result once its done.

Drakulix commented 11 years ago

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)
philiplaureano commented 11 years ago

(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 .

Drakulix commented 11 years ago

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?

philiplaureano commented 11 years ago

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 .

Drakulix commented 11 years ago

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.

philiplaureano commented 11 years ago

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 .

Drakulix commented 11 years ago

sure, here you go:

https://dl.dropboxusercontent.com/u/46559498/ReturnTest.zip

The ReturnTestInject executable expects the path of the Target as argument.

Drakulix commented 11 years ago

Works nicely, thanks!