2

Using EasyHook I have set up the following structure:

APP <--> Interface <--> DLL

I am trying to run some code inside the injected DLL when I press a button in the APP.

I managed to get the DLL to send messages outside using this code:

((EntryPoint)HookRuntimeInfo.Callback).Interface.WriteLine("");

But how can I actually make code run inside the injected DLL?

Eliza
  • 23
  • 3

1 Answers1

2

You need to configure a bi-directional IPC interface. There are a range of different ways to implement this. What follows is one example using .NET Remoting.

First take a look at the EasyHook remote file monitor tutorial as a starting point for creating your interface to send messages from the DLL back to APP, i.e. APP <- interface <- DLL.

To allow messages from APP -> interface -> DLL, a new channel needs to be configured within the DLL IEntryPoint constructor: e.g.

    #region Allow client event handlers (bi-directional IPC)
    // Attempt to create a IpcServerChannel so that any event handlers on the client will function correctly
    System.Collections.IDictionary properties = new System.Collections.Hashtable();
    properties["name"] = channelName;
    properties["portName"] = channelName + Guid.NewGuid().ToString("N"); // random portName so no conflict with existing channels of channelName

    System.Runtime.Remoting.Channels.BinaryServerFormatterSinkProvider binaryProv = new System.Runtime.Remoting.Channels.BinaryServerFormatterSinkProvider();
    binaryProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

    System.Runtime.Remoting.Channels.Ipc.IpcServerChannel _clientServerChannel = new System.Runtime.Remoting.Channels.Ipc.IpcServerChannel(properties, binaryProv);
        System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(_clientServerChannel, false);
    #endregion

To implement the IPC from APP -> interface -> DLL take a look at the Disconnect method and Disconnected event within the "Client-side events" of the Direct3DHook project, CaptureInterface.Disconnect, CaptureInterface.Disconnected and ClientCaptureInterfaceEventProxy.Disconnected, all in CaptureInterface.cs. In addition to the interface class, this approach also uses a client event proxy class that inherits from MarshalByRefObject and allows an event handler to be called elsewhere in your DLL in response to the APP calling a method. You will need to take a good look at the code linked, there are some additional points of interest that need to be considered (such as event handler lifetime), the interface implements a wrapper around each event to trigger it in a "Safe" manner.

Finally the handler for the Disconnected event is attached within the DLL's IEntryPoint Run method:

    _interface.Disconnected += _clientEventProxy.DisconnectedProxyHandler;

    _clientEventProxy.Disconnected += () =>
            {
                // This code in the DLL will run when APP calls CaptureInterface.Disconnect
            };
Justin Stenning
  • 1,837
  • 1
  • 15
  • 19
  • Wow, I have been reading the D3DHook project for a few days and never quite understood it, but thanks to you I just got it to work! Thank you!!! – Eliza Jun 09 '17 at 23:15
  • @Eliza glad it helped – Justin Stenning Jun 09 '17 at 23:29
  • Hi there - thanks for the great answer. Could you elaborate on why the ClientCaptureInferfaceEventProxy is there? Is there any difficulties with simply using the original interface for those event handlers? – Tom 'Blue' Piddock Aug 15 '17 at 12:26
  • @Tom'Blue'Piddock the handler must inherit from MarshalByRefObj, I found it easier to use a proxy class for this otherwise you can run into issues with your other non-marshal compatible types. – Justin Stenning Aug 15 '17 at 21:43