首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【愚公系列】2023年02月 .NET CORE工具案例-Lib.Harmony之AOP拦截

【愚公系列】2023年02月 .NET CORE工具案例-Lib.Harmony之AOP拦截

作者头像
愚公搬代码
发布2023-03-16 17:27:56
发布2023-03-16 17:27:56
61800
代码可运行
举报
文章被收录于专栏:历史专栏历史专栏
运行总次数:0
代码可运行

文章目录


前言

API拦截是指通过拦截某个应用程序编程接口(API)的调用,限制或控制程序的功能和行为。它通常是在应用程序和操作系统之间进行拦截,以防止应用程序访问某些操作系统功能或资源。

API拦截可以用来监控和分析API调用,以确保API调用者遵守安全规则。它也可以用来确保API不被滥用,以及确保API调用者支付合理的费用。此外,它还可以用来收集API调用的统计数据,以让开发人员和运营人员了解API的使用情况。

Lib.Harmony的Github网址:https://github.com/pardeike/Harmony

Lib.Harmony官网:https://harmony.pardeike.net/

一、自定义拦截

1.安装包

代码语言:javascript
代码运行次数:0
运行
复制
Lib.Harmony

2.基本使用

2.1 定义被拦截的类

代码语言:javascript
代码运行次数:0
运行
复制
public class Student
{
    public string GetDetails(string name)
    {
        return $"大家好,我是博主:{name}";
    }
}

2.2 定义拦截类

代码语言:javascript
代码运行次数:0
运行
复制
/// <summary>
/// 自定义拦截器(拦截Student和GetDetails方法)
/// </summary>
[HarmonyPatch(typeof(Student))]
[HarmonyPatch(nameof(Student.GetDetails))]
public class HookStudent
{
    public static bool Prefix()
    {
        Console.WriteLine($"Prefix");
        return true;
    }

    public static void Postfix()
    {
        Console.WriteLine($"Postfix");
    }

    public static void Finalizer()
    {
        Console.WriteLine($"Finalizer");
    }
}

2.3 运行

代码语言:javascript
代码运行次数:0
运行
复制
using ConsoleTest;
using HarmonyLib;
using System.Reflection;

var student = new Student();
Console.WriteLine(student.GetDetails("愚公搬代码"));

var harmony = new Harmony("https://blog.csdn.net/aa2528877987");
harmony.PatchAll(Assembly.GetExecutingAssembly());

Console.WriteLine(student.GetDetails("愚公搬代码"));

Console.ReadLine();

使用PatchAll能自动发现拦截类,从而自动拦截GetDetails方法调用,发现第二次调用方法时,Harmony的三个生命周期方法都被调用了。

3.参数篡改

3.1 拦截类修改

代码语言:javascript
代码运行次数:0
运行
复制
/// <summary>
/// 自定义拦截器(拦截Student和GetDetails方法)
/// </summary>
[HarmonyPatch(typeof(Student))]
[HarmonyPatch(nameof(Student.GetDetails))]
public class HookStudent
{
    public static bool Prefix(ref string name, ref string __result)
    {
        if ("愚公搬代码".Equals(name))
        {
            __result = $"愚公搬代码已经改名了";
            return false;
        }

        if ("代码搬愚公".Equals(name))
        {
            name = "代码搬愚公";
        }

        return true;
    }

    public static void Postfix()
    {
        Console.WriteLine($"Postfix");
    }

    public static void Finalizer()
    {
        Console.WriteLine($"Finalizer");
    }
}

3.2 运行

代码语言:javascript
代码运行次数:0
运行
复制
using ConsoleTest;
using HarmonyLib;
using System.Reflection;

var student = new Student();
Console.WriteLine(student.GetDetails("愚公搬代码"));

var harmony = new Harmony("https://blog.csdn.net/aa2528877987");
harmony.PatchAll(Assembly.GetExecutingAssembly());

Console.WriteLine(student.GetDetails("愚公搬代码"));
Console.WriteLine(student.GetDetails("代码搬愚公"));


Console.ReadLine();

Prefix方法默认返回的true,表示需要调用原生方法,这里会将篡改的参数传入原生方法。

二、WPF自定义拦截

自定义消息框

代码语言:javascript
代码运行次数:0
运行
复制
public class TG_MessageBox
{
    public void TG_Show(string messageBoxText)
    {
        MessageBox.Show(messageBoxText);
    }
}

1.App中注册自动拦截

代码语言:javascript
代码运行次数:0
运行
复制
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
    //自动拦截注册
    protected override void OnStartup(StartupEventArgs e)
    {

        base.OnStartup(e);

        var harmony = new Harmony("https://blog.csdn.net/aa2528877987");
        harmony.PatchAll(Assembly.GetExecutingAssembly());
    }
}

2.自动拦截类

代码语言:javascript
代码运行次数:0
运行
复制
[HarmonyPatch(typeof(TG_MessageBox))]
[HarmonyPatch(nameof(TG_MessageBox.TG_Show))]
[HarmonyPatch(new[] { typeof(string) })]
public class HookMessageBox
{
    public static bool Prefix(ref string messageBoxText)
    {
        if (messageBoxText.Contains("愚公"))
        {
            messageBoxText = "愚公的博客:https://blog.csdn.net/aa2528877987";
        }

        return true;
    }
}

3.运行

在窗体MainWindow.xaml里添加两个弹出提示框的按钮:

代码语言:javascript
代码运行次数:0
运行
复制
<Window x:Class="WpfTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <Button Content="弹出默认提示框" Width="120" Height="30" Click="ShowDialog_OnClick"></Button>
        <Button Content="愚公博客网站" Width="120" Height="30" Click="ShowBadMessageDialog_OnClick"></Button>
    </StackPanel>
</Window>
代码语言:javascript
代码运行次数:0
运行
复制
public partial class MainWindow : Window
{
    public TG_MessageBox tG_MessageBox { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        tG_MessageBox = new TG_MessageBox();
    }

    private void ShowDialog_OnClick(object sender, RoutedEventArgs e)
    {

        tG_MessageBox.TG_Show("https://blog.csdn.net/aa2528877987 是一个热衷于技术分享的程序员网站");
    }

    private void ShowBadMessageDialog_OnClick(object sender, RoutedEventArgs e)
    {
        tG_MessageBox.TG_Show("愚公");
    }
}

可以看到弹出消息被篡改

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 前言
  • 一、自定义拦截
    • 1.安装包
    • 2.基本使用
      • 2.1 定义被拦截的类
      • 2.2 定义拦截类
      • 2.3 运行
    • 3.参数篡改
      • 3.1 拦截类修改
      • 3.2 运行
  • 二、WPF自定义拦截
    • 1.App中注册自动拦截
    • 2.自动拦截类
    • 3.运行
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档