[英]How to Inject code in c# method calls from a separate app
我很好奇是否有人知道监视.Net应用程序的运行时信息的方法(正在调用什么方法等)
并从单独的运行进程中注入要在某些方法上运行的额外代码。
说我有两个应用程序:
app1.exe,为简单起见,可以
class Program
{
static void Main(string[] args)
{
while(true){
Somefunc();
}
}
static void Somefunc()
{
Console.WriteLine("Hello World");
}
}
我有第二个应用程序,我希望能够检测应用程序1中的Somefunc()何时运行并注入自己的代码,
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中看到过类似的做法,但从未在c#中看到过。
编辑:澄清一下,使用这个是将插件系统添加到基于.Net的游戏,我无法访问源代码。
可能值得研究Mono.Cecil进行代码注入。 它不会像您在问题中描述的那样在线工作,但我相信它可以做你想要的离线(能够找到给定的方法,添加代码,并写出修改后的程序集)。 http://www.codeproject.com/KB/dotnet/MonoCecilChapter1.aspx
您需要使用Profiling API
将第二个程序配置文件作为第一个。 然后,您可以收到任何方法调用的通知。
那么,没有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 ... */
}
}
通过你在评论中做出的澄清,在我看来,你最好使用ildasm和ilasm进行反汇编和重新组装。
另一个想法是编写一个应用程序来改变你想要监控的exe。 它会做类似于分析工具在“检测”您的应用程序时所执行的操作。 基本上,您使用反射来浏览应用程序,然后使用.NET的Emit功能重新创建exe(使用不同的文件名)并同时插入代码。
当然,如果应用程序尝试安全地执行操作,则可能不允许此新版本与其他程序集通信。
根据作者打包/构建其应用程序的方式,您可以从自己的项目中添加对其EXE文件的引用,并从您自己的应用程序中执行其代码。 如果可行的话,那就是在这一点上使用Reflection来获得你可以插入的有用接口/事件/等(如果它们被标记为私有......否则只是直接使用它们:)。 您可以添加对使用调试或发布版本的默认设置构建的任何EXE的引用,并像使用DLL一样使用它。
如果这不起作用,你可以使用高级技巧来交换方法调用等,但这超出了本回复的范围......我建议先尝试参考。
可以将代码注入正在运行的应用程序中。 这是一个工作示例,但涉及注入非托管dll。
使用Mono Cecil在程序集中注入代码
您可以尝试使用CInject将C#或VB.NET代码注入程序集
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.