XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using Mono.Cecil;
using Mono.Cecil.Cil;
using XFESystem.Collections;

namespace XFESystem.Tools.JintCleanupPatch;

public static partial class Program
{
    private const string RegexLiteralMarker = "XFESystem.JintLiteralRegexReplacementV1";
    private static bool OriginalLiteralCall(Instruction instruction) => instruction.Operand is MethodReference call &&
        call.DeclaringType.FullName == "System.Text.RegularExpressions.Regex" && call.Name == "Replace" &&
        call.Parameters.Count == 3 && call.Parameters[0].ParameterType.FullName == "System.String" &&
        call.Parameters[1].ParameterType.FullName == "System.String" && call.Parameters[2].ParameterType.FullName == "System.Int32";
    private static bool PatchedLiteralCall(Instruction instruction) => instruction.Operand is MethodReference call &&
        call.DeclaringType.FullName == typeof(LiteralRegexReplacement).FullName && call.Name == "Replace";
    private static void PatchRegexLiteral(ModuleDefinition module)
    {
        if (module.GetType(RegexLiteralMarker) is not null) { ValidateRegexLiteral(module); return; }
        var replace = module.GetType("Jint.Native.RegExp.RegExpPrototype").Methods.Single(method => method.Name == "Replace");
        var calls = replace.Body.Instructions.Where(OriginalLiteralCall).ToArray();
        if (calls.Length != 1 || replace.Body.Instructions.Any(PatchedLiteralCall))
            throw new InvalidOperationException("Pinned literal regex replacement call shape changed.");
        calls[0].OpCode = OpCodes.Call;
        calls[0].Operand = module.ImportReference(typeof(LiteralRegexReplacement).GetMethod(nameof(LiteralRegexReplacement.Replace))!);
        module.Types.Add(new("XFESystem", "JintLiteralRegexReplacementV1", TypeAttributes.NotPublic | TypeAttributes.Abstract | TypeAttributes.Sealed, module.TypeSystem.Object));
        ValidateRegexLiteral(module);
    }
    private static void ValidateRegexLiteral(ModuleDefinition module)
    {
        var replace = module.GetType("Jint.Native.RegExp.RegExpPrototype").Methods.Single(method => method.Name == "Replace");
        if (module.GetType(RegexLiteralMarker) is null || replace.Body.Instructions.Any(OriginalLiteralCall) ||
            replace.Body.Instructions.Count(PatchedLiteralCall) != 1 ||
            replace.Body.Instructions.Single(PatchedLiteralCall).OpCode != OpCodes.Call)
            throw new InvalidOperationException("The literal regex replacement patch is incomplete.");
    }
}