点击上方 蓝字 江湖评谈 设为关注
有小伙伴问: .NET托管入口Main函数可以修改成别的函数,用来作为程序的入口吗?
答案:当然是可以的。这也算是.NET里面非常简单的骚操了。本篇来用最新的.NET8演示下,如何修改Main入口。
1.简单控制台例子:
namespace ConsoleApp1
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Call Main");
}
static void ABC()
{
Console.WriteLine("Call ABC");
}
}
}
例子里面有两个函数:Main和ABC。Main函数是托管入口函数,这里演示下如何把托管入口函数改为ABC函数。结果是程序启动会直接打印出 "Call ABC" 字符串,而不是 "Call Main" 字符串。
以上代码运行之后在bin/Debug/net8.0目录下生成了ConsoleApp1.dll文件,比如我的当前目录如下:
2.修改
我们需要用到一个工具CFF Explorer_CN(本文底部有这个小工具的下载链接)解析下ConsoleApp1.dll托管动态链接库。它是类似于PE查看器的小工具,同时也兼具托管DLL的MSIL数据查看。如下图:
把ConsoleApp1.dll拖入到CFF Explorer_CN,展开.NET目录-】表-】Method表。如下图所示:
Method表里面有三个方法,我们只看前两个方法Main和ABC 。点击下Main,看到Main函数RVA的Value值是0000205E
点击下ABC函数,它的RVA Value值是00002050
知识点来了,JIT编译MSIL的时候根据RVA的值,进行定位函数头的位置。既然如此,把Main的RVA Value改成ABC的RVA Value,把ABC的RVA Value改成Main的RVA Value。即可进行Main函数和ABC函数的逻辑调换。
如何改呢?在Main的Value值处双击,把Value改成ABC的RVA Value值: 00002050。同样在ABC的Value值处双击,把Value值改成Main的RVA Value值: 0000205E。如下红框双击即可改动数据。
记得关闭ConsoleApp1.dll的时候保存下,不然改动不会生效。
最后cmd切换到ConsoleApp1.dll的目录,通过dotnet命令运行下下:
dotnet ConsoleApp1.dll
结果如下: