SerializationException (Ipc.IpcServerChannel)?

Jun 19, 2012 at 4:33 AM

Lastnight, my application was working fine.
Today, without any changes in code, I'm getting the following error while trying to inject into the remote process:

"Type 'System.Runtime.Remoting.Channels.Ipc.IpcServerChannel' in Assembly 'System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable."

I performed a little research about this error, but couldn't find anything specific to any pre-assembled .NET library. Most solutions were found by adding the [Serializable] attribute to a class -- which, of course, is impossible in this scenario.
So what could be causing this, and how can it be fixed?

Jun 19, 2012 at 9:09 PM

My mistake, I actually DID make a minor change to the code (and I must've been too exhausted to remember).

I now know what is causing this issue. I had changed the Run() parameters to include a delegate, like so:

 

public class CaptureServer : EasyHook.IEntryPoint
{
    private CaptureInterface _interface = null;
    public delegate void OnConnectionDelegate(CaptureServer sender);

    public CaptureServer(RemoteHooking.IContext context, String channelName, OnConnectionDelegate connectionDelegate)
    {
        _interface = RemoteHooking.IpcConnectClient<CaptureInterface>(channelName);
    }

    public void Run(RemoteHooking.IContext InContext, String channelName, OnConnectionDelegate connectionDelegate)
    {
        //...
    }
}

And in the client application, the error is generated here:

public void Connect(string targetName, string targetExecutable)
{
    //...
    RemoteHooking.Inject( /* <--This line generates the error */
        processID,
        InjectionOptions.Default,
        "Capture32.dll",
        "Capture64.dll",
        ChannelName,
        new Action<CaptureServer.OnConnectionDelegate>(this.OnConnection)
    );
    //...
}

public void OnConnection(object sender)
{
    CaptureServer server = (CaptureServer)sender;
}

This was in an attempt to reference certain properties within the CaptureServer object, which I would still like to be able to do.

But this error is still in my way. Can anyone please tell me what's going on here?

Jun 21, 2012 at 1:14 AM

Hi,

I think there are a couple of issues here:

1) if you are not registering in the GAC then the the EasyHook assembly might not be able to resolve the type during injection - UNLESS you use something like ILMerge and combine your assembly and the EasyHook assembly together (I have done this in one of my projects). Also not using the GAC can cause another issue with the .NET Remoting where it does not correctly resolve the assembly types during IPC communication, this is easily solved by including a few lines of code in the Run method:

                // When not using GAC there can be issues with remoting assemblies resolving correctly
                // this is a workaround that ensures that the current assembly is correctly associated
                AppDomain currentDomain = AppDomain.CurrentDomain;
                currentDomain.AssemblyResolve += (sender, args) =>
                {
                    return this.GetType().Assembly.FullName == args.Name ? this.GetType().Assembly : null;
                }; 
2) I'm not sure that you will be able pass a delegate directly, you may need to create a MarshalByRef class with the delegate setup as a member and pass a reference to an instance of this across
To debug this I would do the following:
a) move the delegate into a MarshalByRef class instance
b) register in GAC and see that everything is working or not
c) if it works, use without GAC and see if you need to add the workaround code above
The documentation for 2.7 needs to be updated to reflect some of the issues that can occur when not using the GAC, it is still an open issue.

I hope this helps