有小伙伴问: .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值是00002050
点击下ABC函数,它的RVA Value值是0000207C
知识点来了,JIT编译MSIL的时候根据RVA的值,进行定位函数头的位置。既然如此,把Main的RVA Value改成ABC的RVA Value,把ABC的RVA Value改成Main的RVA Value。即可进行Main函数和ABC函数的逻辑调换。
如何改呢?在Main的Value值处双击,把Value改成ABC的RVA Value值:0000207C。同样在ABC的Value值处双击,把Value值改成Main的RVA Value值:00002050。如下红框双击即可改动数据。
记得关闭ConsoleApp1.dll的时候保存下,不然改动不会生效。
最后cmd切换到ConsoleApp1.dll的目录,通过dotnet命令运行下下:
dotnet ConsoleApp1.dll
结果如下:
CFF Explorer简单介绍
CFF Explorer是一款优秀的PE资源工具,使用CFF Explorer可以方便地查看和编辑PE(EXE/DLL)资源,类似PE资源工具
使用CFF Explorer可以查看和修改PE文件的资源,可以查看dll文件可供调用的函数,修改函数入口地址达到制造崩溃屏蔽功能的目的。
PE(Portable Execute)文件被称为可移植的执行体,常见的EXE、DLL、OCX、SYS、COM都是PE文件,PE文件是微软Windows操作系统上的程序文件 。