Unity 注入IL代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using Mirror;
using System;
using Mono.CecilX;
using Mono.CecilX.Cil;

public class Test : MonoBehaviour
{
    internal int HaHa() => 3;

    byte[] buffer = new byte[10];

     [InitializeOnLoadMethod]
    public static void OnInitializeOnLoad()
    {
        UnityEditor.Compilation.CompilationPipeline.assemblyCompilationFinished += TestInjectMothod;
    }

    void Start()
    {
        //A(Vector3.one);
        //A(1.28f);
        //GetSize(Vector3.zero);
        //B();
        InjectMod();
    }

    unsafe void A<T>(T value) where T : unmanaged
    {
        fixed (byte* ptr = &buffer[8])
        {
            *(T*)ptr = value;
        }

        T value2;
        fixed(byte* ptr = &buffer[8])
        {
            value2 = *(T*)ptr;
        }
        Debug.LogError(value2);
    }

    unsafe void GetSize<T>(T value) where T : unmanaged
    {
        Debug.LogError(sizeof(T));
    }

    unsafe void B()
    {
        int a = 1;
        int* ptr = &a;
        *(Vector3*)ptr = Vector3.one;
        
        int* ptr2 = &a;
        Debug.LogError(*(Vector3*)ptr2);
    }



    void InjectMod () 
    {
        Debug.LogError("Heihei asdasd");
    }

    public static void TestInjectMothod(string assemblyPath, UnityEditor.Compilation.CompilerMessage[] messages)
    {
         if (assemblyPath.Contains("-Editor") || assemblyPath.Contains(".Editor"))
        {
            return;
        }
        
        string path = @"D:\ChromeDownload\Mirror\Mirror\Library\ScriptAssemblies\Assembly-CSharp.dll";
        string path2 = @"D:\ChromeDownload\Mirror\Mirror\Library\ScriptAssemblies\Assembly-CSharp2.dll";

        FileUtil.DeleteFileOrDirectory(path2);
        FileUtil.CopyFileOrDirectory(path, path2);
        FileUtil.DeleteFileOrDirectory(path); 

        AssemblyDefinition assembly;
        var readerParameters = new ReaderParameters { ReadSymbols = true };
        using (assembly = AssemblyDefinition.ReadAssembly(path2))
        {
            var types = assembly.MainModule.GetTypes();
            foreach(var type in types)
            {
                foreach(var Method in type.Methods)
                {
                    if(Method.Name == "InjectMod")
                    {
                        InjectMethod(Method, assembly);
                    }
                }
            }

            var writerParameters = new WriterParameters { WriteSymbols = true };
            assembly.Write(path, new WriterParameters());       
        };
    }

    private static void InjectMethod(MethodDefinition method, AssemblyDefinition assembly)
    {
        var firstIns = method.Body.Instructions[0];
        var worker = method.Body.GetILProcessor();

        //获取Debug.Log方法引用
        var hasPatchRef = assembly.MainModule.Import(typeof(Debug).GetMethod("LogError", new Type[] { typeof(string) }));
        //插入函数
        //压入参数
        var current = InsertBefore(worker, firstIns, worker.Create(OpCodes.Ldstr, "Inject Test 2 "));
        //调用方法
        current = InsertBefore(worker, firstIns, worker.Create(OpCodes.Call, hasPatchRef));
        //计算Offset
        ComputeOffsets(method.Body);
    }

    /// <summary>
    /// 语句前插入Instruction, 并返回当前语句
    /// </summary>
    private static Instruction InsertBefore(ILProcessor worker, Instruction target, Instruction instruction)
    {
        worker.InsertBefore(target, instruction);
        return instruction;
    }

    /// <summary>
    /// 语句后插入Instruction, 并返回当前语句
    /// </summary>
    private static Instruction InsertAfter(ILProcessor worker, Instruction target, Instruction instruction)
    {
        worker.InsertAfter(target, instruction);
        return instruction;
    }

    //计算注入后的函数偏移值
    private static void ComputeOffsets(MethodBody body)
    {
        var offset = 0;
        foreach (var instruction in body.Instructions)
        {
            instruction.Offset = offset;
            offset += instruction.GetSize();
        }
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容