关于静态修改.NET的DLL对某些函数进行HOOK的方法

以 Hook httpclient,打印它的request和response为例

1. 使用ildasm将目标DLL转成IL

cs 复制代码
ildasm target.dll /out=target.il

2.修改target.il

原始:

复制代码
    IL_007b:  newobj     instance void [netstandard]System.Net.Http.HttpClientHandler::.ctor()
    IL_0080:  dup
    IL_0081:  ldc.i4.3
    IL_0082:  callvirt   instance void [netstandard]System.Net.Http.HttpClientHandler::set_AutomaticDecompression(valuetype [netstandard]System.Net.DecompressionMethods)
    IL_0087:  stloc.0
    IL_0088:  ldarg.0
    IL_0089:  ldloc.0
    IL_008a:  newobj     instance void [netstandard]System.Net.Http.HttpClient::.ctor(class [netstandard]System.Net.Http.HttpMessageHandler)

修改调用自己的handler, 直接[netstandard]System.Net.Http.HttpClientHandler 改成 [InterceptorLib]InterceptorLib.LoggingHandler:

diff 复制代码
    IL_007b:  newobj     instance void [InterceptorLib]InterceptorLib.LoggingHandler::.ctor()
    IL_0080:  dup
    IL_0081:  ldc.i4.3
    IL_0082:  callvirt   instance void [InterceptorLib]InterceptorLib.LoggingHandler::set_AutomaticDecompression(valuetype [netstandard]System.Net.DecompressionMethods)
    IL_0087:  stloc.0
    IL_0088:  ldarg.0

然后il文件开头添加InterceptorLib引用

diff 复制代码
.assembly extern InterceptorLib
{
  .ver 0:0:0:0
}

3. 生成一个InterceptorLib.dll 和 LoggingHandler这个类。

cs 复制代码
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.IO;

namespace InterceptorLib
{
    public class LoggingHandler : DelegatingHandler
    {
        
        public LoggingHandler()
            : base(new HttpClientHandler())
        {

        }
        //[netstandard] System.Net.Http.HttpClientHandler::set_AutomaticDecompression(valuetype[netstandard] System.Net.DecompressionMethods)
        public System.Net.DecompressionMethods  AutomaticDecompression
        {
            get { return ((HttpClientHandler)this.InnerHandler).AutomaticDecompression; }
            set { ((HttpClientHandler)this.InnerHandler).AutomaticDecompression = value; }
        }


        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {

            StreamWriter sw = File.AppendText("api.log");
            try
            {
                sw.WriteLine(DateTime.Now +  " Request:");
                sw.WriteLine(request.ToString());
                if (request.Content != null)
                {
                    sw.WriteLine(await request.Content.ReadAsStringAsync());
                }
                sw.WriteLine();
                sw.WriteLine();

                HttpResponseMessage response = await base.SendAsync(request, cancellationToken);

                sw.WriteLine(DateTime.Now + " Response:");
                sw.WriteLine(response.ToString());
                if (response.Content != null)
                {
                    sw.WriteLine(await response.Content.ReadAsStringAsync());
                }
                sw.WriteLine();
                return response;
            }
            catch (Exception ex)
            {
                // Handle potential errors during logging (e.g., file access issues)
                Console.WriteLine($"Error writing to log file: {ex.Message}");
            }

            return null;
        }



    }
}

4. 使用ilasm 将target.il 转成 dll

cs 复制代码
ilasm  target.il /dll

5. 将InterceptorLib.dll和生成后的target.dll 复制到目标目录

cs 复制代码
cp *.dll target_dir
相关推荐
rockey6274 小时前
AScript之eval函数详解
c#·.net·script·eval·expression·动态脚本
周杰伦fans1 天前
AutoCAD .NET 二次开发:深入理解 EntityJig 的工作原理与正确实现
开发语言·.net
William_cl2 天前
【C#/.NET 进阶】ASP.NET 架构与最佳实践:DI 依赖注入(IoC 核心)从入门到避坑
c#·asp.net·.net
武藤一雄2 天前
WPF:MessageBox系统消息框
前端·microsoft·c#·.net·wpf
武藤一雄2 天前
WPF进阶:万字详解WPF如何性能优化
windows·性能优化·c#·.net·wpf·.netcore·鲁棒性
唐青枫2 天前
别再层层传参了!C#.NET AsyncLocal 异步上下文透传实战
c#·.net
小邓的技术笔记3 天前
.NET 10 使用 Microsoft.AspNetCore.OpenApi 实现 API 版本管理
.net
夏霞3 天前
IIS 应用程序池 3 种标识:ApplicationPoolIdentity / LocalSystem / LocalService 权限区别(超清晰)
c#·.net
回忆2012初秋3 天前
Quartz.NET 全面解析与实战指南
.net
我是唐青枫3 天前
C#.NET ThreadLocal 深入解析:线程独享数据、性能收益与实战边界
c#·.net