运行时拦截现有DLL方法调用的技术实现咨询
运行时无重编译DLL方法拦截实现结论
你提出的不需要修改原DLL代码、不需要重新编译DLL,在运行时拦截方法添加日志、甚至绕过原方法逻辑的需求,完全可以通过Dynamic Proxy、方法拦截类的AOP技术实现。
两类主流技术的适用场景
- 动态代理(Dynamic Proxy)方案
这是最通用的无侵入AOP实现方式,运行时会在内存中动态生成目标类型的代理子类,所有经过代理的方法调用都会先进入你自定义的拦截管道,你可以在管道中插入日志记录逻辑,再选择继续调用原方法、或者直接返回自定义结果跳过原逻辑。
这类方案的限制是:只能拦截标记为virtual的虚方法、或者通过接口定义的方法,因为代理本质是重写原方法实现调用逻辑。你不需要手动逐个定位要拦截的方法,只要配置统一的匹配规则(比如指定命名空间、指定方法名前缀、指定返回值类型等),就能批量给符合规则的方法附加日志逻辑,全程不会修改磁盘上存储的原DLL文件。 - 运行时内存方法替换方案
如果要拦截的方法是非虚方法、静态方法,动态代理无法覆盖,就可以用这类方案。核心逻辑是在目标DLL被加载到进程内存后,直接修改内存中对应方法的入口地址,把所有对原方法的调用重定向到你写的拦截函数中。
这类方案没有方法类型的限制,支持所有类型的方法拦截,同样不需要修改原DLL文件,配置匹配规则后就能批量完成拦截,既可以加日志,也可以直接返回自定义结果绕过原方法执行。
这类技术和目标DLL的交互方式
- 所有拦截逻辑都在运行时、进程内完成,不需要提前对原DLL做任何修改,也不需要重新编译原DLL。
- 用动态代理方案时,你只需要把原有代码中直接实例化目标类型的逻辑,替换为调用代理生成器创建代理实例,后续所有对该实例的方法调用都会自动走拦截逻辑,原DLL的类型定义、存储内容都不会发生任何改变。
- 用内存方法替换方案时,连实例化逻辑都不需要调整,只要在应用启动阶段、目标DLL加载完成后,按照预设规则扫描内存中符合条件的方法,修改方法入口指向拦截函数即可,原有业务代码不需要做任何改动,所有对目标方法的调用都会自动被拦截。
注意:针对强名称签名的DLL,上述两类运行时拦截方案都不会触发签名校验失败,因为所有修改都仅作用于进程内存,不会改动磁盘上的原DLL文件;如果是跨进程的拦截场景需要额外处理进程权限,同进程内的拦截不需要特殊权限配置。
内容的提问来源于stack exchange,提问作者Mselmi Ali
相关产品推荐
相关产品推荐

