You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将.NET托管DLL注入其他.NET进程并外部调用其方法

可行性结论

这个需求完全可实现,全C#技术栈即可完成,不需要依赖C++等原生语言开发组件。
注意和传统原生DLL注入的核心差异:C#编译生成的是托管DLL,依赖.NET CLR运行,不能直接套用原生LoadLibrary远程注入的逻辑加载,需要结合CLR的托管加载规则实现。

具体实现步骤
  • 前置准备:开发待注入的C# DLL
    把需要在目标进程执行的逻辑封装在类库项目中,将需要被外部触发的方法定义为public static类型,比如预留统一入口:

    public class InjectMain
    {
        public static void Entry(string param)
        {
            // 这里写注入后要执行的初始化逻辑,比如启动IPC监听
        }
    }
    

    编译时注意两点:一是平台目标和要注入的目标进程保持一致(同为x86或x64);二是目标框架版本和目标进程的.NET版本完全匹配(比如目标进程跑.NET Framework 4.8就不要把DLL编译成.NET 6,反之亦然),否则会加载失败。

  • 核心注入逻辑开发(注入器部分)
    注入器是独立的C#控制台/WinForm程序,核心通过调用Win32 API完成操作,流程如下:

    1. 通过OpenProcess拿到目标进程的操作句柄,申请权限至少包含PROCESS_CREATE_THREAD、PROCESS_VM_OPERATION、PROCESS_VM_WRITE、PROCESS_QUERY_INFORMATION,如果目标进程是管理员/系统权限运行,注入器也需要以对应权限启动,否则会拿不到句柄。
    2. 在目标进程的虚拟内存空间中申请一块可读写的内存,将待注入DLL的完整本地路径写入这块内存。
    3. 不要直接远程调用kernel32.dll的LoadLibrary函数加载托管DLL——这只会把DLL当做原生PE映射到进程内存,不会进入CLR加载流程,也无法执行托管代码。正确的做法是针对目标进程的CLR版本,调用CLR导出的托管加载接口(.NET Framework场景可以借助clr.dll/mscorwks.dll的CLR托管接口,.NET Core/.NET 5+场景可以借助已加载运行时的Assembly.LoadFile相关入口),加载DLL到目标进程的默认应用域中,然后直接调用你之前写好的静态入口方法完成DLL初始化。
  • 注入后跨进程调用DLL内部方法
    最稳妥、兼容性最高的方案是在DLL的初始化入口里启动一个本地IPC服务,推荐用命名管道实现:DLL作为服务端监听专属的命名管道地址,注入器作为客户端连接这个管道,之后所有方法调用请求都通过管道发送,DLL收到请求后通过反射调用自身内部的对应方法,参数和返回值做序列化传输即可。
    不推荐直接获取方法JIT后的内存地址、通过远程线程直接跳转调用的方案:.NET运行时的GC回收、JIT动态重编译都会导致方法内存地址变动,非常容易触发目标进程崩溃。

常见避坑点
  • 安全软件会对远程线程注入、内存写入操作做拦截,测试时记得加白名单,不要在生产环境无提示做注入操作。
  • 如果目标进程做了强签名校验、进程内存防篡改保护,注入会失败,需要先过对应校验逻辑。
  • .NET Core单文件自包含发布的进程,注入时要注意不要把DLL路径写错,优先用进程当前的运行时上下文加载,不要硬编码系统安装的.NET路径。

注:注入行为需要符合对应软件的用户协议和当地法律法规要求,仅可用于合法的调试、自研程序扩展场景。

内容的提问来源于stack exchange,提问作者root823746374

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 09:18:21