views:

900

answers:

8

I was curious if anyone knew of a way of monitoring a .Net application's runtime info (what method is being called and such)

and injecting extra code to be run on certain methods from a separate running process.

say i have two applications:

app1.exe that for simplicity's sake could be

class Program
{
    static void Main(string[] args)
    {
      while(true){
        Somefunc();
      }
    }

    static void Somefunc()
    {
       Console.WriteLine("Hello World");
    }
}

and I have a second application that I wish to be able to detect when Somefunc() from application 1 is running and inject its own code,

 class Program
 {
     static void Main(string[] args)
     {
       while(true){
          if(App1.SomeFuncIsCalled)
             InjectCode();
         }
     }

    static void InjectCode()
    {
       App1.Console.WriteLine("Hello World Injected");
    }
 }

So The result would be Application one would show

Hello World
Hello World Injected

I understand its not going to be this simple ( By a long shot ) but I have no idea if it's even possible and if it is where to even start.

Any suggestions ?

I've seen similar done in java, But never in c#.

EDIT: To clarify, the usage of this would be to add a plugin system to a .Net based game that I do not have access to the source code of.

+1  A: 

With the clarifications you made in a comment, it seems to me you would be better off disassembling and reassembling using ildasm and ilasm.

Barry Kelly
im thinking you my be correct. I was hoping it wouldnt come to that.
Fusspawn
+2  A: 

You need to use the Profiling API to make the second program profile the first one. You van then be notified of any method calls.

SLaks
That won't help with the modification though.
Barry Kelly
+1  A: 

Well, to do that without App1's permission is difficult. But assuming you actually want to create an extension point in App1, it's relatively straightforward to do what you're suggesting with some kind of extensibility framework. I suggest:

Since I am more familiar with MEF, here's how it would look:

class Program
{
    [ImportMany("AddinContractName", typeof(IRunMe))]
    public IEnumerable<IRunMe> ThingsToRun { get; set; }

    void SomeFunc()
    {
        foreach(IRunMe thing in ThingsToRun)
        {
            thing.Run();
        }
        /* do whatever else ... */
    }
}
Scott Whitlock
While i am aware this is slightly morally wrong, Let me explain what the intended use it now, I enjoy playing a small single player game that does not have any form of addon support ( the game is also .net based ), yet there are a few custom addons i would like to make for my own versionUnable to get access to the code/or lack of addon system, I intended to make my own, I have no intentions or releasing this to the public,
Fusspawn
This also means i have no access to modify App1's code,
Fusspawn
@Fusspawn - I see. I wasn't sure at first if you had access to app 1's code or not. I see you've edited your question to clarify. Thanks.
Scott Whitlock
Thanks for your answer anyway, Its something i never knew existed in c# and has added to my reading list :)
Fusspawn
+1  A: 

Another idea is to write an app that will change the exe you want to monitor. It would do things similar to what profiling tools do when they "instrument" your app. Basically, you use reflection to browse the app, then you re-create the exe (with a different file name) using the Emit features of .NET and insert your code at the same time.

Of course, if the app attempted to do things securely, this new version may not be allowed to communicate with its other assemblies.

John Fisher
Its this i was hoping to do, via having to run a background app and do it in realtime, or the way you suggested, I just wasnt sure how to go about this.
Fusspawn
You might also look up some of the Aspect Oriented Programming tools, since some of them use the same principle of modifying an already existing assembly.
John Fisher
A: 

Depending on how the author packaged/structured his application, you might be able to add a reference to his EXE file from your own project and just execute his code from within your own application. If that works, it's just a matter of using Reflection at that point to get at useful interfaces/events/etc that you can plug into (if they are marked private...otherwise just use them directly :). You can add a reference to any EXE built with the default settings for debug or release builds, and use it just like a DLL.

If that doesn't work there are advanced tricks you can use as well to swap out method calls and such, but that is beyond the scope of this reply...I suggest trying the reference thing first.

+3  A: 

It might be worth looking into Mono.Cecil for code injection. It won't work online the way you described in your question, but I believe it may do what you want offline (be able to find a given method, add code to it, and write out the modified assembly). http://www.codeproject.com/KB/dotnet/MonoCecilChapter1.aspx

genki
A: 

Injecting code into a running app is possible. This is a working example, but involves injection into an unmanaged dll.

Brian
A: 

Inject code in the assembly with Mono Cecil

Nicolas Dorier