关于静态修改.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
相关推荐
1314lay_10075 小时前
.NET 7.0在.NET Core Web API中实现限流
.net·.netcore
步步为营DotNet6 小时前
深入探究.NET中Stream:灵活高效的数据流处理核心
服务器·数据库·.net
1314lay_10077 小时前
C# .Net 7.0 Core添加日志可视化
visualstudio·c#·.net·.netcore
时光追逐者8 小时前
C#/.NET/.NET Core技术前沿周刊 | 第 66 期(2026年1.12-1.18)
c#·.net·.netcore
一个帅气昵称啊9 小时前
.Net C# AI 如何实现联网搜索
人工智能·c#·.net
初级代码游戏20 小时前
C#:程序发布的大小控制 裁剪 压缩
c#·.net·dotnet·压缩·大小·发布·裁剪
weixin_421994781 天前
重复的力量 - 循环
.net·.netcore
Liust1 天前
扩展方法+泛型+委托+Lambda 联合使用
.net
一叶星殇1 天前
C# .NET 如何解决跨域(CORS)
开发语言·前端·c#·.net
weixin_421994781 天前
数学运算与逻辑判断 - 运算符与条件语句
.net·.netcore