Как внедрить код в вызовы метода c # из отдельного приложения

2

Мне было любопытно, знал ли кто-нибудь о способе мониторинга информации о времени выполнения приложения .Net(какой метод вызывается и т.д.)

и вводить дополнительный код для запуска определенных методов из отдельного запущенного процесса.

Скажем, у меня два приложения:

app1.exe, что для простоты может быть

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

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

и у меня есть второе приложение, которое я хочу, чтобы обнаружить, когда Somefunc() из приложения 1 запущен и ввести свой собственный код,

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

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

Таким образом, результатом будет приложение, которое показывало бы

Hello World
Hello World Injected 

Я понимаю, что это будет не так просто (длинным выстрелом) но я понятия не имею, возможно ли это, и если это даже когда начать.

Любые предложения?

Я видел подобное в java, но никогда в С#.

EDIT: Чтобы уточнить, использование этого было бы добавить плагиновую систему в игру на основе .Net, в которой у меня нет доступа к исходному коду.

Теги:
code-injection
aop

9 ответов

4
Лучший ответ

Возможно, стоит посмотреть в Mono.Cecil для инъекций кода. Он не будет работать онлайн так, как вы описали в своем вопросе, но я считаю, что он может делать то, что вы хотите в автономном режиме (иметь возможность найти данный метод, добавить код к нему и записать измененную сборку). http://www.codeproject.com/KB/dotnet/MonoCecilChapter1.aspx

2

Вам нужно использовать Profiling API чтобы сделать второй профиль программы первым. Затем вы можете получать уведомления о любых вызовах методов.

  • 0
    Это не поможет с модификацией, хотя.
2

Ну, сделать это без разрешения App1 сложно. Но, предполагая, что вы действительно хотите создать точку расширения в App1, относительно просто сделать то, что вы предлагаете с помощью какой-либо расширяемости. Я предлагаю:

Поскольку я больше знаком с MEF, вот как он выглядит:

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
    Хотя я знаю, что это немного аморально, позвольте мне объяснить, для чего оно предназначено сейчас, мне нравится играть в небольшую однопользовательскую игру, которая не имеет какой-либо формы поддержки аддонов (игра также основана на .net), но есть несколько пользовательских надстроек, которые я хотел бы сделать для своей собственной версии Невозможно получить доступ к коду / или отсутствие системы надстроек, я намеревался создать свой собственный, у меня нет намерений или выпускать его для публики,
  • 0
    Это также означает, что у меня нет доступа к изменению кода App1,
Показать ещё 2 комментария
1

Другая идея - написать приложение, которое изменит EXE, который вы хотите контролировать. Это будет делать то же, что и инструменты профилирования, когда они "приспосабливают" ваше приложение. В основном, вы используете отражение для просмотра приложения, затем вы заново создаете exe (с другим именем файла), используя функции Emit.NET и вставляете свой код в одно и то же время.

Конечно, если приложение попытается сделать что-то надежно, этой новой версии не разрешается связываться со своими другими сборками.

  • 0
    Это то, что я надеялся сделать, запустив фоновое приложение и выполнив его в режиме реального времени, или как вы предложили, я просто не был уверен, как это сделать.
  • 0
    Вы также можете посмотреть некоторые инструменты аспектно-ориентированного программирования, поскольку некоторые из них используют тот же принцип изменения уже существующей сборки.
1

С разъяснениями, сделанными вами в комментарии, мне кажется, что вам лучше разобрать и повторно собрать, используя ildasm и ilasm.

  • 0
    Я думаю, ты будешь прав. Я надеялся, что до этого не дойдет.
0

Вы можете попробовать CInject для внедрения вашего кода С# ИЛИ VB.NET в сборки

0

Введите код в сборке с Mono Cecil

0

В зависимости от того, как автор упаковал/структурировал свое приложение, вы могли бы добавить ссылку на свой EXE файл из своего собственного проекта и просто выполнить его код из своего собственного приложения. Если это сработает, это просто вопрос использования Reflection в этот момент, чтобы получить полезные интерфейсы/события/etc, которые вы можете подключить (если они выделены частным... иначе просто используйте их напрямую:). Вы можете добавить ссылку на любой EXE, созданный с настройками по умолчанию для отладки или выпуска сборок, и использовать его так же, как DLL.

Если это не работает, есть расширенные трюки, которые вы можете использовать, чтобы поменять вызовы методов и т.д., но это выходит за рамки этого ответа... Я предлагаю сначала попробовать ссылку.

0

Ввод кода в запущенное приложение возможно. Это является рабочим примером, но включает в себя инъекцию в неуправляемую dll.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню