准备
namespace ConsoleApp1
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
Console.ReadKey();
}
}
}
编译出来如下内容
使用ilspy打开
代码
安装Mono.Cecil
包
代码如下
using Mono.Cecil;
using Mono.Cecil.Cil;
using System.Diagnostics;
namespace ILInject
{
internal class Program
{
static void Main(string[] args)
{
string path = @"G:\ConsoleApp1\bin\Debug\net8.0\ConsoleApp1.dll";
Run(path, false);
Console.ReadKey();
}
/// <summary>
/// 注入IL代码
/// </summary>
/// <param name="path"></param>
/// <param name="isBreak"></param>
static void Run(string path, bool isBreak)
{
//加载程序集
using var assembly = AssemblyDefinition.ReadAssembly(path, new ReaderParameters { ReadWrite = true });
//查找入口方法
var entryPoint = assembly.EntryPoint;
//获取入口点方法的IL处理器
var ilProcessor = entryPoint.Body.GetILProcessor();
//创建添加说明
Instruction[] instructions;
if (isBreak)
{
var launchDebuggerInstruction = ilProcessor.Create(OpCodes.Call, assembly.MainModule.ImportReference(
typeof(Debugger).GetMethod(nameof(Debugger.Launch), Type.EmptyTypes)));
instructions = new[]
{
launchDebuggerInstruction,
Instruction.Create(OpCodes.Pop),
};
}
else
{
var writeLineInstruction = ilProcessor.Create(OpCodes.Call, assembly.MainModule.ImportReference(
typeof(Console).GetMethod(nameof(Console.WriteLine), new Type[] { typeof(string) })));
var readKeyInstruction = ilProcessor.Create(OpCodes.Call, assembly.MainModule.ImportReference(
typeof(Console).GetMethod(nameof(Console.ReadKey), Type.EmptyTypes)));
instructions = new[]
{
Instruction.Create(OpCodes.Ldstr, "Please attach debugger, then press any key"),
writeLineInstruction,
readKeyInstruction,
//使用Pop删除ReadKey的返回值
Instruction.Create(OpCodes.Pop),
};
}
var firstInstruction = ilProcessor.Body.Instructions[0];
// 在方法的开头插入新的说明
for (int i = 0; i < instructions.Length; i++)
{
ilProcessor.InsertBefore(firstInstruction, instructions[i]);
}
// 保存修改后的组件
assembly.Write();
Console.WriteLine("已成功修改并保存程序集。");
}
}
}
再次运行exe即可看到效果
参考
https://www.bilibili.com/video/BV1WVbFeKEKD/?spm_id_from=333.999.0.0&vd_source=b7fa6e046b093a4aca400b429259cf8b
IL指令
https://github.com/yangzhongke/DotNetBreak/tree/main/DotNetWait