2009-07-22 4 views
2

Ich war gespannt, ob jemand eine Möglichkeit, wußte eine .NET-Anwendung Laufzeit Informationen zu überwachen (welche Methode aufgerufen und so wird) zuWie injiziert Code in C# Methodenaufrufen von einer separaten App

und Injizieren zusätzlichen Code auf bestimmten Methoden von einem separaten laufenden Prozess ausgeführt werden.

sagen, ich habe zwei Anwendungen:

App1.exe, dass der Einfachheit halber

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

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

und ich habe eine zweite Anwendung sein könnte, dass ich wünschte, wenn sie erkennen können someFunc() aus der Anwendung 1 läuft und seinen eigenen Code injizieren,

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

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

So Das Ergebnis Anwendung wäre würde man zeigen

Hello World 
Hello World Injected 

Ich verstehe, es wird nicht so einfach sein (durch eine Totale) aber ich habe keine Ahnung, ob es überhaupt möglich ist und ob es wo überhaupt anfangen soll.

Irgendwelche Vorschläge?

Ich habe ähnliche in Java getan, aber nie in C# gesehen.

EDIT: Um zu verdeutlichen, wäre die Verwendung von dies ein Plugin-System zu einem .Net-basierten Spiel hinzuzufügen, die ich keinen Zugriff auf den Quellcode von haben.

Antwort

4

Es könnte sich lohnen, in Mono.Cecil nach Codeinjektionen zu suchen. Es funktioniert nicht online so, wie Sie es in Ihrer Frage beschrieben haben, aber ich glaube, es kann das tun, was Sie offline wollen (Sie können eine bestimmte Methode finden, Code hinzufügen und die modifizierte Assembly ausschreiben). http://www.codeproject.com/KB/dotnet/MonoCecilChapter1.aspx

+0

Bitte werfen Sie einen Blick auf diese: http://StackOverflow.com/q/13169865/75500 – Shimmy

1

Mit den Klarstellungen, die Sie in einem Kommentar gemacht haben, scheint es mir, Sie wären besser disassemblieren und wieder zusammenbauen mit ildasm und ilasm.

+0

im einzuspritzen denken Sie richtig sein meine. Ich hatte gehofft, dass es dazu nicht kommen würde. – Fusspawn

2

Sie müssen das Profiling API verwenden, um das zweite Programmprofil als erstes zu erstellen. Sie werden dann von allen Methodenanrufen benachrichtigt.

+0

Das wird jedoch nicht mit der Änderung helfen. –

2

Nun, das ohne App1's Erlaubnis zu tun ist schwierig. Aber vorausgesetzt, Sie möchten tatsächlich einen Erweiterungspunkt in App1 erstellen, ist es relativ einfach, das zu tun, was Sie vorschlagen, mit einer Art Erweiterbarkeits-Framework. Ich schlage vor:

Da ich mit MEF mehr vertraut bin, ist hier, wie es aussehen würde:

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

    void SomeFunc() 
    { 
     foreach(IRunMe thing in ThingsToRun) 
     { 
      thing.Run(); 
     } 
     /* do whatever else ... */ 
    } 
} 
+0

Während ich weiß, das ist ein wenig moralisch falsch, lassen Sie mich erklären, was die beabsichtigte Verwendung es jetzt, ich genieße ein kleines Einzelspieler-Spiel, das keine Form von Addon-Unterstützung (das Spiel ist auch .net basiert), noch da sind ein paar benutzerdefinierte Addons, die ich für meine eigene Version machen möchte Unable Zugriff auf den Code/oder das Fehlen von Addon-System, ich beabsichtigte, meine eigenen, habe ich keine Absichten oder die Freigabe dieser an die Öffentlichkeit, – Fusspawn

+0

Dies bedeutet auch, ich habe keinen Zugriff auf App1-Code zu ändern, – Fusspawn

+0

@Fusspawn - ich sehe. Ich war mir zunächst nicht sicher, ob Sie Zugriff auf den Code von App 1 hatten oder nicht. Ich sehe, du hast deine Frage bearbeitet, um sie zu klären. Vielen Dank. –

1

Eine andere Idee ist, eine App zu schreiben, die die exe ändert, die Sie überwachen möchten . Es würde ähnliche Dinge tun wie Profiling-Tools, wenn sie Ihre App "instrumentieren". Im Grunde verwenden Sie Reflektion, um die App zu durchsuchen, dann erstellen Sie die Exe (mit einem anderen Dateinamen) mit den Emit-Funktionen von .NET neu und fügen Ihren Code gleichzeitig ein.

Natürlich, wenn die App versucht, Dinge sicher zu tun, darf diese neue Version möglicherweise nicht mit seinen anderen Baugruppen kommunizieren.

+0

Es war dies zu tun, über eine Hintergrund App zu tun und tun es in Echtzeit oder wie Sie vorgeschlagen, ich war einfach nicht sicher, wie das geht. – Fusspawn

+0

Sie können auch einige der aspektorientierten Programmierwerkzeuge nachschlagen, da einige von ihnen das gleiche Prinzip verwenden, eine bereits bestehende Baugruppe zu modifizieren. –

0

Je nachdem, wie der Autor seine Anwendung gepackt/strukturiert hat, können Sie möglicherweise einen Verweis auf seine EXE-Datei aus Ihrem eigenen Projekt hinzufügen und seinen Code in Ihrer eigenen Anwendung ausführen. Wenn das funktioniert, ist es nur eine Frage der Verwendung von Reflection an diesem Punkt, um an nützliche Schnittstellen/Ereignisse/etc zu gelangen, an die Sie sich anschließen können (wenn sie als privat markiert sind, ansonsten verwenden Sie sie einfach direkt :). Sie können eine Referenz zu einer EXE hinzufügen, die mit den Standardeinstellungen für Debug- oder Release-Builds erstellt wurde, und sie wie eine DLL verwenden.

Wenn das nicht funktioniert, gibt es erweiterte Tricks, die Sie auch verwenden können, um Methodenaufrufe und dergleichen auszutauschen, aber das ist außerhalb des Rahmens dieser Antwort ... Ich schlage vor, die Referenz zuerst zu versuchen.

0

Eingeben von Code in eine laufende App ist möglich. This ist ein funktionierendes Beispiel, beinhaltet aber die Injektion in eine nicht verwaltete DLL.

0

können Sie CInject ausprobieren C# oder VB.NET-Code in Baugruppen